Shader newblocks (C++)
|
Home
|
Click on the filename to display or download the file.
newblocks.mi
# Simple geometry objects for use in the example scenes of
# "Writing mental ray shaders". http://www.writingshaders.com/
declare shader
geometry "bw_square" (
string "name",
scalar "x" default 0,
scalar "y" default 0,
scalar "z" default 0,
scalar "sx" default 1,
scalar "sy" default 1 )
version 1
apply geometry
end declare
declare shader
geometry "bw_cube" (
string "name" )
version 1
apply geometry
end declare
declare shader
geometry "bw_cylinder" (
string "name",
integer "sides" default 60,
scalar "radius" default 0.5,
scalar "start_angle" default 0,
boolean "average_normals" default on )
version 1
apply geometry
end declare
declare shader
geometry "bw_cone" (
string "name",
integer "sides" default 120,
scalar "radius" default 0.5,
boolean "average_normals" default on )
version 1
apply geometry
end declare
declare shader
geometry "bw_ball" (
string "name",
integer "div_u" default 60,
integer "div_v" default 30,
boolean "average_normals" default on )
version 1
apply geometry
end declare
newblocks.cpp
// Simple geometry objects for use in the example scenes of
// "Writing mental ray shaders". http://www.writingshaders.com/
#include "mrpoly.h"
// --------------------------------------------------------------------------------
// SQUARE
struct bw_square {
miTag name;
miScalar x, y, z, sx, sy;
};
extern "C" DLLEXPORT
int bw_square_version(void) { return 1; }
extern "C" DLLEXPORT
miBoolean bw_square (miTag *result, miState *state, struct bw_square *params)
{
polygon_object obj;
polygon_group group;
tlist t;
matrix scale;
scale.s(*mi_eval_scalar(¶ms->sx), *mi_eval_scalar(¶ms->sy));
obj.mi_begin(get_string(state, ¶ms->name, "square"));
group = obj.new_group();
t.square(*mi_eval_scalar(¶ms->x),
*mi_eval_scalar(¶ms->y),
*mi_eval_scalar(¶ms->z));
t.transform(scale);
polygon p(t);
group.add_polygon(p.set_bounding_uvs().set_bump_basis());
group.mi(false);
return obj.mi_end(result);
}
// --------------------------------------------------------------------------------
// CUBE
struct bw_cube {
miTag name;
};
extern "C" DLLEXPORT
int bw_cube_version(void) { return 1; }
extern "C" DLLEXPORT
miBoolean bw_cube (miTag *result, miState *state, struct bw_cube *params)
{
polygon_object obj;
polygon_group group;
tlist s;
polygon p(s.square(0.0, 0.0, 0.5));
p.set_bounding_uvs().set_bump_basis();
matrix rotate;
rotate.ry(90);
obj.mi_begin(get_string(state, ¶ms->name, "cube"));
group = obj.new_group();
for (int i = 0; i < 4; i++) { // Sides
group.add_polygon(p.transform(rotate));
}
group.add_polygon(p.transform(rotate.i().rx(90))); // Top
group.add_polygon(p.transform(rotate.i().s(-1).sx(-1))); // Bottom
group.mi(false);
return obj.mi_end(result);
}
// --------------------------------------------------------------------------------
// Utility functions can also be constructed from the mrpoly library
// to simplify the creation of related shaders. The "cylinder"
// function is used in the following "bw_cylinder" and "bw_cone"
// shaders.
miBoolean cylinder(miTag *result, const char* name, int sides,
float bottom_radius=0.5, float top_radius=0.5,
float start_angle=0, bool average_normals=true)
{
polygon_object obj;
polygon_group ring, caps;
tlist t, b, uvs;
matrix m;
obj.mi_begin(name);
t.arc(sides, top_radius, 0, 0, 0, start_angle, start_angle + 360.0);
t[t.size()-1] = t[0]; // Guarantee last and first points equal despite precision.
uvs = t.bounding_uvs();
polygon top(t);
top.set_uvs(uvs).set_bump_basis().transform(m.rx(-90).ty(0.5));
b.arc(sides, bottom_radius, 0, 0, 0, start_angle, start_angle + 360.0);
b[b.size()-1] = b[0];
uvs = b.bounding_uvs();
uvs.transform(m.i().sy(-1));
polygon bottom(b);
bottom.set_uvs(uvs).transform(m.i().rx(-90).ty(-0.5));
caps = obj.new_group();
caps.add_polygon(top);
caps.add_polygon(bottom);
caps.mi();
ring = obj.new_group();
tlist bt, tp;
bottom.get_positions(bt);
top.get_positions(tp);
ring.zipper(bt, tp, 0.0, 0.0, 1.0, 1.0, bt[1], tp[1]);
ring.mi(average_normals);
return obj.mi_end(result);
}
// --------------------------------------------------------------------------------
// CYLINDER
struct bw_cylinder {
miTag name;
miInteger sides;
miScalar radius;
miScalar start_angle;
miBoolean average_normals;
};
extern "C" DLLEXPORT
int bw_cylinder_version(void) { return 1; }
extern "C" DLLEXPORT
miBoolean bw_cylinder (miTag *result, miState *state, struct bw_cylinder *params)
{
miScalar radius = *mi_eval_scalar(¶ms->radius);
return cylinder(result,
get_string(state, ¶ms->name, "cylinder"),
*mi_eval_integer(¶ms->sides),
radius, radius,
*mi_eval_scalar(¶ms->start_angle),
*mi_eval_boolean(¶ms->average_normals));
}
// --------------------------------------------------------------------------------
// CONE
struct bw_cone {
miTag name;
miInteger sides;
miScalar radius;
miBoolean average_normals;
};
extern "C" DLLEXPORT
int bw_cone_version(void) { return 1; }
extern "C" DLLEXPORT
miBoolean bw_cone (miTag *result, miState *state, struct bw_cone *params)
{
return cylinder(result,
get_string(state, ¶ms->name, "cone"),
*mi_eval_integer(¶ms->sides),
*mi_eval_scalar(¶ms->radius),
0.001, 0,
*mi_eval_boolean(¶ms->average_normals));
}
// --------------------------------------------------------------------------------
// BALL
struct bw_ball {
miTag name;
miInteger div_u, div_v;
miBoolean average_normals;
};
extern "C" DLLEXPORT
int bw_ball_version(void) { return 1; }
extern "C" DLLEXPORT
miBoolean bw_ball (miTag *result, miState *state, struct bw_ball *params)
{
miInteger div_u = *mi_eval_integer(¶ms->div_u);
miInteger div_v = *mi_eval_integer(¶ms->div_v);
polygon_object obj;
polygon_group group;
tlist semicircle;
semicircle.arc(div_v, 1, 0, 0, 0, -89.9, 89.9); // Allow for caps as small polygons.
obj.mi_begin(get_string(state, ¶ms->name, "ball"));
group = obj.new_group();
group.revolver(semicircle, div_u, triple::y_axis, 0.0, 0.0, 1.0, 1.0, true);
group.mi(*mi_eval_boolean(¶ms->average_normals));
return obj.mi_end(result);
}
3 March 2008 20:23:09