00001 #include <esg/OSGAdapter.h>
00002 #include <esg/spacesorting/FDH14Tree.h>
00003 #include <esg/spacesorting/FDH6Tree.h>
00004 #include <esg/spacesorting/SphereTree.h>
00005
00006 using namespace esg;
00007
00008 void OSGAdapter::_put_polygon(osg::Geometry::PrimitiveSetList * pDrawArraysList,
00009 osg::Vec3Array * pVertArray,
00010 osg::Vec3Array * pNormalArray,
00011 osg::Geometry::AttributeBinding normal_binding)
00012 {
00013 unsigned int i;
00014 osg::PrimitiveSet *pDrawArrays;
00015 osg::Geometry::PrimitiveSetList::iterator itr;
00016 int first = 0, count = 0;
00017
00018 OSGPolygon *osgpolygon;
00019
00020 i = 0;
00021 for (itr = pDrawArraysList->begin();
00022 itr != pDrawArraysList->end();
00023 itr++)
00024 {
00025 pDrawArrays = (*itr).get();
00026
00027
00028 switch (pDrawArrays->getType()) {
00029 case osg::PrimitiveSet::PrimitiveType:
00030 count = pDrawArrays->getNumIndices();
00031
00032 break;
00033 case osg::PrimitiveSet::DrawArraysPrimitiveType:
00034
00035 count = pDrawArrays->getNumIndices();
00036
00037 break;
00038 case osg::PrimitiveSet::DrawArrayLengthsPrimitiveType:
00039 count = pDrawArrays->getNumIndices();
00040
00041 break;
00042 case osg::PrimitiveSet::DrawElementsUBytePrimitiveType:
00043 count = pDrawArrays->getNumIndices();
00044
00045 break;
00046 case osg::PrimitiveSet::DrawElementsUShortPrimitiveType:
00047 count = pDrawArrays->getNumIndices();
00048
00049 break;
00050 case osg::PrimitiveSet::DrawElementsUIntPrimitiveType:
00051 count = pDrawArrays->getNumIndices();
00052
00053 break;
00054 }
00055
00056 osg::PrimitiveSet::Mode mode = (osg::PrimitiveSet::Mode) pDrawArrays->getMode();
00057
00058 switch (mode) {
00059 case osg::PrimitiveSet::TRIANGLES:
00060
00061 for (register int j = 0; j < count; j+=3) {
00062 _pGroupNode->append(new OSGPolygon((GLint) first, (GLint) j,
00063 pDrawArrays->getType(),
00064 mode, pVertArray,
00065 pDrawArrays,
00066 pNormalArray, normal_binding));
00067 }
00068 break;
00069 case osg::PrimitiveSet::QUADS:
00070
00071 for (register int j = 0; j < count; j+=4)
00072 _pGroupNode->append(new OSGPolygon((GLint) first, (GLint) j,
00073 pDrawArrays->getType(),
00074 mode,
00075 pVertArray, pDrawArrays,
00076 pNormalArray, normal_binding));
00077 break;
00078 case osg::PrimitiveSet::TRIANGLE_STRIP:
00079
00080 for (register int j = 0; j < count-2; j++) {
00081 _pGroupNode->append(osgpolygon = new OSGPolygon((GLint) first,
00082 (GLint) j,
00083 pDrawArrays->getType(),
00084 mode,
00085 pVertArray,
00086 pDrawArrays,
00087 pNormalArray,
00088 normal_binding));
00089 }
00090 break;
00091 case osg::PrimitiveSet::QUAD_STRIP:
00092
00093 for (register int j = 0; j < count-3; j+=2)
00094 _pGroupNode->append(new OSGPolygon((GLint) first, (GLint) j,
00095 pDrawArrays->getType(),
00096 mode,
00097 pVertArray, pDrawArrays,
00098 pNormalArray,
00099 normal_binding));
00100 break;
00101 case osg::PrimitiveSet::POLYGON:
00102
00103 _pGroupNode->append(new OSGPolygon((GLint) first, 0,
00104 pDrawArrays->getType(), mode,
00105 pVertArray, pDrawArrays,
00106 pNormalArray, normal_binding));
00107 break;
00108 case osg::PrimitiveSet::TRIANGLE_FAN:
00109
00110 first =0;
00111 for (register int j = 1; j < count-1; j++)
00112 _pGroupNode->append(new OSGPolygon((GLint) first, (GLint) j,
00113 pDrawArrays->getType(),
00114 mode,
00115 pVertArray,
00116 pDrawArrays,
00117 pNormalArray,
00118 normal_binding));
00119 break;
00120 default:
00121 fprintf(stderr,"OSGFactory::_put_polyon(): Unsupported OSG primitive mode\n");
00122 break;
00123 }
00124 }
00125 }
00126
00127
00128 OSGAdapter::OSGAdapter(osg::Geometry * pGeometry,
00129 unsigned leafLimit,
00130 unsigned depthLimit,
00131 BVList::SplitStrategy strategy,
00132 bvType bv)
00133 {
00134 switch (bv) {
00135 case BV_FDH14:
00136 _pGroupNode = new Group(FDH14Tree(leafLimit,depthLimit,true,strategy));
00137 break;
00138 case BV_AABB:
00139 _pGroupNode = new Group(FDH6Tree(leafLimit,depthLimit,true,strategy));
00140 break;
00141 case BV_SPHERE:
00142 default:
00143 _pGroupNode = new Group(SphereTree(leafLimit,depthLimit,true,strategy));
00144 }
00145
00146 osg::Vec3 * validArray;
00147 osg::Vec3Array * pVertArray = (osg::Vec3Array *) pGeometry->getVertexArray();
00148 osg::Geometry::PrimitiveSetList *pDrawArrays = &(pGeometry->getPrimitiveSetList());
00149
00150 if (!pDrawArrays || !pVertArray) return;
00151
00152 validArray = (osg::Vec3*) pVertArray->getDataPointer();
00153 if (!validArray) return;
00154
00155 _put_polygon(pDrawArrays,
00156 pVertArray,
00157 (osg::Vec3Array*) pGeometry->getNormalArray(),
00158 pGeometry->getNormalBinding());
00159
00160 _pGroupNode->build();
00161 }
00162
00163 OSGAdapter::OSGAdapter(Geometry * pGeometry,
00164 unsigned leafLimit,
00165 unsigned depthLimit,
00166 BVList::SplitStrategy strategy,
00167 bvType bv)
00168 {
00169 switch (bv) {
00170 case BV_FDH14:
00171 _pGroupNode = new Group(FDH14Tree(leafLimit,depthLimit,true,strategy));
00172 break;
00173 case BV_AABB:
00174 _pGroupNode = new Group(FDH6Tree(leafLimit,depthLimit,true,strategy));
00175 break;
00176 case BV_SPHERE:
00177 default:
00178 _pGroupNode = new Group(SphereTree(leafLimit,depthLimit,true,strategy));
00179 }
00180
00181 SceneGraphObject * pObj = new Leaf();
00182 pObj->setPrivateGeometry(pGeometry);
00183 _pGroupNode->append(pObj);
00184 _pGroupNode->build();
00185 }
00186
00187 OSGAdapter::OSGAdapter(AutoPtr<Geometry> * pGeometry,
00188 unsigned leafLimit,
00189 unsigned depthLimit,
00190 BVList::SplitStrategy strategy,
00191 bvType bv)
00192 {
00193 switch (bv) {
00194 case BV_FDH14:
00195 _pGroupNode = new Group(FDH14Tree(leafLimit,depthLimit,true,strategy));
00196 break;
00197 case BV_AABB:
00198 _pGroupNode = new Group(FDH6Tree(leafLimit,depthLimit,true,strategy));
00199 break;
00200 case BV_SPHERE:
00201 default:
00202 _pGroupNode = new Group(SphereTree(leafLimit,depthLimit,true,strategy));
00203 }
00204
00205 SceneGraphObject * pObj = new Leaf();
00206 pObj->setSharedGeometry(pGeometry);
00207 _pGroupNode->append(pObj);
00208 _pGroupNode->build();
00209 }
00210
00211 double* OSGAdapter::getVertices(Matrix4 * pTrMat, unsigned * num)
00212 {
00213 if (!num) return NULL;
00214 *num = 0;
00215
00216 BVH* pBVH = (BVH*) _pGroupNode->getRepository();
00217 if (!pBVH) return NULL;
00218
00219 IteratorSDS* pIter = (IteratorSDS*) pBVH->createIterator();
00220 if (!pIter) return NULL;
00221
00222 List<OSGPolygon> list;
00223 pIter->initChildrenSearch();
00224 OSGPolygon * pObj = (OSGPolygon*) pIter->firstChild();
00225 while (pObj) {
00226 list.append(pObj);
00227 pObj = (OSGPolygon*) pIter->nextChild();
00228 }
00229
00230 *num = list.length() * 9;
00231 double* array = new double [*num];
00232
00233 pObj = list.firstItem();
00234 unsigned j = 0;
00235 Vector3 v;
00236 while (pObj) {
00237 for (unsigned i = 0; i < 3; i++) {
00238 v.set(pObj->getVertex(i));
00239 if (pTrMat) pTrMat->transform(v);
00240 array[j++] = v.x;
00241 array[j++] = v.y;
00242 array[j++] = v.z;
00243 }
00244 pObj = list.nextItem();
00245 }
00246
00247 return array;
00248 }
00249
00250 double OSGAdapter::distance(Matrix4* pMatA,
00251 OSGAdapter& adapter,
00252 Matrix4* pMatB,
00253 BVH::Node** ppNodeA,
00254 BVH::Node** ppNodeB,
00255 Vector3* pDir,
00256 unsigned d1,
00257 unsigned d2)
00258 {
00259 BVH* pBVH1 = (BVH*) _pGroupNode->getRepository();
00260 BVH* pBVH2 = (BVH*) adapter._pGroupNode->getRepository();
00261
00262 return ((pBVH1 && pBVH2)
00263 ? pBVH1->distance(pMatA,*pBVH2,pMatB,ppNodeA,ppNodeB,pDir,d1,d2)
00264 : -MAXDOUBLE);
00265 }
00266
00267 bool OSGAdapter::separation(Matrix4* pMatA,
00268 OSGAdapter& adapter,
00269 Matrix4* pMatB,
00270 Vector3* pDir,
00271 unsigned d1,
00272 unsigned d2)
00273 {
00274 BVH* pBVH1 = (BVH*) _pGroupNode->getRepository();
00275 BVH* pBVH2 = (BVH*) adapter._pGroupNode->getRepository();
00276
00277 return ((pBVH1 && pBVH2)
00278 ? pBVH1->separation(pMatA, *pBVH2, pMatB, pDir, d1, d2)
00279 : true);
00280 }
00281
00282 Geometry** OSGAdapter::collision(Matrix4* pMatA,
00283 float x, float y, float z, float r, int* pObj)
00284 {
00285 BVH* pBVH = (BVH*) _pGroupNode->getRepository();
00286 return ((pBVH) ? pBVH->collision(pMatA, x, y, z, r, pObj) : NULL);
00287 }
00288
00289 PointEnv* OSGAdapter::rayIntersection(const Matrix4* pTrMat,
00290 const Vector3& origin,
00291 const Vector3& direction,
00292 int mask,
00293 float maxDist)
00294 {
00295 _pGroupNode->setPrivateTransformation((pTrMat)?new Transform(*pTrMat):NULL);
00296
00297 Intersector intersector;
00298 intersector.init(mask, maxDist);
00299
00300 RayIntExplorer explorer(origin, direction, &intersector, maxDist);
00301 explorer.explore(*_pGroupNode);
00302 PointEnv * pE = explorer.result();
00303
00304 if (pTrMat && pE) {
00305 if (pE->mask & ENV_HAVE_INTERSECTION)
00306 pTrMat->transform(pE->intersection);
00307
00308 if (pE->mask & ENV_HAVE_NORMAL) {
00309 Matrix3 rMat;
00310 Vector3 tVec, sVec;
00311 pTrMat->get(rMat, tVec, sVec);
00312 rMat.transform(pE->normal);
00313 }
00314
00315 pE->mask &= ~ENV_HAVE_TRANSFORMATION;
00316 pE->mask &= ~ENV_HAVE_ASOC_PRIMITIVE;
00317 }
00318
00319 return pE;
00320 }
00321
00322 Interval OSGAdapter::extent(const Matrix4* pTrMat, const Vector3& direction)
00323 {
00324 _pGroupNode->setPrivateTransformation((pTrMat)?new Transform(*pTrMat):NULL);
00325 ExtentExplorer explorer(direction);
00326 explorer.explore(*_pGroupNode);
00327 return explorer.result();
00328 }
00329
00330 Interval* OSGAdapter::nExtents(const Matrix4* pTrMat,
00331 const Vector3* directions,
00332 unsigned nDirs)
00333 {
00334 _pGroupNode->setPrivateTransformation((pTrMat)?new Transform(*pTrMat):NULL);
00335
00336 NExtentsExplorer explorer(directions, nDirs);
00337 explorer.explore(*_pGroupNode);
00338
00339 Interval* ret = new Interval [nDirs];
00340 for (unsigned i = 0; i < nDirs; i++) ret[i] = explorer.result(i);
00341
00342 return ret;
00343 }
00344