// SceneGraph.cpp // NKU CSC 480/580 - Kirby // -------------------------------------------- // A first attempt at a scene graph. Bare bones. // -------------------------------------------- #include "SceneGraph.h" #include #include using namespace std ; // TransformationNode // ------------------ TransformationNode::TransformationNode() : Node() { // Identity transformation. _m[0]= 1 ; _m[4]=0 ; _m[8]= 0 ; _m[12]= 0 ; _m[1]= 0 ; _m[5]=1 ; _m[9]= 0 ; _m[13]= 0 ; _m[2]= 0 ; _m[6]=0 ; _m[10]= 1 ; _m[14]= 0 ; _m[3]= 0 ; _m[7]=0 ; _m[11]= 0 ; _m[15]= 1 ; } void TransformationNode::set( const Vector3& axis, double angle, double scale, const Vector3& trans ) // Set to a uniform TSR transformation. That is: rotate first, then scale, then translate. // Note that this is "set", not "apply further." { // For this quick & dirty version, use OpenGL's matrix stack as scratch space to do the work. glMatrixMode( GL_MODELVIEW ) ; glPushMatrix() ; glLoadIdentity() ; glTranslated( trans.dx, trans.dy, trans.dz ) ; if ( scale != 1 ) glScaled( scale, scale, scale ) ; if ( angle != 0 ) glRotated( angle, axis.dx, axis.dy, axis.dz ) ; glGetDoublev( GL_MODELVIEW_MATRIX, _m ) ; glPopMatrix() ; } void TransformationNode::set( const double m[16] ) // Set to an arbitrary 4x4 matrix (in OpenGL's column-major order). // Note that this is "set", not "apply further." { memcpy( _m, m, 16*sizeof( double ) ) ; } void TransformationNode::render() const // Compose current modelview with this transform, then render children. { glMatrixMode( GL_MODELVIEW ) ; glPushMatrix() ; glMultMatrixd( _m ) ; renderChildren() ; glPopMatrix() ; } // EnvironmentNode // --------------- EnvironmentNode::EnvironmentNode() :Node() { } // LightNode // --------------- int LightNode::_lightCount= 0 ; LightNode::LightNode() : EnvironmentNode() { _id= GL_LIGHT0 + _lightCount ; _lightCount++ ; _isOn= false ; } void LightNode::setPosition( const Point3& pt, double w ) { float pos[4] ; pos[0]= (float) pt.x ; pos[1]= (float) pt.y ; pos[2]= (float) pt.z ; pos[3]= w ; glLightfv( _id, GL_POSITION, pos ) ; } void LightNode::setAmbientColor( float r, float g, float b, float a ) { float color[4] ; color[0]= r ; color[1]= g ; color[2]= b ; color[3]= a ; glLightfv( _id, GL_AMBIENT, color ) ; } void LightNode::setDiffuseColor( float r, float g, float b, float a ) { float color[4] ; color[0]= r ; color[1]= g ; color[2]= b ; color[3]= a ; glLightfv( _id, GL_DIFFUSE, color ) ; } void LightNode::lightsOn( bool on ) { _isOn= on ; } void LightNode::render() const { glPushAttrib( GL_LIGHTING_BIT ) ; if ( _isOn ) glEnable( _id ) ; renderChildren() ; glDisable( _id ) ; glPopAttrib() ; } // AppearanceNode // --------------- AppearanceNode::AppearanceNode() :Node() { } // MaterialNode // ------------ MaterialNode::MaterialNode() :AppearanceNode() { _color[0]= _color[1]= _color[2]= _color[3]= 1 ; } void MaterialNode::setColor( float r, float g, float b, float a ) { _color[0]= r ; _color[1]= g ; _color[2]= b ; _color[3]= a ; } void MaterialNode::render() const { glPushAttrib( GL_LIGHTING_BIT ) ; glMaterialfv( GL_FRONT, GL_AMBIENT, _color ) ; glMaterialfv( GL_FRONT, GL_AMBIENT, _color ) ; renderChildren() ; glPopAttrib() ; } // ArtifactNode // ------------- ArtifactNode::ArtifactNode() :Node() { } // GlutSphereNode // -------------- GlutSphere::GlutSphere() : ArtifactNode(), _center( Point3(0,0,0) ), _upVec( Vector3(0,1,0) ) { _id= glGenLists( 1 ) ; glNewList( _id, GL_COMPILE ) ; glutSolidSphere( 1.0, 30, 30 ) ; glEndList() ; } const Point3& GlutSphere::getCenter() const { return _center ; } double GlutSphere::getRadius() const { return 1.0 ; } const Vector3& GlutSphere::getUpVec() const { return _upVec ; } double GlutSphere::getBaseDepth() const { return 0.5 ; } void GlutSphere::render() const { glCallList( _id ) ; }