void LoadTetrahedraCube(DemoEntityManager* const scene, int materialID) { dFloat mass = 5.0f; NewtonWorld* const world = scene->GetNewton(); char name[2048]; dGetWorkingFileName ("box.tet", name); NewtonMesh* const tetraCube = NewtonMeshLoadTetrahedraMesh(scene->GetNewton(), name); dMatrix aligmentUV(dGetIdentityMatrix()); int material = LoadTexture("smilli.tga"); NewtonMeshApplyBoxMapping(tetraCube, material, material, material, &aligmentUV[0][0]); NewtonMeshCalculateVertexNormals(tetraCube, 60.0f * dDegreeToRad); // make a deformable collision mesh NewtonCollision* const deformableCollision = NewtonCreateDeformableSolid(world, tetraCube, materialID); //create a rigid body with a deformable mesh m_body = CreateRigidBody(scene, mass, deformableCollision); // create the soft body mesh //m_mesh = new TetrahedraSoftMesh(tetraCube, m_body); DemoMesh* const mesh = new TetrahedraSoftMesh(scene, tetraCube, m_body); SetMesh(mesh, dGetIdentityMatrix()); // do not forget to destroy this objects, else you get bad memory leaks. mesh->Release (); NewtonDestroyCollision(deformableCollision); NewtonMeshDestroy(tetraCube); }
void ExportScene (NewtonWorld* const world, const char* const name) { char fileName[2048]; dGetWorkingFileName(name, fileName); MakeViualMesh context (world); dScene testScene (world); testScene.NewtonWorldToScene (world, &context); testScene.Serialize (fileName); }
void Friction (DemoEntityManager* const scene) { // load the skybox scene->CreateSkyBox(); // load the scene from a ngd file format char fileName[2048]; dGetWorkingFileName ("frictionDemo.ngd", fileName); scene->LoadScene (fileName); // set a default material call back NewtonWorld* const world = scene->GetNewton(); int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world); NewtonMaterialSetCollisionCallback (world, defaultMaterialID, defaultMaterialID, UserOnAABBOverlap, UserContactFriction); //NewtonMaterialSetDefaultCollidable(world, defaultMaterialID, defaultMaterialID, 0); // customize the scene after loading // set a user friction variable in the body for variable friction demos // later this will be done using LUA script int index = 0; for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBodyGetMass (body, &mass, &Ixx, &Iyy, &Izz); if (mass > 0.0f) { // use the new instance feature to ass per shape information NewtonCollision* const collision = NewtonBodyGetCollision(body); // use the collision user data to save the coefficient of friction dFloat coefficientOfFriction = dFloat (index) * 0.03f; NewtonCollisionSetUserData (collision, *((void**)&coefficientOfFriction)); // DemoEntity* const entity = (DemoEntity*) NewtonBodyGetUserData (body); // dVariable* const friction = entity->CreateVariable (FRICTION_VAR_NAME); // dAssert (friction); // friction->SetValue(dFloat (index) * 0.03f); index ++; } } // place camera into position dQuaternion rot; dVector origin (-70.0f, 10.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); // ExportScene (scene->GetNewton(), "../../../media/test1.ngd"); }
NewtonBody* ParseRagdollFile(const char* const name, dCustomActiveCharacterController* const controller) { char fileName[2048]; dGetWorkingFileName(name, fileName); char* const oldloc = setlocale(LC_ALL, 0); setlocale(LC_ALL, "C"); FILE* const imputFile = fopen(fileName, "rt"); dAssert(imputFile); MySaveLoad saveLoad(GetWorld(), imputFile, m_material); NewtonBody* const rootBone = saveLoad.Load (); fclose(imputFile); setlocale(LC_ALL, oldloc); return rootBone; }
NewtonBody* CreateLevelMesh (DemoEntityManager* const scene, const char* const name, bool optimized) { // load the scene from a ngd file format char fileName[2048]; dGetWorkingFileName (name, fileName); scene->LoadScene (fileName); NewtonBody* levelBody = NULL; NewtonWorld* const world = scene->GetNewton(); for (DemoEntityManager::dListNode* node = scene->GetLast(); node; node = node->GetPrev()) { DemoEntity* const ent = node->GetInfo(); DemoMesh* const mesh = (DemoMesh*) ent->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); if (mesh) { const dString& namePtr = mesh->GetName(); if (namePtr == "levelGeometry_mesh") { levelBody = CreateLevelMeshBody (world, ent, optimized); break; } } } return levelBody; }
//dAnimTakeData* LoadAnimation(dAnimIKController* const controller, const char* const animName) dAnimationKeyframesSequence* GetAnimationSequence(const char* const animName) { dTree<dAnimationKeyframesSequence*, dString>::dTreeNode* cachedAnimNode = m_animCache.Find(animName); if (!cachedAnimNode) { dScene scene(GetWorld()); char pathName[2048]; dGetWorkingFileName(animName, pathName); scene.Deserialize(pathName); dScene::dTreeNode* const animTakeNode = scene.FindChildByType(scene.GetRootNode(), dAnimationTake::GetRttiType()); if (animTakeNode) { //dTree<dAnimimationKeyFramesTrack*, dString> map; //const dAnimPose& basePose = controller->GetBasePose(); //dAnimTakeData* const animdata = new dAnimTakeData(basePose.GetCount()); dAnimationKeyframesSequence* const animdata = new dAnimationKeyframesSequence(); dAnimationTake* const animTake = (dAnimationTake*)scene.GetInfoFromNode(animTakeNode); animdata->SetPeriod(animTake->GetPeriod()); cachedAnimNode = m_animCache.Insert(animdata, animName); //dList<dAnimimationKeyFramesTrack>& tracks = animdata->GetTracks(); //dList<dAnimimationKeyFramesTrack>::dListNode* ptr = tracks.GetFirst(); //dList<dAnimimationKeyFramesTrack>::dListNode* ptr = tracks.Append(); //for (dAnimPose::dListNode* ptrNode = basePose.GetFirst(); ptrNode; ptrNode = ptrNode->GetNext()) { // DemoEntity* const entity = (DemoEntity*)ptrNode->GetInfo().m_userData; // map.Insert(&ptr->GetInfo(), entity->GetName()); // ptr = ptr->GetNext(); //} dList<dAnimimationKeyFramesTrack>& tracks = animdata->GetTracks(); for (void* link = scene.GetFirstChildLink(animTakeNode); link; link = scene.GetNextChildLink(animTakeNode, link)) { dScene::dTreeNode* const node = scene.GetNodeFromLink(link); dAnimationTrack* const srcTrack = (dAnimationTrack*)scene.GetInfoFromNode(node); if (srcTrack->IsType(dAnimationTrack::GetRttiType())) { //dTree<dAnimimationKeyFramesTrack*, dString>::dTreeNode* const ptrNode = map.Find(srcTrack->GetName()); //dAssert(ptrNode); //dAnimTakeData::dAnimTakeTrack* const dstTrack = ptrNode->GetInfo(); dAnimimationKeyFramesTrack* const dstTrack = &tracks.Append()->GetInfo(); dstTrack->SetName(srcTrack->GetName()); const dList<dAnimationTrack::dCurveValue>& rotations = srcTrack->GetRotations(); dstTrack->m_rotation.Resize(rotations.GetCount()); int index = 0; for (dList<dAnimationTrack::dCurveValue>::dListNode* node = rotations.GetFirst(); node; node = node->GetNext()) { dAnimationTrack::dCurveValue keyFrame(node->GetInfo()); dMatrix matrix(dPitchMatrix(keyFrame.m_x) * dYawMatrix(keyFrame.m_y) * dRollMatrix(keyFrame.m_z)); dQuaternion rot(matrix); dstTrack->m_rotation[index].m_rotation = rot; dstTrack->m_rotation[index].m_time = keyFrame.m_time; index++; } for (int i = 0; i < rotations.GetCount() - 1; i++) { dFloat dot = dstTrack->m_rotation[i].m_rotation.DotProduct(dstTrack->m_rotation[i + 1].m_rotation); if (dot < 0.0f) { dstTrack->m_rotation[i + 1].m_rotation.m_x *= -1.0f; dstTrack->m_rotation[i + 1].m_rotation.m_y *= -1.0f; dstTrack->m_rotation[i + 1].m_rotation.m_z *= -1.0f; dstTrack->m_rotation[i + 1].m_rotation.m_w *= -1.0f; } } const dList<dAnimationTrack::dCurveValue>& positions = srcTrack->GetPositions(); dstTrack->m_position.Resize(positions.GetCount()); index = 0; for (dList<dAnimationTrack::dCurveValue>::dListNode* node = positions.GetFirst(); node; node = node->GetNext()) { dAnimationTrack::dCurveValue keyFrame(node->GetInfo()); dstTrack->m_position[index].m_posit = dVector(keyFrame.m_x, keyFrame.m_y, keyFrame.m_z, dFloat(1.0f)); dstTrack->m_position[index].m_time = keyFrame.m_time; index++; } } } } } dAssert(cachedAnimNode); return cachedAnimNode->GetInfo(); }
// Loads the texture from the specified file and stores it in iTexture. Note // that we're using the GLAUX library here, which is generally discouraged, // but in this case spares us having to write a bitmap loading routine. GLuint LoadTexture(const char* const filename) { #pragma pack(1) struct TGAHEADER { char identsize; // Size of ID field that follows header (0) char colorMapType; // 0 = None, 1 = palette char imageType; // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rle unsigned short colorMapStart; // First color map entry unsigned short colorMapLength; // Number of colors unsigned char colorMapBits; // bits per palette entry unsigned short xstart; // image x origin unsigned short ystart; // image y origin unsigned short width; // width in pixels unsigned short height; // height in pixels char bits; // bits per pixel (8 16, 24, 32) char descriptor; // image descriptor }; #pragma pack(8) char fullPathName[2048]; dGetWorkingFileName (filename, fullPathName); TextureCache& cache = TextureCache::GetChache(); GLuint texture = cache.GetTexture(fullPathName); if (!texture) { FILE* const pFile = fopen (fullPathName, "rb"); if(pFile == NULL) { return 0; } //dAssert (sizeof (TGAHEADER) == 18); // Read in header (binary) sizeof(TGAHEADER) = 18 TGAHEADER tgaHeader; // TGA file header fread(&tgaHeader, 18, 1, pFile); // Do byte swap for big vs little Indian tgaHeader.colorMapStart = SWAP_INT16(tgaHeader.colorMapStart); tgaHeader.colorMapLength = SWAP_INT16(tgaHeader.colorMapLength); tgaHeader.xstart = SWAP_INT16(tgaHeader.xstart); tgaHeader.ystart = SWAP_INT16(tgaHeader.ystart); tgaHeader.width = SWAP_INT16(tgaHeader.width); tgaHeader.height = SWAP_INT16(tgaHeader.height); // Get width, height, and depth of texture int width = tgaHeader.width; int height = tgaHeader.height; short sDepth = tgaHeader.bits / 8; dAssert ((sDepth == 3) || (sDepth == 4)); // Put some validity checks here. Very simply, I only understand // or care about 8, 24, or 32 bit targa's. if(tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32) { fclose(pFile); return 0; } // Calculate size of image buffer unsigned lImageSize = width * height * sDepth; // Allocate memory and check for success char* const pBits = new char [width * height * 4]; if(pBits == NULL) { fclose(pFile); return 0; } // Read in the bits // Check for read error. This should catch RLE or other // weird formats that I don't want to recognize if(fread(pBits, lImageSize, 1, pFile) != 1) { fclose(pFile); delete[] pBits; return 0; } TextureImageFormat format = m_rgb; switch(sDepth) { case 1: format = m_luminace; break; case 3: format = m_rgb; break; case 4: format = m_rgba; break; }; texture = LoadImage(fullPathName, pBits, tgaHeader.width, tgaHeader.height, format); // Done with File fclose(pFile); delete[] pBits; } return texture; }
static void CreateConvexAproximation (const char* const name, DemoEntityManager* const scene, const dVector& origin, int instaceCount, const char* const texture) { char fileName[2048]; dGetWorkingFileName (name, fileName); NewtonWorld* const world = scene->GetNewton(); dScene compoundTestMesh (world); compoundTestMesh.Deserialize(fileName); // freeze the scale and pivot on the model compoundTestMesh.FreezeScale(); // compoundTestMesh.FreezeGeometryPivot (); dMeshNodeInfo* meshInfo = NULL; dMatrix scale (dGetIdentityMatrix()); for (dScene::dTreeNode* node = compoundTestMesh.GetFirstNode (); node; node = compoundTestMesh.GetNextNode (node)) { dNodeInfo* info = compoundTestMesh.GetInfoFromNode(node); if (info->GetTypeId() == dMeshNodeInfo::GetRttiType()) { for (void* link = compoundTestMesh.GetFirstParentLink(node); link; link = compoundTestMesh.GetNextParentLink (node, link)) { dScene::dTreeNode* const node = compoundTestMesh.GetNodeFromLink(link); dNodeInfo* const info = compoundTestMesh.GetInfoFromNode(node); if (info->GetTypeId() == dSceneNodeInfo::GetRttiType()) { scale = ((dSceneNodeInfo*)info)->GetGeometryTransform(); break; } } meshInfo = (dMeshNodeInfo*) info; break; } } NewtonMeshApplyTransform(meshInfo->GetMesh(), &scale[0][0]); dAssert (meshInfo); dAssert (meshInfo->GetMesh()); #if 1 NewtonMesh* const mesh = meshInfo->GetMesh(); #else dGetWorkingFileName ("mesh.off", fileName); NewtonMesh* const mesh = NewtonMeshLoadOFF(world, fileName); // dMatrix scale (GetIdentityMatrix()); // //dFloat scaleMag = 0.05f; // dFloat scaleMag = 1.0f; // scale[0][0] = scaleMag; // scale[1][1] = scaleMag; // scale[2][2] = scaleMag; // NewtonMesApplyTransform (mesh, &scale[0][0]); #endif //NewtonMesh* const newtonMesh = NewtonMeshSimplify(mesh, 500, ReportProgress); // create a convex approximation form the original mesh, 32 convex max and no more than 100 vertex convex hulls // NewtonMesh* const convexApproximation = NewtonMeshApproximateConvexDecomposition (mesh, 0.01f, 0.2f, 32, 100, ReportProgress, scene); NewtonMesh* const convexApproximation = NewtonMeshApproximateConvexDecomposition (mesh, 0.01f, 0.2f, 256, 100, ReportProgress, scene); // NewtonMesh* const convexApproximation = NewtonMeshApproximateConvexDecomposition (mesh, 0.00001f, 0.0f, 256, 100, ReportProgress, scene); // create a compound collision by creation a convex hull of each segment of the source mesh NewtonCollision* const compound = NewtonCreateCompoundCollisionFromMesh (world, convexApproximation, 0.001f, 0, 0); // test collision mode // NewtonCollisionSetCollisonMode(compound, 0); // make a visual Mesh int tex = LoadTexture(texture); dMatrix aligmentUV(dGetIdentityMatrix()); NewtonMeshApplyBoxMapping(mesh, tex, tex, tex, &aligmentUV[0][0]); DemoMesh* const visualMesh = new DemoMesh (mesh); dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit = origin; for (int ix = 0; ix < instaceCount; ix ++) { for (int iz = 0; iz < instaceCount; iz ++) { dFloat y = origin.m_y; dFloat x = origin.m_x + (ix - instaceCount/2) * 10.0f; dFloat z = origin.m_z + (iz - instaceCount/2) * 10.0f; matrix.m_posit = FindFloor (world, dVector (x, y + 10.0f, z, 0.0f), 20.0f); ; matrix.m_posit.m_y += 2.0f; CreateSimpleSolid (scene, visualMesh, 10.0f, matrix, compound, 0); } } visualMesh->Release(); NewtonDestroyCollision(compound); NewtonMeshDestroy (convexApproximation); }