
This file was automatically generated from diguyOsgGraphicsLink.cpp. Do not edit this file directly; the changes will be lost.
| Introduction |
DI-Guy 'links' are essentially the same as 'bones' in other APIs.
There are two primary purposes of links:
- to form a skeleton that can be animated using motion data, and
- to serve as attachment points for shapes.
The class diguyOsgGraphicsLink is an example of a diguyGraphicsLink subclass for a scene graph environment using the DI-Guy Loader. The example subclass shows how to use the accessors of the diguyGraphicsLink class and which virtual functions should be overridden for a scene graph environment such as OSG.
Transformation Coordinate Systems
This example shows two ways that link tranform matrix data can be retrieved from the diguyGraphicsLink base class: transforms in character-local space, and transforms in link-local space.
Character Local
For the character-local approach the top-level position link is given the world space transform; this becomes the origin of the character local coordinate system. All child link transforms are in that coordinate system.
This approach will be faster than the link-local approach, as DI-Guy has already computed the character-local matrices, and they can be retrieved and applied as-is to OSG Matrixf nodes.
Link Local
For the link-local approach all links are given a transform relative to their parent link's coordinate system.
This approach will be slower than the character-local approach, for in each update call the translate, rotate, and scale values must be retrieved, and a link-local matrix generated from these values.
(This approach was used in DI-Guy versions prior to DI-Guy 11.)
| Header files and forward declarations |
#define USE_CHARACTER_LOCAL_TRANSFORMS 1 #include "diguyGraphicsMaterial.h" #include "diguyGraphicsMesh.h" #include "diguyGraphicsTexture.h" #include "diguyOsgGraphicsLink.h" #include "diguyOsgGraphicsShaderProgram.h" #include "diguyOsgGraphicsShaderInstance.h" #include "diguyOsgGraphicsShape.h" #include "diguyOsgGraphicsState.h" #include "diguyOsgUtil.h" #include <diguyCharacter.h> #include <diguyScenario.h> #include <diguyGraphicsShaderProgram.h> #include <libbdilog.h> #include <stdlib.h> #include <osg/Group> #include <osg/MatrixTransform> #include <osg/Matrixf> #include <osg/Material> #include <osg/PolygonMode> #include <osg/Shape> #include <osg/ShapeDrawable> #include <osg/StateSet> #include <osg/TexEnv> #include <osg/Texture2D> /* * Convenience constants. */ #define CONSTANT_PI ((float) 3.1415926535897932384626433832795028841971693993751058209749445923078164062862L) #define CONSTANT_DEG2RAD (CONSTANT_PI / 180.0f) osg::ref_ptr<osg::Texture2D> diguyOsgGraphicsLink::sm_degenerate_texture = NULL; /* * Top-level static variable that stores the osg group to which DI-Guy * objects should be added. */ osg::Group* diguyOsgGraphicsLink::s_diguy_attach_pt = NULL; /* * Needed for looking up the current light. (There might be a cleaner way.) */ osgViewer::Viewer* diguyOsgGraphicsLink::s_viewer = NULL;
| Constructor |
Initialize data members of the class to a known state.
Base class data will not be fully initialized until during the Build Stage, so most base class accessors should not be called here.
diguyOsgGraphicsLink::diguyOsgGraphicsLink(void* internal_data) : diguyGraphicsLink(internal_data), m_offset_node(NULL), m_dof_node(NULL), m_bounding_sphere_visual(NULL), m_diguy_osg_shader_instance(NULL), m_diguy_osg_shader_program(NULL), m_ufrm_link_matrix(NULL), m_ufrm_inverse_transform_matrix(NULL), m_ufrm_eye_point_os(NULL), m_ufrm_light_dir_os(NULL) { /* * Nothing else to do after calling base class constructor and * initializing data members. */ }
| Character Local Approach |
#if USE_CHARACTER_LOCAL_TRANSFORMS
| build |
Build Stage
Description:
Override of diguyGraphicsLink::build().
The build() function should create the objects necessary to apply offsets contained in this link to its shapes and child links.
There are two types of offsets:
- Static offsets that specify link lengths from the parent link (e.g., distance from shoulder to elbow).
- Runtime transformations, usually joint rotations, read from DI-Guy motion data.
This implementation creates osg::MatrixTransform that will allow offsets from the parent link to be applied, and transformations from DI-Guy motion data to be applied.
void diguyOsgGraphicsLink::build() { // Potential optimization // if (get_num_shapes() == 0 && !get_is_position_link()) // return; /* * If we're using the character-local transformation approach, the * offset nodes aren't needed, and the DOF nodes are attached to the * top-level position node. */ if (get_is_position_link()) { /* * The top-level position link needs an offset node. This node * is attached to the scene via s_diguy_attach_pt. It does not * have any actual offset values, however; it just serves as a * top-level handle to the node hierarchy. */ m_offset_node = new osg::MatrixTransform; /* * If a scene graph mask has been specified for the character of * this link, set the node mask to it. */ diguyCharacter* character = get_character(); if (character && character->get_scene_graph_mask() != 0) m_offset_node->setNodeMask(character->get_scene_graph_mask()); /* * Build a DOF (degree of freedom) matrix transform for this * link that will be updated each frame from motion data. * * The position link DOF node applies a transform from world * space to character-local space. */ m_dof_node = new osg::MatrixTransform; m_offset_node->addChild(m_dof_node); } else { /* * Build a DOF (degree of freedom) matrix transform for this * link that will be updated each frame from motion data. * * Non-top-level links are attached to the position link's DOF * node. They will contain character-local transforms. */ // TODO for diguy 12 we could change this to a m_group_node // and avoid using a matrix transform since the dof data is going // into the uniform link matrix m_dof_node = new osg::MatrixTransform; /* * Attach the DOF node to the position link's DOF node. */ diguyCharacter* character = get_character(); if (character) { diguyGraphicsLink* position_link = character->get_position_link(); diguyOsgGraphicsLink* osg_position_link = (diguyOsgGraphicsLink *) position_link; osg_position_link->m_dof_node->addChild(m_dof_node); } } }
| unbuild |
Unbuild Stage
Description:
Override of diguyGraphicsLink::unbuild().
The unbuild() function should destroy the objects created in the build() function.
This implementation dereference the nodes created in build().
void diguyOsgGraphicsLink::unbuild() { if (!m_dof_node) return; if (get_is_position_link()) { diguyOsgUtil::detach_and_null(m_dof_node); diguyOsgUtil::detach_and_null(m_offset_node); } else { diguyOsgUtil::detach_and_null(m_dof_node); diguyOsgUtil::detach_and_null(m_offset_node); } }
| update |
Update Stage
Description:
Override of diguyGraphicsLink::update().
The update() function should update objects created in build() with up-to-date values from motion data.
This implementation reads transformation data from the base class and loads it into the osg::MatrixTransform nodes created in build().
void diguyOsgGraphicsLink::update() { if (!m_dof_node && !m_ufrm_link_matrix) return; /* * Update the scene graph nodes created during build() with new values. * The position link matrix is in world space, all others in * character-local space. */ osg::Matrixf mat; int transpose = 1; if (!get_is_position_link()) { /* * Set the link's matrix uniform. */ get_local_transformation_matrix_4x4_ptr(mat.ptr(), transpose); m_ufrm_link_matrix->set(mat); return; } else { get_transformation_matrix_4x4_ptr(mat.ptr(), transpose); /* * We need to set the link's matrix uniform, but since the offset * from the origin will be applied as part of setting the * m_dof_node's matrix below, just set the uniform to contain the * identity matrix. Otherwise we'd end up with double offset. */ if (m_ufrm_link_matrix) { osg::Matrixf identity; identity.makeIdentity(); m_ufrm_link_matrix->set(identity); } /* * Apply scale for character. */ osg::Vec3f scale; diguyCharacter* character = get_character(); if (character) character->get_scale(&scale[0], &scale[1], &(scale[2])); if (scale[0] != 1.0f || scale[1] != 1.0f || scale[2] != 1.0f) { mat.preMultScale(scale); } /* * Set the m_dof_node matrix. */ m_dof_node->setMatrix(mat); if (s_viewer) { /* * This code is needed to get the bump map shader working. It * will need to to be adapted to your code and it relies on * s_viewer and the diguy Camera position to be set. The two * uniforms below represent the light and the camera in the * local space of the character. * * Note I'm transposing this matrix for constancy but the * transformations below are the reverse of what I would expect. * Might be differences between diguy OGL and this. * Di-Guy 12.5 removed the transpose here, still a bit confused */ osg::Matrixf inv_mat; get_inverse_rotation_matrix_4x4_ptr(inv_mat.ptr(), 0, 1); m_ufrm_inverse_transform_matrix->set(inv_mat); // FIXME shouldn't doing invert twice, but it's hard to access _mat in matrix // and short on time osg::Matrixf inv_mat_no_trans; get_inverse_rotation_matrix_4x4_ptr(inv_mat_no_trans.ptr(), 0, 0); // this needs clean up now that that inverse matrix is in the vid card osg::Light* light = s_viewer->getLight(); if (light) { osg::Vec4 light_dir = light->getPosition(); light_dir = inv_mat_no_trans *light_dir; m_ufrm_light_dir_os->set(light_dir); //uniform vec4 } if (get_character()) { diguyViewCamera* camera = get_character()->get_scenario()->get_scenario_camera(); osg::Vec3 eye_point(camera->get_position_x(), camera->get_position_y(), camera->get_position_z()); //float char_pos_x, char_pos_y, char_pos_z; //get_character()->get_position(&char_pos_x, &char_pos_y, &char_pos_z); //eye_point = eye_point - osg::Vec3(char_pos_x, char_pos_y, char_pos_z); //eye_point = inv_mat_no_trans*eye_point; eye_point = inv_mat*eye_point; m_ufrm_eye_point_os->set(eye_point); //uniform vec3 } } } }
| Link Local Approach |
#else
| build |
Build Stage
Description:
Override of diguyGraphicsLink::build().
Look in the Character Local Approach build() comment above for what this function should do.
void diguyOsgGraphicsLink::build() { /* * Create a matrix that has the link's static offset transformations. * This matrix will not be changed during update() calls. */ osg::Matrixf mat; osg::Matrixf mat_temp; mat.makeIdentity(); /* * Add explicit offset translation. */ float offset_t[3]; get_offset_translation(&offset_t[0], &offset_t[1], &offset_t[2]); mat_temp.makeTranslate(offset_t[0], offset_t[1], offset_t[2]); mat.preMult(mat_temp); /* * Add explicit offset rotation. */ float offset_r[3]; get_offset_rotation(&offset_r[0], &offset_r[1], &offset_r[2]); if ((offset_r[0] != 0.0f) || (offset_r[1] != 0.0f) || (offset_r[2] != 0.0f)) { mat_temp.makeRotate(offset_r[2] * CONSTANT_DEG2RAD, osg::Vec3f(0.0f, 1.0f, 0.0f), offset_r[1] * CONSTANT_DEG2RAD, osg::Vec3f(1.0f, 0.0f, 0.0f), offset_r[0] * CONSTANT_DEG2RAD, osg::Vec3f(0.0f, 0.0f, 1.0f)); mat.preMult(mat_temp); } /* * The runtime translation values of each link may be marked as always * static. If this is the case for this link, add the runtime * translation into the offset matrix. */ if (get_translation_is_static()) { float t[3]; get_translation(&t[0], &t[1], &t[2]); mat_temp.makeTranslate(t[0], t[1], t[2]); mat.preMult(mat_temp); } /* * Runime rotation values may also be marked as static. */ if (get_rotation_is_static()) { float r[3]; get_rotation(&r[0], &r[1], &r[2]); if ((r[0] != 0.0f) || (r[1] != 0.0f) || (r[2] != 0.0f)) { mat_temp.makeRotate(r[2] * CONSTANT_DEG2RAD, osg::Vec3f(0.0f, 1.0f, 0.0f), r[1] * CONSTANT_DEG2RAD, osg::Vec3f(1.0f, 0.0f, 0.0f), r[0] * CONSTANT_DEG2RAD, osg::Vec3f(0.0f, 0.0f, 1.0f)); mat.preMult(mat_temp); } } /* * Runime scale values may also be marked as static. */ if (get_scale_is_static()) { float s[3]; get_scale(&s[0], &s[1], &s[2]); if ((s[0] != 1.0f) || (s[1] != 1.0f) || (s[2] != 1.0f)) { mat_temp.makeScale(osg::Vec3f(s[0], s[1], s[2])); mat.preMult(mat_temp); } } /* * Build an offset node for this link based on the above computed offset * matrix. */ m_offset_node = new osg::MatrixTransform; m_offset_node->setMatrix(mat); /* * Build a DOF (degree of freedom) matrix transform for this link that * will be updated each frame from motion data. * * This DOF node will be updated with link-local transform data. */ m_dof_node = new osg::MatrixTransform; m_offset_node->addChild(m_dof_node); /* * See if we should attach to parent link. The top-level position link * should not start out attached. When necessary it will be attached to * the scene graph in the attach_to_scene() function. */ if (!get_is_position_link()) { diguyGraphicsLink* parent_link = get_parent_link(); diguyOsgGraphicsLink* osg_parent_link = (diguyOsgGraphicsLink *) parent_link; osg_parent_link->m_dof_node->addChild(m_offset_node); } }
| unbuild |
Unbuild Stage
Description:
Override of diguyGraphicsLink::unbuild().
Look in the Character Local Approach unbuild() comment above for what this function should do.
void diguyOsgGraphicsLink::unbuild() { m_offset_node->removeChild(m_dof_node); if (!get_is_position_link()) { diguyGraphicsLink* parent_link = get_parent_link(); diguyOsgGraphicsLink* osg_parent_link = (diguyOsgGraphicsLink *) parent_link; osg_parent_link->m_dof_node->removeChild(m_offset_node); } /* * Setting the m_offset_node and m_dof_node ref_ptrs to NULL * dereferences the objects they point to, possibly deleting them. */ m_offset_node = NULL; m_dof_node = NULL; }
| update |
Update Stage
Description:
Override of diguyGraphicsLink::update().
Look in the Character Local Approach update() comment above for what this function should do.
void diguyOsgGraphicsLink::update() { /* * Update the scene graph nodes created during build() with new values. * * These values should be obtained by calling get_translation(), * get_rotation(), and get_scale(). */ osg::Matrixf mat; osg::Matrixf mat_temp; /* * Start with identity. */ mat.makeIdentity(); if (!get_translation_is_static()) { float t[3]; get_translation(&t[0], &t[1], &t[2]); mat_temp.makeTranslate(t[0], t[1], t[2]); mat.preMult(mat_temp); } if (!get_rotation_is_static()) { float r[3]; get_rotation(&r[0], &r[1], &r[2]); if ((r[0] != 0.0f) || (r[1] != 0.0f) || (r[2] != 0.0f)) { mat_temp.makeRotate(r[2] * CONSTANT_DEG2RAD, osg::Vec3f(0.0f, 1.0f, 0.0f), r[1] * CONSTANT_DEG2RAD, osg::Vec3f(1.0f, 0.0f, 0.0f), r[0] * CONSTANT_DEG2RAD, osg::Vec3f(0.0f, 0.0f, 1.0f)); mat.preMult(mat_temp); } } if (!get_scale_is_static()) { float s[3]; get_scale(&s[0], &s[1], &s[2]); if ((s[0] != 1.0f) || (s[1] != 1.0f) || (s[2] != 1.0f)) { mat_temp.makeScale(osg::Vec3f(s[0], s[1], s[2])); mat.preMult(mat_temp); } } /* * Set the m_dof_node matrix. */ m_dof_node->setMatrix(mat); }
| Common to Character Local and Link Local Approach |
#endif
| make_bounding_sphere_visual |
Utility function to create a sphere visual.
osg::Geode* diguyOsgGraphicsLink::make_bounding_sphere_visual(osg::Vec3& center, float radius) { osg::ref_ptr<osg::PolygonMode> polygon_mode = new osg::PolygonMode; polygon_mode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable; shape->setShape(new osg::Sphere(center, radius)); osg::Uniform* uniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "ufrm_link_matrix"); osg::Matrixf mat; mat.makeIdentity(); uniform->set(mat); osg::Geode* bounding_sphere_visual = new osg::Geode; bounding_sphere_visual->getOrCreateStateSet()->setAttribute(polygon_mode); bounding_sphere_visual->getOrCreateStateSet()->addUniform(uniform); bounding_sphere_visual->addDrawable(shape); return bounding_sphere_visual; }
| InitialBoundVisitor |
DI-Guys are modeled with parts (hands, guns, etc...) at the origin. These parts are rendered using a uniform in the shader unavailable to the OSG cull traversal. The InitialBoundVisitor is a NodeVisitor that adds a initial bound (osg::BoundingBox) to the drawable of geode nodes to ensure parts are not improperly culled.
class InitialBoundVisitor : public osg::NodeVisitor { public: InitialBoundVisitor(float edge_length) : m_edge_length(edge_length) { setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); } virtual void apply(osg::Geode& geode) { const float len = m_edge_length; const osg::BoundingBoxf bbox(osg::Vec3f(-len, -len, -len), osg::Vec3f(len, len, len)); const unsigned int num = geode.getNumDrawables(); for (unsigned int i = 0; i < num; ++i) { osg::Drawable* drawable = geode.getDrawable(i); const osg::BoundingBox& curr_bbox = drawable->getInitialBound(); if (!curr_bbox.valid()) { /* * Drawables are shared between character instances. * Only set the initial bound of the drawable if it hasn't * already been set. This avoids dirtying the bound and forcing * recomputation of bounding info for other characters sharing * this drawable. */ drawable->setInitialBound(bbox); } } traverse(geode); } private: float m_edge_length; };
| attach_to_scene |
Update Stage
Description:
Override of diguyGraphicsLink::attach_to_scene().
The attach_to_scene() function should perform the actions necessary to attach this link to somewhere on the scene graph.
This implementation attaches this link's offset node as a child to the node specified by s_diguy_attach_pt.
This function will only be called on the position link.
void diguyOsgGraphicsLink::attach_to_scene() { /* * Need m_offset_node to do attach. */ if (!m_offset_node) return; if (m_offset_node->getNumParents() > 0) { bdi_log_printf(BDI_LOG_WARN, "WARNING: Link '%s' already attached to something. " "Call to attach_to_scene() failed.\n", get_name()); return; } /* * Make the attachment. */ if (s_diguy_attach_pt) { diguyCharacter* character = get_character(); if (character) { /* * Add an initial bound (bounding box) to all drawables * of the character such that parts cull correctly. */ const float radius = character->get_default_bounding_radius(); const float len = sqrt((radius*radius)/3.0f); InitialBoundVisitor initialBoundVisitor(len); m_offset_node->accept(initialBoundVisitor); #define SHOW_BOUNDING_SPHERE 0 #if SHOW_BOUNDING_SPHERE // Show bounding sphere around characters. osg::BoundingSphere bSphere = m_offset_node->getBound(); m_bounding_sphere_visual = make_bounding_sphere_visual(bSphere.center(), bSphere.radius()); diguyGraphicsLink* position_link = character->get_position_link(); diguyOsgGraphicsLink* osg_position_link = (diguyOsgGraphicsLink *) position_link; osg_position_link->m_dof_node->addChild(m_bounding_sphere_visual); #endif } s_diguy_attach_pt->addChild(m_offset_node); } }
| detach_from_scene |
Update Stage
Description:
Override of diguyGraphicsLink::detach_from_scene().
The detach_to_scene() function should perform the actions necessary to detach this link from the scene graph.
This implementation removes this link's offset node as a child from the node specified by s_diguy_attach_pt.
This function will only be called on the position link.
void diguyOsgGraphicsLink::detach_from_scene() { /* * Need m_offset_node to do detach. */ if (!m_offset_node) return; /* * If m_offset_node has no parents, it is already detached. */ if (m_offset_node->getNumParents() == 0) { bdi_log_printf(BDI_LOG_WARN, "WARNING: Link '%s' not attached to anything. " "Call to detach_from_scene() failed.\n", get_name()); return; } if (s_diguy_attach_pt) { s_diguy_attach_pt->removeChild(m_offset_node); m_dof_node->removeChild(m_bounding_sphere_visual); m_bounding_sphere_visual = NULL; } }
| attach_to_link |
Update Stage
Description:
Override of diguyGraphicsLink::attach_to_link().
This function is similar to attach_to_scene(), but the link's object should be attached to another link instead of the scene graph.
void diguyOsgGraphicsLink::attach_to_link(diguyGraphicsLink* link) { /* * Need m_offset_node to do attach. */ if (!m_offset_node) return; /* * If m_offset_node already has parents, it is already attached. */ if (m_offset_node->getNumParents() > 0) { bdi_log_printf(BDI_LOG_WARN, "WARNING: Link '%s' already attached to something. " "Call to attach_to_link() failed.\n", get_name()); return; } /* * Attach m_offset_node of this link to m_dof_node of the * attachment link. */ diguyOsgGraphicsLink* osg_link = (diguyOsgGraphicsLink*) link; if (osg_link->m_dof_node) { osg_link->m_dof_node->addChild(m_offset_node); } }
| detach_from_link |
Update Stage
Description:
Override of diguyGraphicsLink::detach_from_link().
This function is similar to detach_from_scene(), but the link's object should be detached from another link instead of the scene graph.
void diguyOsgGraphicsLink::detach_from_link() { /* * Need m_offset_node to do detach. */ if (!m_offset_node) return; /* * If m_offset_node has no parents, it is already detached. */ if (m_offset_node->getNumParents() == 0) { bdi_log_printf(BDI_LOG_WARN, "WARNING: Link '%s' not attached to anything. " "Call to detach_from_link() failed.\n", get_name()); return; } diguyGraphicsLink* link = get_attached_to_link(); diguyOsgGraphicsLink* osg_link = (diguyOsgGraphicsLink*) link; if (osg_link->m_dof_node) { osg_link->m_dof_node->removeChild(m_offset_node); } } /* * Create a default variation object, and load it with a 1x1 place holder image */ osg::ref_ptr<osg::Texture2D> diguyOsgGraphicsLink::get_default_variation_texture() { if(sm_degenerate_texture){ return sm_degenerate_texture; } /* * Theres a small chance that this might leak a 1x1 pixel texture at shut down. */ sm_degenerate_texture = new osg::Texture2D(); GLenum pixel_format = GL_RGBA; GLint internal_texture_format = GL_RGBA; /* * Make the zero change variation texture object. The osg image will take * ownership of it. */ unsigned char* texture_map_data = new unsigned char [4]; texture_map_data[0] = 128; texture_map_data[1] = 128; texture_map_data[2] = 128; texture_map_data[3] = 255; /* * Create an osg image. */ osg::Image* osg_image = new osg::Image(); osg_image->setImage(1, 1, 1, internal_texture_format, pixel_format, GL_UNSIGNED_BYTE, texture_map_data, osg::Image::USE_NEW_DELETE, // osg will deallocate texture_map_data_copy with call to delete 4); // pack/unpack alignment // not sure this is needed sm_degenerate_texture->setUnRefImageDataAfterApply(true); sm_degenerate_texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP); sm_degenerate_texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP); sm_degenerate_texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST); sm_degenerate_texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST); sm_degenerate_texture->setResizeNonPowerOfTwoHint(true); sm_degenerate_texture->setImage(osg_image); return sm_degenerate_texture; }
| set_shader_instance |
Update Stage
Description:
Override of diguyGraphicsLink::set_shader_instance().
The set_shader_instance() function should perform the actions necessary to associate the passed shader instance with this link's node object.
This implementation updates the offset node's state set to use the passed shader's state set.
void diguyOsgGraphicsLink::set_shader_instance(diguyGraphicsShaderInstance* shader_instance) { diguyCharacter* character = get_character(); if (!character) return; /* * Convert the passed shader instance to an OSG-specific object. */ m_diguy_osg_shader_instance = (diguyOsgGraphicsShaderInstance*) shader_instance; m_diguy_osg_shader_program = NULL; osg::ref_ptr<osg::StateSet> shader_state_set = NULL; if (m_diguy_osg_shader_instance) { m_diguy_osg_shader_program = (diguyOsgGraphicsShaderProgram*) m_diguy_osg_shader_instance->get_shader_program(); bdi_log_printf(BDI_LOG_INFO, "INFO: Setting character '%s' shader instance to '%s'.\n", character->get_name(), m_diguy_osg_shader_program->get_name()); shader_state_set = new osg::StateSet(*m_diguy_osg_shader_instance->get_state_set()); /* * Add a default variation texture to the node, the shapes can override this * on a per shape basis. */ osg::ref_ptr<osg::Texture2D> texture = get_default_variation_texture(); shader_state_set->setTextureAttribute(DIGUY_TEXTURE_MAP_TYPE_COMPONENT_RAMP, texture); shader_state_set->setTextureMode(DIGUY_TEXTURE_MAP_TYPE_COMPONENT_RAMP, GL_TEXTURE_2D, osg::StateAttribute::PROTECTED | osg::StateAttribute::ON); m_offset_node->setStateSet(shader_state_set); } else { bdi_log_printf(BDI_LOG_INFO, "INFO: Un-setting character '%s' shader instance.\n", character->get_name()); m_offset_node->setStateSet(NULL); } /* * Ideally we'd only set this if m_ufrm_link_matrix is valid for the * shader. However it doesn't appear to be trivial to identify that in * OSG. Make a unique shader state per link that supports segmented * geometry. */ if (shader_state_set) { int i; for (i = 0; i < character->get_num_links(); i++) { diguyOsgGraphicsLink* link = ((diguyOsgGraphicsLink *) character->get_link_at_index(i)); if (!link->m_dof_node) continue; osg::StateSet* child_shader_state_set = new osg::StateSet(*shader_state_set); link->m_ufrm_link_matrix = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "ufrm_link_matrix"); child_shader_state_set->addUniform(link->m_ufrm_link_matrix); if (link->get_is_position_link()) { link->m_ufrm_light_dir_os = new osg::Uniform(osg::Uniform::FLOAT_VEC4, "ufrm_light_dir_os"); child_shader_state_set->addUniform(link->m_ufrm_light_dir_os); link->m_ufrm_eye_point_os = new osg::Uniform(osg::Uniform::FLOAT_VEC3, "ufrm_eye_point_os");// uniform vec3 ufrm_eye_point_os; child_shader_state_set->addUniform(link->m_ufrm_eye_point_os); link->m_ufrm_inverse_transform_matrix = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "ufrm_inverse_transform_matrix"); child_shader_state_set->addUniform(link->m_ufrm_inverse_transform_matrix); } link->m_dof_node->setStateSet(child_shader_state_set); } } }
| Create function definition |
Create and return an object of a subclass of diguyGraphicsLink. This function will be called whenever DI-Guy requires a link object.
diguyGraphicsLink* diguyOsgGraphicsLink_create_func(void* internal_data) { return new diguyOsgGraphicsLink(internal_data); }
ALL RIGHTS RESERVED.
These coded instructions, statements, and computer programs contain unpublished proprietary information of Boston Dynamics and are protected by Copyright Laws of the United States. They may not be used, duplicated, or disclosed in any form, in whole or in part, without the prior written consent from Boston Dynamics.
RESTRICTED RIGHTS LEGEND
Use, duplication, or disclosure by the government is subject to restrictions as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Sofware clause at DFARS 252.227-7013 and/or in similar or successor clauses in the FAR, or the DOD or NASA FAR Supplement, or to subparagraphs (c)(1) and (c)(2) of the Commercial Computer Software--Restricted Rights at 48 CFR 52.227-19, as applicable. Unpublished-rights reserved under the Copyright Laws of the United States.
Contractor/Manufacturer is:
Boston Dynamics/78 Fourth Avenue/Waltham MA 02451.