static NewtonBody* CreateHeightFieldTerrain (DemoEntityManager* const scene, int sizeInPowerOfTwos, dFloat cellSize, dFloat elevationScale, dFloat roughness, dFloat maxElevation, dFloat minElevation) { int size = (1 << sizeInPowerOfTwos) + 1 ; dFloat* const elevation = new dFloat [size * size]; //MakeFractalTerrain (elevation, sizeInPowerOfTwos, elevationScale, roughness, maxElevation, minElevation); MakeFractalTerrain (elevation, sizeInPowerOfTwos, elevationScale, roughness, maxElevation, minElevation); for (int i = 0; i < 4; i ++) { ApplySmoothFilter (elevation, size); } //memset (elevation, 0, size * size * sizeof (dFloat)); //SetBaseHeight (elevation, size); // apply simple calderas // MakeCalderas (elevation, size, maxElevation * 0.7f, maxElevation * 0.1f); // // create the visual mesh DemoMesh* const mesh = new DemoMesh ("terrain", elevation, size, cellSize, 1.0f/4.0f, TILE_SIZE); DemoEntity* const entity = new DemoEntity(dGetIdentityMatrix(), NULL); scene->Append (entity); entity->SetMesh(mesh, dGetIdentityMatrix()); mesh->Release(); // create the height field collision and rigid body // create the attribute map int width = size; int height = size; char* const attibutes = new char [size * size]; memset (attibutes, 0, width * height * sizeof (char)); NewtonCollision* collision = NewtonCreateHeightFieldCollision (scene->GetNewton(), width, height, 1, 0, elevation, attibutes, 1.0f, cellSize, 0); #ifdef USE_STATIC_MESHES_DEBUG_COLLISION NewtonStaticCollisionSetDebugCallback (collision, ShowMeshCollidingFaces); #endif NewtonCollisionInfoRecord collisionInfo; // keep the compiler happy memset (&collisionInfo, 0, sizeof (NewtonCollisionInfoRecord)); NewtonCollisionGetInfo (collision, &collisionInfo); width = collisionInfo.m_heightField.m_width; height = collisionInfo.m_heightField.m_height; //elevations = collisionInfo.m_heightField.m_elevation; dVector boxP0; dVector boxP1; // get the position of the aabb of this geometry dMatrix matrix (entity->GetCurrentMatrix()); NewtonCollisionCalculateAABB (collision, &matrix[0][0], &boxP0.m_x, &boxP1.m_x); matrix.m_posit = (boxP0 + boxP1).Scale (-0.5f); matrix.m_posit.m_w = 1.0f; //SetMatrix (matrix); entity->ResetMatrix (*scene, matrix); // create the terrainBody rigid body NewtonBody* const terrainBody = NewtonCreateDynamicBody(scene->GetNewton(), collision, &matrix[0][0]); // release the collision tree (this way the application does not have to do book keeping of Newton objects NewtonDestroyCollision (collision); // in newton 300 collision are instance, you need to ready it after you create a body, if you want to male call on the instance collision = NewtonBodyGetCollision(terrainBody); #if 0 // uncomment this to test horizontal displacement unsigned short* const horizontalDisplacemnet = new unsigned short[size * size]; for (int i = 0; i < size * size; i++) { horizontalDisplacemnet[i] = dRand(); } NewtonHeightFieldSetHorizontalDisplacement(collision, horizontalDisplacemnet, 0.02f); delete horizontalDisplacemnet; #endif // save the pointer to the graphic object with the body. NewtonBodySetUserData (terrainBody, entity); // set the global position of this body // NewtonBodySetMatrix (m_terrainBody, &matrix[0][0]); // set the destructor for this object //NewtonBodySetDestructorCallback (terrainBody, Destructor); // get the position of the aabb of this geometry //NewtonCollisionCalculateAABB (collision, &matrix[0][0], &boxP0.m_x, &boxP1.m_x); #ifdef USE_TEST_ALL_FACE_USER_RAYCAST_CALLBACK // set a ray cast callback for all face ray cast NewtonTreeCollisionSetUserRayCastCallback (collision, AllRayHitCallback); dVector p0 (0, 100, 0, 0); dVector p1 (0, -100, 0, 0); dVector normal; dLong id; dFloat parameter; parameter = NewtonCollisionRayCast (collision, &p0[0], &p1[0], &normal[0], &id); #endif delete[] attibutes; delete[] elevation; return terrainBody; }
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 }