ObjectModel.cpp

Go to the documentation of this file.
00001 
00007 /* ---------------------------------------------------------------------------
00008  * Authors:      Tomáš Burian (tburian _AT centrum.cz)            
00009  * Thanks to:    PCJohn (peciva _AT fit.vutbr.cz)
00010  * Contributors: 
00011  *
00012  * THIS SOFTWARE IS NOT COPYRIGHTED
00013  *
00014  * This source code is offered for use in the public domain.
00015  * You may use, modify or distribute it freely.
00016  *
00017  * This source code is distributed in the hope that it will be useful but
00018  * WITHOUT ANY WARRANTY.  ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
00019  * DISCLAIMED.  This includes but is not limited to warranties of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00021  *
00022  * If you find the source code useful, authors will kindly welcome
00023  * if you give them credit and keep their names with their source code,
00024  * but do not feel to be forced to do so.
00025  * ---------------------------------------------------------------------------
00026  */
00027 
00028 //----------------------------------------------------------------------------
00029 // INCLUDEs
00030 //----------------------------------------------------------------------------
00031 
00032 #include "ShadowManager.h"
00033 #include "ObjectModel.h"
00034 
00035 //----------------------------------------------------------------------------
00036 // IMPLEMENTATION
00037 //----------------------------------------------------------------------------
00038 
00039 SbVec3f CObjectModel::prevNormal(1.0f, 1.0f, 1.0f);
00040 
00044 CObjectModel::CObjectModel()
00045 {
00046   nTriangles = 0;
00047   modelIfs = NULL;
00048   modelCoord3 = NULL;
00049   objectModelRoot = new SoSeparator;
00050 }
00051 
00052 
00056 CObjectModel::~CObjectModel()
00057 {
00058   objectModelRoot->removeAllChildren();
00059 }
00060 
00061 
00073 SbVec3f CObjectModel::faceNormal(const SbVec3f p1, const SbVec3f p2, const SbVec3f p3)
00074 {
00075   SbVec3f vector1, vector2;
00076 
00077   vector1 = p2 - p1;
00078   vector2 = p3 - p2;
00079 
00080   if ( vector1.length() <= .0f ) {
00081     ONDEBUG(printf("Error: Length of a vector1 is 0. Correcting...\n"));
00082   }
00083   if ( vector2.length() <= .0f ) {
00084     ONDEBUG(printf("Error: Length of a vector2 is 0. Correcting...\n"));
00085   }
00086 
00087   SbVec3f normal = vector1.cross(vector2);
00088   if ( normal.length() > .0f ) {
00089     normal.normalize();
00090     prevNormal = normal;
00091   } else {
00092     ONDEBUG(printf("Error: FaceNormal: Length of the normal is 0. Using previous.\n"));
00093     ONDEBUG(printf("prevNormal: %.2f %.2f %.2f \n",prevNormal[0], prevNormal[1], prevNormal[2]));
00094     normal = prevNormal;
00095 
00096 //    normal = SbVec3f(0.0f,0.0f,0.0f);
00097   }
00098 
00099   return normal;
00100 }
00101 
00102 
00114 void CObjectModel::TriangleCB(void * userdata,
00115                        SoCallbackAction * action,
00116                        const SoPrimitiveVertex * v1,
00117                        const SoPrimitiveVertex * v2,
00118                        const SoPrimitiveVertex * v3)
00119 {
00120   CObjectModel * sc = (CObjectModel *) userdata;
00121   sc->nTriangles++;
00122 
00123   // get current active material
00124   SbColor ambient;
00125   SbColor diffuse;
00126   SbColor specular; 
00127   SbColor  emission;
00128   float shininess;
00129   float transparency;
00130   int index = 0;
00131   action->getMaterial(ambient, diffuse, specular, emission, shininess, transparency, index );
00132   
00133 /*
00134   // TODO: grab normal somewhow
00135   int numnorm = action->getNumNormals();
00136   faceDetail->getPoint(i)->getCoordinateIndex();
00137   printf("object model: numnorm: %d \n", numnorm);
00138 */
00139 
00140   // create model of object's opaque triangles
00141   if ( transparency == 0.0f )
00142   {
00143     // transformation into global coords
00144 
00145       // triangle vertices
00146       const SbVec3f vtx[] = { v1->getPoint(), v2->getPoint(), v3->getPoint() };
00147       // tr. matrix
00148     const SbMatrix mm = action->getModelMatrix();
00149 
00150     // Get tr. coordinates
00151     SbVec3f vx[3];
00152     mm.multVecMatrix(vtx[0], vx[0]);
00153     mm.multVecMatrix(vtx[1], vx[1]);
00154     mm.multVecMatrix(vtx[2], vx[2]);
00155 
00156     // Add a face to face set
00157       sc->modelCoord3->point.setNum(sc->modelCoord3->point.getNum() + 3);
00158       sc->modelCoord3->point.setValues(sc->coord3idx, 3, vx);
00159 
00160       int32_t indices[] = { sc->coord3idx, sc->coord3idx + 1, sc->coord3idx + 2, -1 };
00161       sc->coord3idx += 3;
00162 
00163       int oldsize = sc->modelIfs->coordIndex.getNum();
00164       sc->modelIfs->coordIndex.setNum(oldsize + 4);
00165       sc->modelIfs->coordIndex.setValues(oldsize, 4, indices);
00166 
00167     // compute normal vector
00168     // assumes counterclockwise triangle orientation
00169     SbVec3f normal = faceNormal(vx[0], vx[1], vx[2]);
00170 
00171     // Add normals 1 per face
00172     int oldsizeN = sc->modelIfs->normalIndex.getNum();
00173     sc->modelNormal->vector.set1Value(oldsizeN, normal);
00174 
00175     sc->modelIfs->normalIndex.set1Value(oldsizeN, oldsizeN); // ??? TB
00176       sc->modelIfs->normalIndex.setNum(oldsizeN + 1);
00177   }
00178 }
00179 
00180 
00186 void CObjectModel::createFaceModel(SoSeparator * object)
00187 {
00188   ONDEBUG(printf("creating face model...\n"));
00189   ONDEBUG( printf("  objectModelRoot has %d children\n",objectModelRoot->getNumChildren()) );
00190   objectModelRoot->removeAllChildren();
00191 
00192   nTriangles = 0;
00193   coord3idx = 0;
00194 
00195     modelCoord3 = new SoCoordinate3;
00196     modelCoord3->point.setNum(0);
00197 
00198     modelIfs = new SoIndexedFaceSet;
00199     modelIfs->coordIndex.setNum(0);
00200   modelIfs->normalIndex.setNum(0);
00201 
00202     modelNormal = new SoNormal;
00203     modelNormal->vector.setNum(0);
00204 
00205   SoShapeHints * hints = new SoShapeHints;
00206   hints->shapeType = SoShapeHintsElement::SOLID;
00207   hints->vertexOrdering = SoShapeHintsElement::COUNTERCLOCKWISE;
00208   //hints->vertexOrdering = SoShapeHintsElement::CLOCKWISE;
00209   
00210   // call CB action
00211   SoCallbackAction ca;
00212   ca.addTriangleCallback(SoShape::getClassTypeId(), TriangleCB, this);
00213     ca.apply(object);
00214 
00215   // normal for each polygon
00216   SoNormalBinding *nbind = new SoNormalBinding;
00217   nbind->value.setValue(SoNormalBinding::PER_FACE_INDEXED);
00218 
00219   objectModelRoot->addChild(modelNormal);
00220   objectModelRoot->addChild(nbind);
00221   objectModelRoot->addChild(hints);
00222 
00223     objectModelRoot->addChild(modelCoord3);
00224     objectModelRoot->addChild(modelIfs);
00225   
00226   ONDEBUG(printf("Face model created. Model consists of %d triangles.\n", this->nTriangles));
00227 }
00228 
00229 
00233 SoSeparator * CObjectModel::getFaceModelNode()
00234 {
00235   return objectModelRoot;
00236 }
00237 
00238 
00242 int32_t CObjectModel::getTrianglesCount()
00243 {
00244   return nTriangles;
00245 }

Generated on Wed May 17 17:27:52 2006 for Shadow Engine by  doxygen 1.4.6-NO