NewtonCollision* CreateNewtonMesh (NewtonWorld* world, StaticEntity* ent, int* shapeIdArray) { NewtonCollision* collision; // now create and empty collision tree collision = NewtonCreateTreeCollision (world, 0); // start adding faces to the collision tree NewtonTreeCollisionBeginBuild (collision); Vertex vert; unsigned int i,j; unsigned int counter = 0; // step over the collision geometry and add all faces to the collision tree for (i = 0; i < ent->meshObj->mesh.size(); i ++) { // add each sub mesh as a face id, will will use this later for a multi material sound effect in and advanced tutorial for (j = 0; j < ent->meshObj->mesh[i]->numFaces; j++) { glm::vec3 face[3]; vert=ent->meshObj->mesh[i]->vertex[ent->meshObj->mesh[i]->face[j].point[0]]; face[0] = glm::vec3(vert.x, vert.y, vert.z)*ent->scale; vert=ent->meshObj->mesh[i]->vertex[ent->meshObj->mesh[i]->face[j].point[1]]; face[1] = glm::vec3 (vert.x, vert.y, vert.z)*ent->scale; vert=ent->meshObj->mesh[i]->vertex[ent->meshObj->mesh[i]->face[j].point[2]]; face[2] = glm::vec3 (vert.x, vert.y, vert.z)*ent->scale; counter++; if (shapeIdArray) { NewtonTreeCollisionAddFace(collision, 3, &face[0].x, sizeof (glm::vec3), shapeIdArray[i]); } else { NewtonTreeCollisionAddFace(collision, 3, &face[0].x, sizeof (glm::vec3), i + 1); } } } // end adding faces to the collision tree, also optimize the mesh for best performance NewtonTreeCollisionEndBuild (collision, 1); return collision; }
void CEffectsGame::CreateScene() { pScene->CreateSkybox("clear"); NewtonBody *bFloor = AddBox(pScene, pWorld, Vector3(0,-0.5,0), Vector3(1000,1,1000), Vector3()); NewtonCollision *col = NewtonCreateTreeCollision(pWorld, 0); NewtonTreeCollisionBeginBuild(col); Vector3 v[4] = { Vector3(-1000,0.5f,-1000), Vector3(-1000,0.5f,+1000), Vector3(+1000,0.5f,+1000), Vector3(+1000,0.5f,-1000) }; NewtonTreeCollisionAddFace(col, 4, &v[0][0], sizeof(Vector3), 1); NewtonTreeCollisionEndBuild(col, 0); NewtonBodySetCollision(bFloor, col); CObject3D *f = (CObject3D*)NewtonBodyGetUserData(bFloor); f->visible = false; NewtonBodySetMaterialGroupID(bFloor, gLevelChunksMaterialID); // floor static CTexture *floorTex = new CTexture("textures/512.png"); CMaterial *floorMat = new CMaterial(); floorMat->features = EShaderFeature::LIGHT | EShaderFeature::FOG | EShaderFeature::SHADOW | EShaderFeature::TEXTURE; CPlaneGeometry *floorGeom = new CPlaneGeometry(1000,1000); CObject3D *floor = new CMesh( floorGeom, floorMat ); floor->geometry->materials.AddToTail(floorMat); floorMat->pTexture = floorTex; floorGeom->SetTextureScale(40,40); floor->SetPosition(-500, 0, -500); pScene->Add(floor); pLevel = new CLevel(pScene, pWorld); pLevel->Create(32,80,32); int width = 24; int depth = 24; int storeys = 8; int storyHeight = 8; for (int y=0; y<storeys*storyHeight; y++) for (int x=0; x<width; x++) for (int z=0; z<depth; z++) { int block = 0; if (x==0 || z==0 || x==width-1 || z==depth-1) block = 1; if (y%storyHeight == storyHeight-1) block = 1; if (x>5 && z>5 && x<width-5 && z<depth-5) block = 0; if (y%storyHeight > 2 && y%storyHeight <= 4) { if (x%8 >= 2 && x%8 < 7) block = 0; if (z%8 >= 2 && z%8 < 7) block = 0; } if ((x==5 && z==5) || (x==width-5 && z==depth-5) || (x==5 && z==depth-5) || (x==width-5 && z==5) ) block = 4; if (block > 0) block = 4; pLevel->GetTile(x,y,z)->type = block; } int sx = 55; int sz = 55; pLevel->Recreate(); for (int x=0; x<pLevel->chunksX; x++) for (int y=0; y<pLevel->chunksY; y++) for (int z=0; z<pLevel->chunksZ; z++) { pLevel->GetChunk(x,y,z)->RecreateCollision(); } // once the map has been created, creatie bodies that will collide /*for (int x=0; x<pLevel->sizeX; x++) for (int y=0; y<pLevel->sizeY; y++) for (int z=0; z<pLevel->sizeZ; z++) { if (pLevel->GetTile(x,y,z)->type == 0) continue; CObject3D *o = new CObject3D(); o->SetPosition(Vector3(x+0.5, y+0.5, z+0.5)); NewtonBody *box = CPhysics::CreateBox(pWorld, o, 1,1,1, 0); NewtonBodySetFreezeState(box, 1); delete o; }*/ // let's create a collision tree for each chunk /* for (int x=0; x<pLevel->chunksX; x++) for (int y=0; y<pLevel->chunksY; y++) for (int z=0; z<pLevel->chunksZ; z++) { NewtonCollision * col = NewtonCreateTreeCollision(pWorld, 0); NewtonTreeCollisionBeginBuild(col); CArray<Vector3> &verts = pLevel->GetChunk(x,y,z)->pMesh->geometry->vertices; for (int i=0; i<pLevel->GetChunk(x,y,z)->pMesh->geometry->faces.Size(); i++) { Face3 face = pLevel->GetChunk(x,y,z)->pMesh->geometry->faces[i]; Vector3 v[] = { verts[face.a], verts[face.b], verts[face.c] }; NewtonTreeCollisionAddFace(col, 3, &v[0][0], sizeof(Vector3), 1); } NewtonTreeCollisionEndBuild(col, 1); // create body float m[16] = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 }; NewtonBody *body = NewtonCreateBody(pWorld, col, &m[0]); NewtonReleaseCollision(pWorld, col); NewtonBody } */ /* CreateBuilding(0,0,0, 3,8,3); CreateBuilding(20,0,-10, 2,4,6); CreateBuilding(-5,0,-20, 5,2,3); */ // point light that will circle the building pLight = new CPointLight(Vector3(), SRGBA(255,200,50)); pLight->range = 8.0f; pLight->overbright = true; pScene->Add(pLight); pScene->fog = new SFog( SRGBA(172,201,241, 255), 200, 500); // point light at 0,1,0 CLight *pLight = new CPointLight(Vector3(0,1,0), RED);//SRGBA(255,233,155,255)); //pScene->Add( pLight ); pLight->specular = pLight->color;//SRGBA(255,255,255,100); pLight->range = 1; pLight->intensity = 1; // directional Sun light CDirectionalLight *pDirLight = new CDirectionalLight(Vector3(0,0,0), SRGBA(255,225,175,255)); pDirLight->SetPosition(+70,90,-70); pDirLight->LookAt(Vector3()); pDirLight->UpdateMatrixWorld(true); pDirLight->shadowNear = 20; pDirLight->shadowFar = 200; pDirLight->castShadow = true; float aspect = (float)gEngine.width / gEngine.height; pDirLight->width = 200.0f; pDirLight->height = pDirLight->width / aspect; pScene->Add( pDirLight ); // ambient light pScene->ambientColor = SRGBA(200,200,255,255); pCamera->LookAt(Vector3()); }
NewtonCollision* CreateCollisionTree (NewtonWorld* world, DemoEntity* const entity, int materialID, bool optimize) { // measure the time to build a collision tree unsigned64 timer0 = dGetTimeInMicrosenconds(); // create the collision tree geometry NewtonCollision* collision = NewtonCreateTreeCollision(world, materialID); // set the application level callback #ifdef USE_STATIC_MESHES_DEBUG_COLLISION NewtonStaticCollisionSetDebugCallback (collision, ShowMeshCollidingFaces); #endif // prepare to create collision geometry NewtonTreeCollisionBeginBuild(collision); // iterate the entire geometry an build the collision for (DemoEntity* model = entity->GetFirst(); model; model = model->GetNext()) { dMatrix matrix (model->GetMeshMatrix() * model->CalculateGlobalMatrix(entity)); DemoMesh* const mesh = (DemoMesh*)model->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); dFloat* const vertex = mesh->m_vertex; for (DemoMesh::dListNode* nodes = mesh->GetFirst(); nodes; nodes = nodes->GetNext()) { DemoSubMesh& segment = nodes->GetInfo(); int matID = segment.m_textureHandle; for (int i = 0; i < segment.m_indexCount; i += 3) { int index; dVector face[3]; index = segment.m_indexes[i + 0] * 3; face[0] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = segment.m_indexes[i + 1] * 3; face[1] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = segment.m_indexes[i + 2] * 3; face[2] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); matrix.TransformTriplex (&face[0].m_x, sizeof (dVector), &face[0].m_x, sizeof (dVector), 3); // use material ids as physics materials NewtonTreeCollisionAddFace(collision, 3, &face[0].m_x, sizeof (dVector), matID); } } } NewtonTreeCollisionEndBuild(collision, optimize ? 1 : 0); // test Serialization #if 0 FILE* file = fopen ("serialize.bin", "wb"); NewtonCollisionSerialize (world, collision, DemoEntityManager::SerializeFile, file); fclose (file); NewtonDestroyCollision (collision); file = fopen ("serialize.bin", "rb"); collision = NewtonCreateCollisionFromSerialization (world, DemoEntityManager::DeserializeFile, file); fclose (file); #endif // measure the time to build a collision tree timer0 = (dGetTimeInMicrosenconds() - timer0) / 1000; return collision; }
void CollisionDetection::addStaticTreeCollisionMesh( Entity *entity, string name) { bool meshCreated = false; NewtonCollision *treeCollision; std::stringstream out; out << name; string fileString = ConstManager::getString("cmesh_file_path"); fileString += out.str(); fileString.append(".cmesh"); cout << fileString<<endl; char *fileName = (char*) fileString.c_str(); if( !gernerateMeshes ) { FILE* meshFile; meshFile = fopen(fileName,"r"); if (meshFile!=NULL) { treeCollision = NewtonCreateCollisionFromSerialization (newtonWorld, myDeserializeCollisionCallbackFunction, meshFile); fclose (meshFile); meshCreated = true; } else { cout << "Colision detection could not read file.\nAttempting to create mesh from scratch" << endl; } } if( !meshCreated ) { treeCollision = NewtonCreateTreeCollision (newtonWorld, 0); NewtonTreeCollisionBeginBuild(treeCollision); size_t vertex_count; size_t index_count; Ogre::Vector3 *vertices; unsigned long *indices; GetMeshInformation( entity->getMesh(), vertex_count, vertices, index_count, indices, entity->getParentNode()->getPosition(), entity->getParentNode()->getOrientation(), entity->getParentNode()->_getDerivedScale()); /* Ogre::Vector3(), Ogre::Quaternion::IDENTITY, Ogre::Vector3(1,1,1)); */ dFloat vArray[9]; int i0, i1, i2; for (int i = 0; i < static_cast<int>(index_count); i += 3) { i0 = indices[i]; i1 = indices[i+1]; i2 = indices[i+2]; vArray[0] = vertices[i0].x; vArray[1] = vertices[i0].y; vArray[2] = vertices[i0].z; vArray[3] = vertices[i1].x; vArray[4] = vertices[i1].y; vArray[5] = vertices[i1].z; vArray[6] = vertices[i2].x; vArray[7] = vertices[i2].y; vArray[8] = vertices[i2].z; NewtonTreeCollisionAddFace(treeCollision, 3, vArray, sizeof(dFloat)*3, i); } NewtonTreeCollisionEndBuild(treeCollision, 1); FILE* meshFile; meshFile = fopen(fileName,"w"); if (meshFile!=NULL) { NewtonCollisionSerialize(newtonWorld, treeCollision, mySerializeCollisionCallbackFunction, meshFile); fclose (meshFile); } else { cout << "Colision detection could not write cmesh file." << endl; } } NewtonBody* rigidTree = NewtonCreateBody (newtonWorld, treeCollision); NewtonReleaseCollision (newtonWorld, treeCollision); NewtonBodySetMatrix (rigidTree, &idmatrix[0]); dFloat boxP0[3]; dFloat boxP1[3]; //possibly need this if we rely on newton //NewtonCollisionCalculateAABB (treeCollision, &idmatrix[0], &boxP0[0], &boxP1[0]); collisionsMap.insert(pair<Entity*,NewtonCollision*>(entity,treeCollision)); bodysMap.insert(pair<Entity*,NewtonBody*>(entity,rigidTree)); }
static NewtonBody* CreateBackgroundWallsAndCellingBody(NewtonWorld* world) { // make a flat quad dFloat floor[4][3] = { { -100.0f, 0.0f, 100.0f }, { 100.0f, 0.0f, 100.0f }, { 100.0f, 0.0f, -100.0f }, { -100.0f, 0.0f, -100.0f }, }; dFloat wall_N[4][3] = { { -100.0f, 0.0f, 100.0f }, { -100.0f, 100.0f, 100.0f }, { 100.0f, 100.0f, 100.0f }, { 100.0f, 0.0f, 100.0f }, }; dFloat wall_W[4][3] = { { 100.0f, 0.0f, 100.0f }, { 100.0f, 100.0f, 100.0f }, { 100.0f, 100.0f, -100.0f }, { 100.0f, 0.0f, -100.0f }, }; dFloat wall_S[4][3] = { { 100.0f, 0.0f, -100.0f }, { 100.0f, 100.0f, -100.0f }, { -100.0f, 100.0f, -100.0f }, { -100.0f, 0.0f, -100.0f }, }; dFloat wall_E[4][3] = { { -100.0f, 0.0f, -100.0f }, { -100.0f, 100.0f, -100.0f }, { -100.0f, 100.0f, 100.0f }, { -100.0f, 0.0f, 100.0f }, }; dFloat celling[4][3] = { { -100.0f, 100.0f, -100.0f }, { 100.0f, 100.0f, -100.0f }, { 100.0f, 100.0f, 100.0f }, { -100.0f, 100.0f, 100.0f }, }; // crate a collision tree NewtonCollision* const collision = NewtonCreateTreeCollision(world, 0); // start building the collision mesh NewtonTreeCollisionBeginBuild(collision); // add the face one at a time NewtonTreeCollisionAddFace(collision, 4, &floor[0][0], 3 * sizeof (dFloat), 0); NewtonTreeCollisionAddFace(collision, 4, &wall_N[0][0], 3 * sizeof (dFloat), 0); NewtonTreeCollisionAddFace(collision, 4, &wall_W[0][0], 3 * sizeof (dFloat), 0); NewtonTreeCollisionAddFace(collision, 4, &wall_S[0][0], 3 * sizeof (dFloat), 0); NewtonTreeCollisionAddFace(collision, 4, &wall_E[0][0], 3 * sizeof (dFloat), 0); NewtonTreeCollisionAddFace(collision, 4, &celling[0][0], 3 * sizeof (dFloat), 0); // finish building the collision NewtonTreeCollisionEndBuild(collision, 1); // create a body with a collision and locate at the identity matrix position dMatrix matrix(dGetIdentityMatrix()); NewtonBody* const body = NewtonCreateDynamicBody(world, collision, &matrix[0][0]); // do no forget to destroy the collision after you not longer need it NewtonDestroyCollision(collision); return body; }
bool Physics::buildStaticGeometry( osg::Group* p_root, const std::string& levelFile ) { NewtonCollision* p_collision = NULL; // check if a serialization file exists, if so then load it. otherwise build the static geometry on the fly. assert( levelFile.length() && "internal error: missing levelFile name!" ); std::string file = cleanPath( levelFile ); std::vector< std::string > path; explode( file, "/", &path ); file = yaf3d::Application::get()->getMediaPath() + YAF3DPHYSICS_MEDIA_FOLDER + path[ path.size() - 1 ] + YAF3DPHYSICS_SERIALIZE_POSTFIX; std::ifstream serializationfile; serializationfile.open( file.c_str(), std::ios_base::binary | std::ios_base::in ); if ( !serializationfile ) { log_warning << "Physics: no serialization file for physics static geometry exists, building on-the-fly ..." << std::endl; p_collision = NewtonCreateTreeCollision( _p_world, levelCollisionCallback ); NewtonTreeCollisionBeginBuild( p_collision ); // build the collision faces //-------------------------- // start timer osg::Timer_t start_tick = osg::Timer::instance()->tick(); //! iterate through all geometries and create their collision faces PhysicsVisitor physVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN, p_collision ); p_root->accept( physVisitor ); // stop timer and give out the time messure osg::Timer_t end_tick = osg::Timer::instance()->tick(); log_debug << "Physics: elapsed time for building physics collision faces = "<< osg::Timer::instance()->delta_s( start_tick, end_tick ) << std::endl; log_debug << "Physics: total num of evaluated primitives: " << physVisitor.getNumPrimitives() << std::endl; log_debug << "Physics: total num of vertices: " << physVisitor.getNumVertices() << std::endl; //-------------------------- // finalize tree building with optimization off ( because the meshes are already optimized by // osg _and_ Newton has currently problems with optimization ) NewtonTreeCollisionEndBuild( p_collision, 0 /* 1 */); } else { log_debug << "Physics: loading serialization file for physics static geometry: '" << file << "' ..." << std::endl; // start timer osg::Timer_t start_tick = osg::Timer::instance()->tick(); p_collision = NewtonCreateTreeCollisionFromSerialization( _p_world, NULL, deserializationCallback, &serializationfile ); assert( p_collision && "internal error, something went wrong during physics deserialization!" ); // stop timer and give out the time messure osg::Timer_t end_tick = osg::Timer::instance()->tick(); log_debug << "Physics: elapsed time for deserializing physics collision faces = "<< osg::Timer::instance()->delta_s( start_tick, end_tick ) << std::endl; serializationfile.close(); } _p_body = NewtonCreateBody( _p_world, p_collision ); // release collision object NewtonReleaseCollision( _p_world, p_collision ); // set Material Id for this object NewtonBodySetMaterialGroupID( _p_body, getMaterialId( "level" ) ); osg::Matrixf mat; mat.identity(); NewtonBodySetMatrix( _p_body, mat.ptr() ); // calculate the world bbox and world size float bmin[ 4 ], bmax[ 4 ]; NewtonCollisionCalculateAABB( p_collision, mat.ptr(), bmin, bmax ); bmin[ 0 ] -= 10.0f; bmin[ 1 ] -= 10.0f; bmin[ 2 ] -= 10.0f; bmin[ 3 ] = 1.0f; bmax[ 0 ] += 10.0f; bmax[ 1 ] += 10.0f; bmax[ 2 ] += 10.0f; bmax[ 3 ] = 1.0f; NewtonSetWorldSize( _p_world, bmin, bmax ); return true; }
void AddCollisionTreeMesh (DemoEntityManager* const scene) { // open the level data char fullPathName[2048]; GetWorkingFileName ("playground.ngd", fullPathName); scene->LoadScene (fullPathName); // find the visual mesh and make a collision tree NewtonWorld* const world = scene->GetNewton(); DemoEntity* const entity = scene->GetLast()->GetInfo(); DemoMesh* const mesh = (DemoMesh*)entity->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); NewtonCollision* const tree = NewtonCreateTreeCollision(world, 0); NewtonTreeCollisionBeginBuild(tree); dFloat* const vertex = mesh->m_vertex; for (DemoMesh::dListNode* node = mesh->GetFirst(); node; node = node->GetNext()){ DemoSubMesh* const subMesh = &node->GetInfo(); unsigned int* const indices = subMesh->m_indexes; int trianglesCount = subMesh->m_indexCount; for (int i = 0; i < trianglesCount; i += 3) { dVector face[3]; int index = indices[i + 0] * 3; face[0] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = indices[i + 1] * 3; face[1] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = indices[i + 2] * 3; face[2] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); int matID = 0; //matID = matID == 2 ? 1 : 2 ; NewtonTreeCollisionAddFace(tree, 3, &face[0].m_x, sizeof (dVector), matID); } } NewtonTreeCollisionEndBuild (tree, 0); // add the collision tree to the collision scene void* const proxy = NewtonSceneCollisionAddSubCollision (m_sceneCollision, tree); // destroy the original tree collision NewtonDestroyCollision (tree); // set the parameter on the added collision share dMatrix matrix (entity->GetCurrentMatrix()); NewtonCollision* const collisionTree = NewtonSceneCollisionGetCollisionFromNode (m_sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (m_sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(collisionTree, mesh); // set the application level callback #ifdef USE_STATIC_MESHES_DEBUG_COLLISION NewtonStaticCollisionSetDebugCallback (collisionTree, ShowMeshCollidingFaces); #endif mesh->AddRef(); scene->RemoveEntity (entity); #ifdef USE_TEST_ALL_FACE_USER_RAYCAST_CALLBACK // set a ray cast callback for all face ray cast NewtonTreeCollisionSetUserRayCastCallback (collisionTree, AllRayHitCallback); dVector p0 (0, 100, 0, 0); dVector p1 (0, -100, 0, 0); dVector normal(0.0f); dLong id; dFloat parameter; parameter = NewtonCollisionRayCast (collisionTree, &p0[0], &p1[0], &normal[0], &id); #endif }
Terrain::Terrain(const ion::base::String& identifier,NewtonWorld *pNewtonworld,ion::scene::Renderer& rRenderer, ion::base::Streamable& heightmap,const ion_uint32 width,const ion_uint32 depth,const ion_uint32 patchwidth, const ion_uint32 patchdepth,const ion::math::Vector3f& offset,const ion::math::Vector3f& size): m_pNewtonworld(pNewtonworld),Node(identifier) { ion_uint32 numpatchesX=(width-1)/(patchwidth-1),numpatchesZ=(depth-1)/(patchdepth-1); ion_uint16 *pHeightbuffer=new ion_uint16[(width+1)*(depth+1)]; { ion_uint16 *pHLine=pHeightbuffer; for (ion_uint32 z=0;z<depth;++z) { heightmap.read(pHLine,width*sizeof(ion_uint16)); // Copy the first height to the one extra height for correct normal vector calculations pHLine[width]=pHLine[0]; pHLine+=(width+1); } // Copy the first line to the one extra line for correct normal vector calculations memcpy(pHeightbuffer+(width+1)*depth,pHeightbuffer,(width+1)*sizeof(ion_uint16)); } const ion::math::Vector3f psize( size.x()/((float)numpatchesX), size.y(), size.z()/((float)numpatchesZ) ); ion::math::Vector3f poffset( offset.x()/*-psize.x()*0.5f*/, offset.y(), offset.z()/*-psize.z()*0.5f*/ ); ion::base::Localfile serializefile; bool fileok=serializefile.open(serializefilename,"rb"); if (fileok) { ion::base::log("Terrain::Terrain()",ion::base::Message) << "Using previously serialized terrain data\n"; serializefile.open(serializefilename,"rb"); m_pTreeCollision=NewtonCreateTreeCollisionFromSerialization(pNewtonworld,0,TerrainDeserialize,&serializefile); serializefile.close(); } else { ion::base::log("Terrain::Terrain()",ion::base::Message) << "Calculating terrain data\n"; m_pTreeCollision=NewtonCreateTreeCollision(pNewtonworld,0); NewtonTreeCollisionBeginBuild(m_pTreeCollision); { for (ion_uint32 z=0;z<(depth-1);++z) { /*float zz1=offset.z()+((float)z)/((float)(depth-1))*zsize; float zz2=offset.z()+((float)(z+1))/((float)(depth-1))*zsize;*/ float zz1=offset.z()+( ((float)z)/((float)(patchdepth-1)) )*psize.z(); float zz2=offset.z()+( ((float)(z+1))/((float)(patchdepth-1)) )*psize.z(); unsigned int zT=(z/patchdepth)&1; for (ion_uint32 x=0;x<(width-1);++x) { float xx1=offset.x()+( ((float)x)/((float)(patchwidth-1)) )*psize.x(); float xx2=offset.x()+( ((float)(x+1))/((float)(patchwidth-1)) )*psize.x(); /*float xx1=offset.x()+((float)x)/((float)(width-1))*xsize; float xx2=offset.x()+((float)(x+1))/((float)(width-1))*xsize;*/ float yy11=offset.y()+((float)(pHeightbuffer[x+z*(width+1)]))/65535.0f*size.y(); float yy21=offset.y()+((float)(pHeightbuffer[x+1+z*(width+1)]))/65535.0f*size.y(); float yy12=offset.y()+((float)(pHeightbuffer[x+(z+1)*(width+1)]))/65535.0f*size.y(); float yy22=offset.y()+((float)(pHeightbuffer[x+1+(z+1)*(width+1)]))/65535.0f*size.y(); float tri1[]={ xx1,yy11,zz1, xx1,yy12,zz2, xx2,yy21,zz1 }; float tri2[]={ xx2,yy21,zz1, xx1,yy12,zz2, xx2,yy22,zz2 }; unsigned int xT=(x/patchwidth)&1; unsigned int matID=((xT&zT)==1) ? 0 : (xT|zT); NewtonTreeCollisionAddFace(m_pTreeCollision,3,tri1,12,0); NewtonTreeCollisionAddFace(m_pTreeCollision,3,tri2,12,0); } } } NewtonTreeCollisionEndBuild(m_pTreeCollision,0); serializefile.open(serializefilename,"wb"); NewtonTreeCollisionSerialize(m_pTreeCollision,TerrainSerialize,&serializefile); serializefile.close(); } NewtonBody *pTerrainBody=NewtonCreateBody(m_pNewtonworld,m_pTreeCollision); NewtonReleaseCollision(m_pNewtonworld,m_pTreeCollision); NewtonBodySetMatrix(pTerrainBody,ion::math::Matrix4f::identitymatrix()); for (ion_uint32 z=0;z<numpatchesZ;++z) { /*if (z==0) { heightmap.read(pHeightbuffer,sizeof(ion_uint16)*width*patchdepth); } else { memcpy(pHeightbuffer,pHeightbuffer+width*(patchdepth-1),width*sizeof(ion_uint16)); heightmap.read(pHeightbuffer+width,sizeof(ion_uint16)*width*(patchdepth-1)); }*/ poffset.x()=offset.x()/*-psize.x()*0.5f*/; for (ion_uint32 x=0;x<numpatchesX;++x) { ion_uint16 *pH=pHeightbuffer+x*(patchwidth-1)+z*(width+1)*(patchdepth-1); TerrainPatch *pPatch=new TerrainPatch("tpatch",rRenderer,pH,patchwidth,width+1,patchdepth, (z==(numpatchesZ-1)),poffset,psize); poffset.x()+=psize.x(); m_Patches.push_back(pPatch); addChild(*pPatch); } poffset.z()+=psize.z(); } delete [] pHeightbuffer; }
void cCollideShapeNewton::CreateFromVertices(const unsigned int* apIndexArray, int alIndexNum, const float *apVertexArray, int alVtxStride, int alVtxNum) { float vTriVec[9]; bool bOptimize = false; bool bCreatedPlane = false; cPlanef plane; mpNewtonCollision = NewtonCreateTreeCollision(mpNewtonWorld, NULL); //Log("-- Creating mesh collision.:\n"); NewtonTreeCollisionBeginBuild(mpNewtonCollision); for(int tri = 0; tri < alIndexNum; tri+=3) { //Log("tri: %d:\n", tri/3); for(int idx =0; idx < 3; idx++) { int lVtx = apIndexArray[tri + 2-idx]*alVtxStride; vTriVec[idx*3 + 0] = apVertexArray[lVtx + 0]; vTriVec[idx*3 + 1] = apVertexArray[lVtx + 1]; vTriVec[idx*3 + 2] = apVertexArray[lVtx + 2]; } if(bOptimize==false) { cPlanef tempPlane; cVector3f vP1(vTriVec[0+0],vTriVec[0+1],vTriVec[0+2]); cVector3f vP2(vTriVec[1*3+0],vTriVec[1*3+1],vTriVec[1*3+2]); cVector3f vP3(vTriVec[2*3+0],vTriVec[2*3+1],vTriVec[2*3+2]); tempPlane.FromPoints(vP1, vP2, vP3); //Log("P1: %s P2: %s P3: %s\n",vP1.ToString().c_str(),vP2.ToString().c_str(),vP3.ToString().c_str()); //Log("Plane: a: %f b: %f c: %f d: %f\n",tempPlane.a,tempPlane.b,tempPlane.c,tempPlane.d); if(bCreatedPlane==false){ plane = tempPlane; bCreatedPlane = true; } else { if( std::abs(plane.a - tempPlane.a) > 0.001f || std::abs(plane.b - tempPlane.b) > 0.001f || std::abs(plane.c - tempPlane.c) > 0.001f || std::abs(plane.d - tempPlane.d) > 0.001f ) { bOptimize = true; } } } NewtonTreeCollisionAddFace(mpNewtonCollision,3,vTriVec,sizeof(float)*3,1); } NewtonTreeCollisionEndBuild(mpNewtonCollision, bOptimize ? 1: 0); //Set bounding box size mBoundingVolume.AddArrayPoints(apVertexArray, alVtxNum); mBoundingVolume.CreateFromPoints(alVtxStride); }
void dNewtonCollisionMesh::EndFace(bool optimize) { NewtonTreeCollisionEndBuild(m_shape, optimize ? 1 : 0); }