void Geometry::update(u32 delta) { char szPath[MAX_PATH] = {0}; char szPath2[MAX_PATH]; while(mAniTime.current > mAniTime.end) { mAniTime.current -= mAniTime.end; } if (mSkin && mSkeleton) { mSkeleton->update(mAniTime, *mSkin); } if (!mStopAimation) { mAniTime.current += delta * m_speed;; } // Vec3 speed(0.000, 0.000, 0.0); Quaternion q(0, 0, 0, 0.000*mAniTime.current); Mat4 tQ(q); Mat4 tT = Mat4::IDENTITY; Vec3 offsetMatrix(-0.5, -0.5, 0.0); tT.setTrans(offsetMatrix); mUVMatrix = tT.inverse() * tQ * tT; // mMaterial->update(delta); }
// create physics scene void ClosestDistance (DemoEntityManager* const scene) { scene->CreateSkyBox(); // 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 NewtonWorld* const world = scene->GetNewton(); dMatrix offsetMatrix (dGetIdentityMatrix()); CreateLevelMesh (scene, "flatPlane.ngd", 1); // CreateLevelMesh (scene, "playground.ngd", 0); int materialID = NewtonMaterialGetDefaultGroupID (world); // disable collision // NewtonMaterialSetDefaultCollidable (world, materialID, materialID, 0); // PrimitiveType castinShapeType = _SPHERE_PRIMITIVE; // PrimitiveType castinShapeType = _BOX_PRIMITIVE; // PrimitiveType castinShapeType = _CAPSULE_PRIMITIVE; // PrimitiveType castinShapeType = _CYLINDER_PRIMITIVE; // PrimitiveType castinShapeType = _CONE_PRIMITIVE; // PrimitiveType castinShapeType = _TAPERED_CAPSULE_PRIMITIVE; // PrimitiveType castinShapeType = _TAPERED_CYLINDER_PRIMITIVE; // PrimitiveType castinShapeType = _CHAMFER_CYLINDER_PRIMITIVE; // PrimitiveType castinShapeType = _RANDOM_CONVEX_HULL_PRIMITIVE; // PrimitiveType castinShapeType = _REGULAR_CONVEX_HULL_PRIMITIVE; PrimitiveType castinShapeType = _COMPOUND_CONVEX_CRUZ_PRIMITIVE; // ClosestDistanceEntityManager* const parallelManager = new ClosestDistanceEntityManager (scene); dClosestDistanceManager* const castManager = new dClosestDistanceManager (scene); int count = 5; // castManager->AddPrimitives (count, dVector ( 0, 0, 0), _SPHERE_PRIMITIVE, materialID, castinShapeType); // castManager->AddPrimitives (count, dVector ( 2, 0, 2), _BOX_PRIMITIVE, materialID, castinShapeType); // castManager->AddPrimitives (count, dVector ( 4, 0, 4), _CAPSULE_PRIMITIVE, materialID, castinShapeType); // castManager->AddPrimitives (count, dVector ( 8, 0, 8), _CYLINDER_PRIMITIVE, materialID, castinShapeType); // castManager->AddPrimitives (count, dVector ( 10, 0, 10), _CHAMFER_CYLINDER_PRIMITIVE, materialID, castinShapeType); // castManager->AddPrimitives (count, dVector (- 4, 0, -4), _CONE_PRIMITIVE, materialID, castinShapeType); // castManager->AddPrimitives (count, dVector (- 6, 0, -6), _TAPERED_CAPSULE_PRIMITIVE, materialID, castinShapeType); // castManager->AddPrimitives (count, dVector (- 8, 0, -8), _TAPERED_CYLINDER_PRIMITIVE, materialID, castinShapeType); // castManager->AddPrimitives (count, dVector (-10, 0, -10), _REGULAR_CONVEX_HULL_PRIMITIVE, materialID, castinShapeType); castManager->AddPrimitives (count, dVector (-12, 0, -12), _COMPOUND_CONVEX_CRUZ_PRIMITIVE, materialID, castinShapeType); // place camera into position //dMatrix camMatrix (dYawMatrix(90.0f * 3.1416f /180.0f)); dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); dVector origin (-30.0f, 10.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); }
//----------------------------------------------------------------------------- //! 描画 //----------------------------------------------------------------------------- void EnemyBase::Render(bool isShadow) { // 死亡フラグが立っていたら処理しない if( _isDead ) return; // カリングされるかどうか Sphere hitSphere = *_myCollision.getHitSphere(); if (GmRender()->isRender(hitSphere)) return; // 移動用マトリックス Matrix offsetMatrix(_pTaskModel->getWorldMatrix()); offsetMatrix = offsetMatrix.translate(_position); Matrix rotateMatrix(_pTaskModel->getRotateMatrix()); rotateMatrix = rotateMatrix.rotateY(Degree(_rotation._y) ); _pTaskModel->setWorldMatrix(offsetMatrix); _pTaskModel->setRotateMatrix(rotateMatrix); _pTaskModel->render(isShadow); }
// create physics scene void PrimitiveCollision (DemoEntityManager* const scene) { // load the skybox scene->CreateSkyBox(); // 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 NewtonWorld* const world = scene->GetNewton(); dMatrix offsetMatrix (dGetIdentityMatrix()); int materialID = NewtonMaterialGetDefaultGroupID (world); // disable collision NewtonMaterialSetDefaultCollidable (world, materialID, materialID, 0); AddSinglePrimitive (scene, -10.0f, _SPHERE_PRIMITIVE, materialID); AddSinglePrimitive (scene, -8.0f, _BOX_PRIMITIVE, materialID); AddSinglePrimitive (scene, -6.0f, _CAPSULE_PRIMITIVE, materialID); AddSinglePrimitive (scene, -4.0f, _CYLINDER_PRIMITIVE, materialID); AddSinglePrimitive (scene, -2.0f, _CONE_PRIMITIVE, materialID); AddSinglePrimitive (scene, 4.0f, _CHAMFER_CYLINDER_PRIMITIVE, materialID); AddSinglePrimitive (scene, 6.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, materialID); AddSinglePrimitive (scene, 8.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, materialID); // here we will change the standard gravity force callback and apply null and add a for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { DemoEntity* const entity = (DemoEntity*) NewtonBodyGetUserData(body); entity->SetUserData (new ShowCollisionCollide(body)); NewtonBodySetForceAndTorqueCallback(body, PhysicsSpinBody); NewtonBodySetAutoSleep (body, 0); } // place camera into position //dMatrix camMatrix (dYawMatrix(90.0f * dDegreeToRad)); dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); dVector origin (-15.0f, 0.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); }
void StandardJoints (DemoEntityManager* const scene) { scene->CreateSkyBox(); // 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 dMatrix offsetMatrix (dGetIdentityMatrix()); CreateLevelMesh (scene, "flatPlane.ngd", 1); dVector location (0.0f, 0.0f, 0.0f, 0.0f); dVector size (1.5f, 2.0f, 2.0f, 0.0f); // AddPoweredRagDoll (scene, dVector (-20.0f, 0.0f, -15.0f)); AddDistance (scene, dVector (-20.0f, 0.0f, -25.0f)); AddLimitedBallAndSocket (scene, dVector (-20.0f, 0.0f, -20.0f)); // AddPoweredRagDoll (scene, dVector (-20.0f, 0.0f, -15.0f)); AddBallAndSockectWithFriction (scene, dVector (-20.0f, 0.0f, -10.0f)); Add6DOF (scene, dVector (-20.0f, 0.0f, -5.0f)); AddHinge (scene, dVector (-20.0f, 0.0f, 0.0f)); AddSlider (scene, dVector (-20.0f, 0.0f, 5.0f)); AddCylindrical (scene, dVector (-20.0f, 0.0f, 10.0f)); AddUniversal (scene, dVector (-20.0f, 0.0f, 15.0f)); //just to show up add some relational joints example AddGear (scene, dVector (-20.0f, 0.0f, 20.0f)); AddPulley (scene, dVector (-20.0f, 0.0f, 25.0f)); AddGearAndRack (scene, dVector (-20.0f, 0.0f, 30.0f)); AddSlidingContact (scene, dVector (-20.0f, 0.0f, 35.0f)); // AddPathFollow (scene, dVector (20.0f, 0.0f, 0.0f)); // place camera into position dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); dVector origin (-40.0f, 5.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); }
void AddCollisionSingleShape(DemoEntityManager* const scene) { dMatrix offsetMatrix (dGetIdentityMatrix()); NewtonCollision* const box = NewtonCreateBox (scene->GetNewton(), 4.0f, 0.1f, 4.0f, 0, &offsetMatrix[0][0]) ; DemoMesh* const mesh = new DemoMesh (" box", box, "metal_30.tga", "metal_30.tga", "metal_30.tga"); // add compound to the scene collision dMatrix matrix; void* proxy; NewtonCollision* shape; matrix = dRollMatrix(15.0f * 3.1416f / 180.0f); matrix.m_posit.m_y = 4.0f; matrix.m_posit.m_x = 3.0f; matrix.m_posit.m_z = 0.0f; proxy = NewtonSceneCollisionAddSubCollision (m_sceneCollision, box); shape = NewtonSceneCollisionGetCollisionFromNode (m_sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (m_sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(shape, mesh); mesh->AddRef(); matrix = dRollMatrix(-15.0f * 3.1416f / 180.0f); matrix.m_posit.m_y = 8.0f; matrix.m_posit.m_x = -3.0f; matrix.m_posit.m_z = 0.0f; proxy = NewtonSceneCollisionAddSubCollision (m_sceneCollision, box); shape = NewtonSceneCollisionGetCollisionFromNode (m_sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (m_sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(shape, mesh); mesh->AddRef(); NewtonDestroyCollision(box); mesh->Release(); }
void Restitution (DemoEntityManager* const scene) { scene->CreateSkyBox(); // 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 NewtonWorld* const world = scene->GetNewton(); dMatrix offsetMatrix (dGetIdentityMatrix()); int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world); NewtonMaterialSetCollisionCallback (world, defaultMaterialID, defaultMaterialID, NULL, UserContactRestitution); CreateLevelMesh (scene, "flatPlane.ngd", 0); dVector location (0.0f, 0.0f, 0.0f, 0.0f); dVector size (0.5f, 0.5f, 1.0f, 0.0f); // create some spheres dVector sphSize (1.0f, 1.0f, 1.0f, 0.0f); NewtonCollision* const sphereCollision = CreateConvexCollision (world, offsetMatrix, sphSize, _SPHERE_PRIMITIVE, 0); DemoMesh* const sphereMesh = new DemoMesh("sphere", sphereCollision, "smilli.tga", "smilli.tga", "smilli.tga"); // create some boxes too dVector boxSize (1.0f, 0.5f, 2.0f, 0.0f); NewtonCollision* const boxCollision = CreateConvexCollision (world, offsetMatrix, boxSize, _BOX_PRIMITIVE, 0); DemoMesh* const boxMesh = new DemoMesh("box", boxCollision, "smilli.tga", "smilli.tga", "smilli.tga"); int zCount = 10; dFloat spacing = 4.0f; dMatrix matrix (dGetIdentityMatrix()); dVector origin (matrix.m_posit); origin.m_x -= 0.0f; // create a simple scene for (int i = 0; i < zCount; i ++) { dFloat z; dFloat x; dFloat mass; dVector size (1.0f, 0.5f, 2.0f, 0.0f); x = origin.m_x; z = origin.m_z + (i - zCount / 2) * spacing; mass = 1.0f; matrix.m_posit = FindFloor (world, dVector (x, 100.0f, z), 200.0f); matrix.m_posit.m_w = 1.0f; float restitution; NewtonBody* body; NewtonCollision* collision; matrix.m_posit.m_y += 4.0f; body = CreateSimpleSolid (scene, sphereMesh, mass, matrix, sphereCollision, defaultMaterialID); NewtonBodySetLinearDamping (body, 0.0f); collision = NewtonBodyGetCollision(body); restitution = i * 0.1f + 0.083f; NewtonCollisionSetUserData (collision, *((void**)&restitution)); matrix.m_posit.m_y += 4.0f; //body = CreateSimpleSolid (scene, sphereMesh, mass, matrix, sphereCollision, defaultMaterialID, shapeOffsetMatrix); body = CreateSimpleSolid (scene, boxMesh, mass, matrix, boxCollision, defaultMaterialID); NewtonBodySetLinearDamping (body, 0.0f); collision = NewtonBodyGetCollision(body); restitution = i * 0.1f + 0.083f; NewtonCollisionSetUserData (collision, *((void**)&restitution)); matrix.m_posit.m_y += 4.0f; body = CreateSimpleSolid (scene, sphereMesh, mass, matrix, sphereCollision, defaultMaterialID); NewtonBodySetLinearDamping (body, 0.0f); collision = NewtonBodyGetCollision(body); restitution = i * 0.1f + 0.083f; NewtonCollisionSetUserData (collision, *((void**)&restitution)); matrix.m_posit.m_y += 4.0f; dVector boxSize (1.0f, 0.5f, 2.0f, 0.0f); body = CreateSimpleSolid (scene, boxMesh, mass, matrix, boxCollision, defaultMaterialID); NewtonBodySetLinearDamping (body, 0.0f); collision = NewtonBodyGetCollision(body); restitution = i * 0.1f + 0.083f; NewtonCollisionSetUserData (collision, *((void**)&restitution)); } boxMesh->Release(); sphereMesh->Release(); NewtonDestroyCollision(boxCollision); NewtonDestroyCollision(sphereCollision); dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); origin = dVector (-25.0f, 5.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); }
void WriteOutput(const String& outputFileName, bool exportAnimations, bool rotationsOnly, bool saveMaterialList) { // Begin serialization { File dest(context_); if (!dest.Open(outputFileName, FILE_WRITE)) ErrorExit("Could not open output file " + outputFileName); // ID dest.WriteFileID("UMDL"); // Vertexbuffers dest.WriteUInt(vertexBuffers_.Size()); for (unsigned i = 0; i < vertexBuffers_.Size(); ++i) vertexBuffers_[i].WriteData(dest); // Indexbuffers dest.WriteUInt(indexBuffers_.Size()); for (unsigned i = 0; i < indexBuffers_.Size(); ++i) indexBuffers_[i].WriteData(dest); // Subgeometries dest.WriteUInt(subGeometries_.Size()); for (unsigned i = 0; i < subGeometries_.Size(); ++i) { // Write bone mapping info from the first LOD level. It does not change for further LODs dest.WriteUInt(subGeometries_[i][0].boneMapping_.Size()); for (unsigned k = 0; k < subGeometries_[i][0].boneMapping_.Size(); ++k) dest.WriteUInt(subGeometries_[i][0].boneMapping_[k]); // Lod levels for this subgeometry dest.WriteUInt(subGeometries_[i].Size()); for (unsigned j = 0; j < subGeometries_[i].Size(); ++j) { dest.WriteFloat(subGeometries_[i][j].distance_); dest.WriteUInt((unsigned)subGeometries_[i][j].primitiveType_); dest.WriteUInt(subGeometries_[i][j].vertexBuffer_); dest.WriteUInt(subGeometries_[i][j].indexBuffer_); dest.WriteUInt(subGeometries_[i][j].indexStart_); dest.WriteUInt(subGeometries_[i][j].indexCount_); } } // Morphs dest.WriteUInt(morphs_.Size()); for (unsigned i = 0; i < morphs_.Size(); ++i) morphs_[i].WriteData(dest); // Skeleton dest.WriteUInt(bones_.Size()); for (unsigned i = 0; i < bones_.Size(); ++i) { dest.WriteString(bones_[i].name_); dest.WriteUInt(bones_[i].parentIndex_); dest.WriteVector3(bones_[i].bindPosition_); dest.WriteQuaternion(bones_[i].bindRotation_); dest.WriteVector3(bones_[i].bindScale_); Matrix3x4 offsetMatrix(bones_[i].derivedPosition_, bones_[i].derivedRotation_, bones_[i].derivedScale_); offsetMatrix = offsetMatrix.Inverse(); dest.Write(offsetMatrix.Data(), sizeof(Matrix3x4)); dest.WriteUByte(bones_[i].collisionMask_); if (bones_[i].collisionMask_ & 1) dest.WriteFloat(bones_[i].radius_); if (bones_[i].collisionMask_ & 2) dest.WriteBoundingBox(bones_[i].boundingBox_); } // Bounding box dest.WriteBoundingBox(boundingBox_); // Geometry centers for (unsigned i = 0; i < subGeometryCenters_.Size(); ++i) dest.WriteVector3(subGeometryCenters_[i]); } if (saveMaterialList) { String materialListName = ReplaceExtension(outputFileName, ".txt"); File listFile(context_); if (listFile.Open(materialListName, FILE_WRITE)) { for (unsigned i = 0; i < materialNames_.Size(); ++i) { // Assume the materials will be located inside the standard Materials subdirectory listFile.WriteLine("Materials/" + ReplaceExtension(SanitateAssetName(materialNames_[i]), ".xml")); } } else PrintLine("Warning: could not write material list file " + materialListName); } XMLElement skeletonRoot = skelFile_->GetRoot("skeleton"); if (skeletonRoot && exportAnimations) { // Go through animations XMLElement animationsRoot = skeletonRoot.GetChild("animations"); if (animationsRoot) { XMLElement animation = animationsRoot.GetChild("animation"); while (animation) { ModelAnimation newAnimation; newAnimation.name_ = animation.GetAttribute("name"); newAnimation.length_ = animation.GetFloat("length"); XMLElement tracksRoot = animation.GetChild("tracks"); XMLElement track = tracksRoot.GetChild("track"); while (track) { String trackName = track.GetAttribute("bone"); ModelBone* bone = 0; for (unsigned i = 0; i < bones_.Size(); ++i) { if (bones_[i].name_ == trackName) { bone = &bones_[i]; break; } } if (!bone) ErrorExit("Found animation track for unknown bone " + trackName); AnimationTrack newAnimationTrack; newAnimationTrack.name_ = trackName; if (!rotationsOnly) newAnimationTrack.channelMask_ = CHANNEL_POSITION | CHANNEL_ROTATION; else newAnimationTrack.channelMask_ = CHANNEL_ROTATION; XMLElement keyFramesRoot = track.GetChild("keyframes"); XMLElement keyFrame = keyFramesRoot.GetChild("keyframe"); while (keyFrame) { AnimationKeyFrame newKeyFrame; // Convert from right- to left-handed XMLElement position = keyFrame.GetChild("translate"); float x = position.GetFloat("x"); float y = position.GetFloat("y"); float z = position.GetFloat("z"); Vector3 pos(x, y, -z); XMLElement rotation = keyFrame.GetChild("rotate"); XMLElement axis = rotation.GetChild("axis"); float angle = -rotation.GetFloat("angle") * M_RADTODEG; x = axis.GetFloat("x"); y = axis.GetFloat("y"); z = axis.GetFloat("z"); Vector3 axisVec(x, y, -z); Quaternion rot(angle, axisVec); // Transform from bind-pose relative into absolute pos = bone->bindPosition_ + bone->bindRotation_ * pos; rot = bone->bindRotation_ * rot; newKeyFrame.time_ = keyFrame.GetFloat("time"); newKeyFrame.position_ = pos; newKeyFrame.rotation_ = rot; newAnimationTrack.keyFrames_.Push(newKeyFrame); keyFrame = keyFrame.GetNext("keyframe"); } // Make sure keyframes are sorted from beginning to end Sort(newAnimationTrack.keyFrames_.Begin(), newAnimationTrack.keyFrames_.End(), CompareKeyFrames); // Do not add tracks with no keyframes if (newAnimationTrack.keyFrames_.Size()) newAnimation.tracks_.Push(newAnimationTrack); track = track.GetNext("track"); } // Write each animation into a separate file String animationFileName = outputFileName.Replaced(".mdl", ""); animationFileName += "_" + newAnimation.name_ + ".ani"; File dest(context_); if (!dest.Open(animationFileName, FILE_WRITE)) ErrorExit("Could not open output file " + animationFileName); dest.WriteFileID("UANI"); dest.WriteString(newAnimation.name_); dest.WriteFloat(newAnimation.length_); dest.WriteUInt(newAnimation.tracks_.Size()); for (unsigned i = 0; i < newAnimation.tracks_.Size(); ++i) { AnimationTrack& track = newAnimation.tracks_[i]; dest.WriteString(track.name_); dest.WriteUByte(track.channelMask_); dest.WriteUInt(track.keyFrames_.Size()); for (unsigned j = 0; j < track.keyFrames_.Size(); ++j) { AnimationKeyFrame& keyFrame = track.keyFrames_[j]; dest.WriteFloat(keyFrame.time_); if (track.channelMask_ & CHANNEL_POSITION) dest.WriteVector3(keyFrame.position_); if (track.channelMask_ & CHANNEL_ROTATION) dest.WriteQuaternion(keyFrame.rotation_); if (track.channelMask_ & CHANNEL_SCALE) dest.WriteVector3(keyFrame.scale_); } } animation = animation.GetNext("animation"); PrintLine("Processed animation " + newAnimation.name_); } } } }
void PrecessingTops (DemoEntityManager* const scene) { scene->CreateSkyBox(); // 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 dMatrix offsetMatrix (dGetIdentityMatrix()); CreateLevelMesh (scene, "flatPlane.ngd", 1); dVector location (0.0f, 0.0f, 0.0f, 0.0f); dVector size (3.0f, 2.0f, 0.0f, 0.0f); // create an array of cones const int count = 10; // all shapes use the x axis as the axis of symmetry, to make an upright cone we apply a 90 degree rotation local matrix dMatrix shapeOffsetMatrix (dRollMatrix(-3.141592f/2.0f)); AddPrimitiveArray(scene, 50.0f, location, size, count, count, 5.0f, _CONE_PRIMITIVE, 0, shapeOffsetMatrix); // till the cont 30 degrees, and apply a local high angular velocity dMatrix matrix (dRollMatrix (-25.0f * 3.141592f / 180.0f)); dVector omega (0.0f, 50.0f, 0.0f); omega = matrix.RotateVector (omega); dVector damp (0.0f, 0.0f, 0.0f, 0.0f); int topscount = 0; NewtonBody* array[count * count]; NewtonWorld* const world = scene->GetNewton(); for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { NewtonCollision* const collision = NewtonBodyGetCollision(body); dVector com; if (NewtonCollisionGetType (collision) == SERIALIZE_ID_CONE) { array[topscount] = body; topscount ++; } } for (int i = 0; i < topscount ; i ++) { dMatrix bodyMatrix; NewtonBody* const body = array[i]; NewtonBodyGetMatrix(body, &bodyMatrix[0][0]); matrix.m_posit = bodyMatrix.m_posit; matrix.m_posit.m_y += 1.0f; NewtonBodySetMatrix(body, &matrix[0][0]); dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBodyGetMassMatrix(body, &mass, &Ixx, &Iyy, &Izz); NewtonBodySetMassMatrix(body, mass, Ixx, Iyy * 8.0f, Izz); NewtonBodySetOmega (body, &omega[0]); NewtonBodySetAutoSleep (body, 0); NewtonBodySetLinearDamping(body, 0.0f); NewtonBodySetAngularDamping (body, &damp[0]); } // place camera into position dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); dVector origin (-40.0f, 5.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); }
static void MakeFunnyCompound (DemoEntityManager* const scene, const dVector& origin) { NewtonWorld* const world = scene->GetNewton(); // create an empty compound collision NewtonCollision* const compound = NewtonCreateCompoundCollision (world, 0); #if 1 NewtonCompoundCollisionBeginAddRemove(compound); // add a bunch of convex collision at random position and orientation over the surface of a big sphere float radio = 5.0f; for (int i = 0 ; i < 300; i ++) { NewtonCollision* collision = NULL; float pitch = RandomVariable (1.0f) * 2.0f * 3.1416f; float yaw = RandomVariable (1.0f) * 2.0f * 3.1416f; float roll = RandomVariable (1.0f) * 2.0f * 3.1416f; float x = RandomVariable (0.5f); float y = RandomVariable (0.5f); float z = RandomVariable (0.5f); if ((x == 0.0f) && (y == 0.0f) && (z == 0.0f)){ x = 0.1f; } dVector p (x, y, z, 1.0f) ; p = p.Scale (radio / dSqrt (p % p)); dMatrix matrix (dPitchMatrix (pitch) * dYawMatrix (yaw) * dRollMatrix (roll)); matrix.m_posit = p; int r = dRand(); switch ((r >>2) & 3) { case 0: { collision = NewtonCreateSphere(world, 0.5, 0, &matrix[0][0]) ; break; } case 1: { collision = NewtonCreateCapsule(world, 0.3f, 0.2f, 0.5f, 0, &matrix[0][0]) ; break; } case 2: { collision = NewtonCreateCylinder(world, 0.25, 0.5, 0.25, 0, &matrix[0][0]) ; break; } case 3: { collision = NewtonCreateCone(world, 0.25, 0.25, 0, &matrix[0][0]) ; break; } } dAssert (collision); // we can set a collision id, and use data per sub collision NewtonCollisionSetUserID(collision, i); NewtonCollisionSetUserData(collision, (void*) i); // add this new collision NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); } // finish adding shapes NewtonCompoundCollisionEndAddRemove(compound); { // remove the first 10 shapes // test remove shape form a compound NewtonCompoundCollisionBeginAddRemove(compound); void* node = NewtonCompoundCollisionGetFirstNode(compound); for (int i = 0; i < 10; i ++) { //NewtonCollision* const collision = NewtonCompoundCollisionGetCollisionFromNode(compound, node); void* const nextNode = NewtonCompoundCollisionGetNextNode(compound, node); NewtonCompoundCollisionRemoveSubCollision(compound, node); node = nextNode; } // finish remove void* handle1 = NewtonCompoundCollisionGetNodeByIndex (compound, 30); void* handle2 = NewtonCompoundCollisionGetNodeByIndex (compound, 100); NewtonCollision* const shape1 = NewtonCompoundCollisionGetCollisionFromNode (compound, handle1); NewtonCollision* const shape2 = NewtonCompoundCollisionGetCollisionFromNode (compound, handle2); NewtonCollision* const copyShape1 = NewtonCollisionCreateInstance (shape1); NewtonCollision* const copyShape2 = NewtonCollisionCreateInstance (shape2); // you can also remove shape by their index NewtonCompoundCollisionRemoveSubCollisionByIndex (compound, 30); NewtonCompoundCollisionRemoveSubCollisionByIndex (compound, 100); handle1 = NewtonCompoundCollisionAddSubCollision (compound, copyShape1); handle2 = NewtonCompoundCollisionAddSubCollision (compound, copyShape2); NewtonDestroyCollision(copyShape1); NewtonDestroyCollision(copyShape2); NewtonCompoundCollisionEndAddRemove(compound); } { // show how to modify the children of a compound collision NewtonCompoundCollisionBeginAddRemove(compound); for (void* node = NewtonCompoundCollisionGetFirstNode(compound); node; node = NewtonCompoundCollisionGetNextNode(compound, node)) { NewtonCollision* const collision = NewtonCompoundCollisionGetCollisionFromNode(compound, node); // you can scale, change the matrix, change the inertia, do anything you want with the change NewtonCollisionSetUserData(collision, NULL); } NewtonCompoundCollisionEndAddRemove(compound); } // NewtonCollisionSetScale(compound, 0.5f, 0.25f, 0.125f); #else //test Yeside compound shape shape // - Rotation="1.5708 -0 0" Translation="0 0 0.024399" Size="0.021 0.096" Pos="0 0 0.115947" // - Rotation="1.5708 -0 0" Translation="0 0 0.056366" Size="0.195 0.024" Pos="0 0 0.147914" // - Rotation="1.5708 -0 0" Translation="0 0 -0.056366" Size="0.0065 0.07 Pos="0 0 0.035182" NewtonCompoundCollisionBeginAddRemove(compound); NewtonCollision* collision; dMatrix offsetMatrix (dPitchMatrix(1.5708f)); offsetMatrix.m_posit.m_z = 0.115947f; collision = NewtonCreateCylinder (world, 0.021f, 0.096f, 0, &offsetMatrix[0][0]) ; NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); offsetMatrix.m_posit.m_z = 0.035182f; collision = NewtonCreateCylinder (world, 0.0065f, 0.07f, 0, &offsetMatrix[0][0]) ; NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); offsetMatrix.m_posit.m_z = 0.147914f; collision = NewtonCreateCylinder (world, 0.195f, 0.024f, 0, &offsetMatrix[0][0]) ; NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); NewtonCompoundCollisionEndAddRemove(compound); #endif // for now we will simple make simple Box, make a visual Mesh DemoMesh* const visualMesh = new DemoMesh ("big ball", compound, "metal_30.tga", "metal_30.tga", "metal_30.tga"); int instaceCount = 2; 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) * 15.0f; dFloat z = origin.m_z + (iz - instaceCount/2) * 15.0f; matrix.m_posit = FindFloor (world, dVector (x, y + 10.0f, z, 0.0f), 20.0f); ; matrix.m_posit.m_y += 15.0f; CreateSimpleSolid (scene, visualMesh, 10.0f, matrix, compound, 0); } } visualMesh->Release(); NewtonDestroyCollision(compound); }
void SkinnedMesh::Load(const string& filename, const VertexAttributesMap_t& vertexAttributes, bool counterClockWise) { Mesh::Load(filename, vertexAttributes, counterClockWise); // Delete last model's skeleton if present if (skeleton_ != nullptr) { ModelManager::GetInstance()->RemoveSkeletonReferenceFromCache(filename_); } // Check cache first if (ModelManager::GetInstance()->CheckIfSkeletonLoaded(filename)) { skeleton_ = ModelManager::GetInstance()->LoadSkeletonFromCache(filename); return; } // Reload the scene - we need it to query information about the bones const aiScene* scene = nullptr; if (importer_ == nullptr) { importer_ = new Assimp::Importer; scene = importer_->ReadFile(filename, aiProcess_LimitBoneWeights); if (scene == nullptr) { Logger::GetInstance()->Error("Couldn't load mesh " + filename); delete importer_; importer_ = nullptr; return; } } else { scene = importer_->GetScene(); } if (!scene->HasAnimations()) { Logger::GetInstance()->Warning("Skinned mesh " + filename + " has no animations"); return; } // Because there are several sub meshes, we want to remember the bone is from which mesh set<string> necessaryBones; map<string, vector<pair<const aiBone*, size_t>>> bones; map<string, size_t> boneNameToIndex; size_t cumulativeNumVertices = 0; queue<const aiNode*> nodes; nodes.push(scene->mRootNode); /////////////////////////////////////////////////////////////////////////////////// // Load the bones from the mesh while (!nodes.empty()) { const aiNode* node = nodes.front(); nodes.pop(); for (size_t i = 0; i < node->mNumMeshes; i++) { const aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; size_t numVertices = mesh->mNumVertices; // Get the surface to set the bones and weights for GPU skinned meshes SurfaceTriangles_t* surface = surfaces_[node->mMeshes[i]]; // Retrieve for each bones the offset matrix and the vertex with their weight that are attached to it if (mesh->HasBones()) { if (meshType_ == MESH_TYPE_STATIC) { surface->numBones = surface->numVertices; surface->numWeights = surface->numVertices; surface->bones = new Vector4[surface->numBones]; surface->weights = new Vector4[surface->numWeights]; // We intialize all weights to 0 for (size_t j = 0; j < surface->numBones; j++) { Vector4& contribuingWeight = surface->weights[j]; contribuingWeight.w = 0.0f; } } for (size_t j = 0; j < mesh->mNumBones; j++) { const aiBone* bone = mesh->mBones[j]; // Only do this for a static mesh, because it will be skinned on the GPU if (meshType_ == MESH_TYPE_STATIC) { // Map the bone index that we'll give to the vertex to its name size_t boneIndex = 0; map<string, size_t>::iterator it = boneNameToIndex.find(bone->mName.data); if (it != boneNameToIndex.end()) { boneIndex = it->second; } else { boneIndex = boneNameToIndex.size(); boneNameToIndex[bone->mName.data] = boneIndex; } for (size_t k = 0; k < bone->mNumWeights; k++) { const aiVertexWeight& weight = bone->mWeights[k]; Vector4& contribuingBone = surface->bones[weight.mVertexId]; Vector4& contribuingWeights = surface->weights[weight.mVertexId]; if (contribuingWeights.x == 0.0f) { contribuingBone.x = (float)boneIndex; contribuingWeights.x = weight.mWeight; } else if (contribuingWeights.y == 0.0f) { contribuingBone.y = (float)boneIndex; contribuingWeights.y = weight.mWeight; } else if (contribuingWeights.z == 0.0f) { contribuingBone.z = (float)boneIndex; contribuingWeights.z = weight.mWeight; } else { contribuingBone.w = (float)boneIndex; contribuingWeights.w = weight.mWeight; } } } if (bones.find(bone->mName.data) == bones.end()) { bones[bone->mName.data] = vector<pair<const aiBone*, size_t>>(); } bones[bone->mName.data].push_back( pair<const aiBone*, size_t>(bone, cumulativeNumVertices) ); necessaryBones.insert(bone->mName.data); // Also, there might be some bones in the hierarchy that have no vertices attached to them // They might still be useful because they connect other bones, so we have to add them to the // skeleton. queue<const aiNode*> nodeHierarchy; nodeHierarchy.push(scene->mRootNode); while (!nodeHierarchy.empty()) { const aiNode* currentNode = nodeHierarchy.front(); nodeHierarchy.pop(); if (currentNode->mName == bone->mName) { const aiNode* parentNode = currentNode->mParent; while (parentNode != nullptr || (parentNode != nullptr && parentNode->mName == node->mName) || (node->mParent != nullptr && parentNode != nullptr && parentNode->mName == node->mParent->mName)) { necessaryBones.insert(parentNode->mName.data); parentNode = parentNode->mParent; } break; } else { for (size_t k = 0; k < currentNode->mNumChildren; k++) { nodeHierarchy.push(currentNode->mChildren[k]); } } } } } cumulativeNumVertices += numVertices; } for (size_t i = 0; i < node->mNumChildren; i++) { nodes.push(node->mChildren[i]); } } /////////////////////////////////////////////////////////////////////////////////// // Build the skeleton skeleton_ = new Skeleton; aiMatrix4x4 globalTransform = scene->mRootNode->mTransformation; Matrix4x4 globalInverseTransform(globalTransform.a1, globalTransform.a2, globalTransform.a3, globalTransform.a4, globalTransform.b1, globalTransform.b2, globalTransform.b3, globalTransform.b4, globalTransform.c1, globalTransform.c2, globalTransform.c3, globalTransform.c4, globalTransform.d1, globalTransform.d2, globalTransform.d3, globalTransform.d4); globalInverseTransform.Inverse(); skeleton_->SetGlobalInverseTransform(globalInverseTransform); nodes.push(scene->mRootNode); while (!nodes.empty()) { const aiNode* node = nodes.front(); nodes.pop(); set<string>::iterator s_it = necessaryBones.find(node->mName.data); if (s_it != necessaryBones.end()) { const aiNode* parent = node->mParent; if (parent == nullptr) { skeleton_->CreateBone(*s_it, Matrix4x4::IDENTITY); } else { // Build the bone hierarchy Bone_t* parentBone = skeleton_->FindBoneByName(parent->mName.data); if (parentBone == nullptr) { parentBone = skeleton_->CreateBone(parent->mName.data, Matrix4x4::IDENTITY); } map<string, vector<pair<const aiBone*, size_t>>>::iterator it = bones.find(node->mName.data); if (it == bones.end()) { aiMatrix4x4 offset = node->mTransformation; Matrix4x4 offsetMatrix(offset.a1, offset.a2, offset.a3, offset.a4, offset.b1, offset.b2, offset.b3, offset.b4, offset.c1, offset.c2, offset.c3, offset.c4, offset.d1, offset.d2, offset.d3, offset.d4); Bone_t* bone = skeleton_->CreateBone(*s_it, offsetMatrix); parentBone->linkedBones.push_back(bone); } else { aiMatrix4x4 offset = it->second[0].first->mOffsetMatrix; Matrix4x4 offsetMatrix(offset.a1, offset.a2, offset.a3, offset.a4, offset.b1, offset.b2, offset.b3, offset.b4, offset.c1, offset.c2, offset.c3, offset.c4, offset.d1, offset.d2, offset.d3, offset.d4); Bone_t* bone = skeleton_->CreateBone(it->first, offsetMatrix); parentBone->linkedBones.push_back(bone); // Only do this for a dynamic mesh, because it will be skinned on the GPU if (meshType_ == MESH_TYPE_DYNAMIC) { for (size_t i = 0; i < it->second.size(); i++) { const aiVertexWeight* weights = it->second[i].first->mWeights; size_t baseIndex = it->second[i].second; for (size_t j = 0; j < it->second[i].first->mNumWeights; j++) { bone->vertexWeight[baseIndex + weights[j].mVertexId] = weights[j].mWeight; } } } else { // Map the bone to the index given to the vertices boneToIndex_[bone] = boneNameToIndex[node->mName.data]; } } } } for (size_t i = 0; i < node->mNumChildren; i++) { nodes.push(node->mChildren[i]); } } /////////////////////////////////////////////////////////////////////////////////// // Load the animations for (size_t i = 0; i < scene->mNumAnimations; i++) { aiAnimation* animation = scene->mAnimations[i]; AnimationState animationState(animation->mDuration, animation->mTicksPerSecond); // Get the keys for all bones for (size_t j = 0; j < animation->mNumChannels; j++) { const aiNodeAnim* nodeAnim = animation->mChannels[j]; vector<pair<double, Vector3>> positionKeys, scaleKeys; vector<pair<double, Quaternion>> rotationKeys; // Get all the key frames for (size_t k = 0; k < nodeAnim->mNumPositionKeys; k++) { const aiVectorKey& positionKey = nodeAnim->mPositionKeys[k]; const aiVector3D& position = positionKey.mValue; positionKeys.push_back(pair<double, Vector3>( positionKey.mTime, Vector3(position.x, position.y, position.z) )); } for (size_t k = 0; k < nodeAnim->mNumRotationKeys; k++) { const aiQuatKey& rotationKey = nodeAnim->mRotationKeys[k]; const aiQuaternion& rotation = rotationKey.mValue; rotationKeys.push_back(pair<double, Quaternion>( rotationKey.mTime, Quaternion(rotation.w, rotation.x, rotation.y, rotation.z) )); } for (size_t k = 0; k < nodeAnim->mNumScalingKeys; k++) { const aiVectorKey& scalingKey = nodeAnim->mScalingKeys[k]; const aiVector3D& scale = scalingKey.mValue; scaleKeys.push_back(pair<double, Vector3>( scalingKey.mTime, Vector3(scale.x, scale.y, scale.z) )); } animationState.SetPositionKeysForBone(nodeAnim->mNodeName.data, positionKeys); animationState.SetRotationKeysForBone(nodeAnim->mNodeName.data, rotationKeys); animationState.SetScaleKeysForBone(nodeAnim->mNodeName.data, scaleKeys); } skeleton_->AddAnimationState(animation->mName.data, animationState); } // Cache the skeleton for future loads ModelManager::GetInstance()->CacheSkeleton(filename, skeleton_); Logger::GetInstance()->Info("Successfully loaded animations from file " + filename); }
void AlchimedesBuoyancy(DemoEntityManager* const scene) { // load the sky box scene->CreateSkyBox(); // load the mesh CreateLevelMesh (scene, "swimmingPool.ngd", true); // add a trigger Manager to the world MyTriggerManager* const triggerManager = new MyTriggerManager(scene->GetNewton()); dMatrix triggerLocation (dGetIdentityMatrix()); triggerLocation.m_posit.m_x = 17.0f; triggerLocation.m_posit.m_y = -3.5f; NewtonCollision* const poolBox = NewtonCreateBox (scene->GetNewton(), 30.0f, 6.0f, 20.0f, 0, NULL); triggerManager->CreateBuoyancyTrigger (triggerLocation, poolBox); NewtonDestroyCollision (poolBox); // 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 dMatrix offsetMatrix (dGetIdentityMatrix()); // place camera into position dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); dVector origin (-20.0f, 10.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); int defaultMaterialID = NewtonMaterialGetDefaultGroupID (scene->GetNewton()); /* //test buoyancy on scaled collisions dVector plane (0.0f, 1.0f, 0.0f, 0.0f); dMatrix L1 (dPitchMatrix(30.0f * 3.141692f / 180.0f) * dYawMatrix(0.0f * 3.141692f / 180.0f) * dRollMatrix(0.0f * 3.141692f / 180.0f)); NewtonCollision* xxx0 = NewtonCreateCompoundCollision(scene->GetNewton(), 0); NewtonCompoundCollisionBeginAddRemove(xxx0); NewtonCollision* xxxx0 = NewtonCreateBox(scene->GetNewton(), 1.0f, 2.0f, 1.0f, 0, &L1[0][0]); NewtonCompoundCollisionAddSubCollision(xxx0, xxxx0); NewtonCompoundCollisionEndAddRemove(xxx0); NewtonCollision* xxx1 = NewtonCreateCompoundCollision(scene->GetNewton(), 0); NewtonCollision* xxxx1 = NewtonCreateBox(scene->GetNewton(), 1.0f, 1.0f, 1.0f, 0, &L1[0][0]); NewtonCompoundCollisionAddSubCollision(xxx1, xxxx1); NewtonCompoundCollisionEndAddRemove(xxx1); NewtonCollisionSetScale(xxx1, 1.0f, 2.0f, 1.0f); //dMatrix m (dPitchMatrix(45.0f * 3.141692f / 180.0f) * dYawMatrix(40.0f * 3.141692f / 180.0f) * dRollMatrix(70.0f * 3.141692f / 180.0f)); dMatrix m (dPitchMatrix(0.0f * 3.141692f / 180.0f) * dYawMatrix(0.0f * 3.141692f / 180.0f) * dRollMatrix(0.0f * 3.141692f / 180.0f)); dVector gravity (0.0f, 0.0f, -9.8f, 0.0f); dVector cog0 (0.0f, 0.0f, 0.0f, 0.0f); dVector accelPerUnitMass0; dVector torquePerUnitMass0; NewtonConvexCollisionCalculateBuoyancyAcceleration (xxx0, &m[0][0], &cog0[0], &gravity[0], &plane[0], 1.0f, 0.1f, &accelPerUnitMass0[0], &torquePerUnitMass0[0]); dVector cog1 (0.0f, 0.0f, 0.0f, 0.0f); dVector accelPerUnitMass1; dVector torquePerUnitMass1; NewtonConvexCollisionCalculateBuoyancyAcceleration (xxx1, &m[0][0], &cog1[0], &gravity[0], &plane[0], 1.0f, 0.1f, &accelPerUnitMass1[0], &torquePerUnitMass1[0]); */ int count = 5; dVector size (1.0f, 0.25f, 0.5f); dVector location (10.0f, 0.0f, 0.0f, 0.0f); dMatrix shapeOffsetMatrix (dGetIdentityMatrix()); // AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); // AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); // AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); // AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); // AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); // AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); // AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _COMPOUND_CONVEX_CRUZ_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); /* for (NewtonBody* bodyPtr = NewtonWorldGetFirstBody(scene->GetNewton()); bodyPtr; bodyPtr = NewtonWorldGetNextBody(scene->GetNewton(), bodyPtr)) { NewtonCollision* collision = NewtonBodyGetCollision(bodyPtr); if (NewtonCollisionGetType(collision) == SERIALIZE_ID_COMPOUND) { NewtonCollisionSetScale (collision, 0.5f, 0.5f, 0.5f); } } */ // AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); }