/// <summary> /// You can put a scale (-1) operation in the global pose, it works! (not for convex meshes though!) /// NOTE: WARNING: scaling not supported!!! (still not supported, it has been delayed for several reasons) /// </summary> /// <param name="data"></param> /// <param name="scene"></param> /// <param name="globalPose"></param> /// <returns></returns> private ActorDescription createActorDesc(MeshCollisionData data, StillDesign.PhysX.Scene scene, Matrix globalPose) { // From PhysX SDK: //There are some performance implications of compound shapes that the user should be aware of: //You should avoid static actors being compounds; there's a limit to the number of triangles allowed in one actor's mesh shapes and subshapes exceeding the limit will be ignored. //TODO: is this about triangle meshes only? EDIT: i dont think so // Pull scaling out of the transformation Vector3 scale, translation; Quaternion rotation; globalPose.Decompose(out scale, out rotation, out translation); //globalPose = Matrix.CreateFromQuaternion(rotation) * Matrix.CreateTranslation(translation); var scaleMat = Matrix.Identity;// Matrix.CreateScale(scale); ActorDescription actorDesc = new ActorDescription(); for (int i = 0; i < data.Boxes.Count; i++) { var box = data.Boxes[i]; var shape = new BoxShapeDescription(box.Dimensions); shape.LocalPose = box.Orientation * scaleMat; actorDesc.Shapes.Add(shape); } for (int i = 0; i < data.ConvexMeshes.Count; i++) { var convex = data.ConvexMeshes[i]; var shape = new ConvexShapeDescription(); shape.ConvexMesh = MeshPhysicsPool.CreateConvexMesh(scene, convex); shape.Flags = ShapeFlag.Visualization; actorDesc.Shapes.Add(shape); } if (data.TriangleMesh != null) { TriangleMesh triangleMesh; triangleMesh = MeshPhysicsPool.CreateTriangleMesh(scene, data.TriangleMesh); TriangleMeshShapeDescription shapeDesc = new TriangleMeshShapeDescription(); shapeDesc.TriangleMesh = triangleMesh; shapeDesc.Flags = ShapeFlag.Visualization; // Vizualization enabled, obviously (not obviously enabled, obvious that this enables visualization) actorDesc.Shapes.Add(shapeDesc); } actorDesc.GlobalPose = globalPose; return(actorDesc); }
public void TestTriangleMesh() { XNAGame game = new XNAGame(); game.SpectaterCamera.CameraPosition = new Vector3(0, 0, -40); PhysicsEngine engine = new PhysicsEngine(); //game.AddXNAObject(engine); game.InitializeEvent += delegate { engine.Initialize(); PhysicsDebugRendererXNA debugRenderer = new PhysicsDebugRendererXNA(game, engine.Scene); game.AddXNAObject(debugRenderer); TangentVertex[] vertices; short[] indices; BoxMesh.CreateUnitBoxVerticesAndIndices(out vertices, out indices); var positions = new Vector3[vertices.Length]; for (int i = 0; i < positions.Length; i++) { positions[i] = vertices[i].pos; } int[] intIndices = new int[indices.Length]; for (int i = 0; i < intIndices.Length; i++) { intIndices[i] = indices[i]; } var triangleMesh = CreateTriangleMesh(positions, intIndices, engine.Scene); var triangleMeshShapeDesc = new TriangleMeshShapeDescription(); triangleMeshShapeDesc.TriangleMesh = triangleMesh; var actorDesc = new ActorDescription(triangleMeshShapeDesc); var actor = engine.Scene.CreateActor(actorDesc); }; game.UpdateEvent += delegate { engine.Update(game.Elapsed); }; game.Run(); engine.Dispose(); }
/// <summary> /// Initializes a new instance of the <see cref="PhysxTriangleMesh"/> class. /// For cooked Models /// </summary> /// <param name="PhysxPhysicWorld">The physx physic world.</param> /// <param name="FileStream">The file stream.</param> /// <param name="localTransformation">The local transformation.</param> /// <param name="worldTransformation">The world transformation.</param> /// <param name="scale">The scale.</param> /// <param name="MaterialDescription">The material description.</param> public PhysxTriangleMesh(PhysxPhysicWorld PhysxPhysicWorld, FileStream FileStream, Microsoft.Xna.Framework.Matrix localTransformation, Microsoft.Xna.Framework.Matrix worldTransformation, Microsoft.Xna.Framework.Vector3 scale, MaterialDescription MaterialDescription) { TriangleMesh triangleMesh = PhysxPhysicWorld.Core.CreateTriangleMesh(FileStream); TriangleMeshShapeDescription bunnyShapeDesc = new TriangleMeshShapeDescription(); bunnyShapeDesc.TriangleMesh = triangleMesh; BodyDescription bodyDesc = new BodyDescription(); ActorDesc.Shapes.Add(bunnyShapeDesc); ActorDesc.BodyDescription = bodyDesc; this.Scale = scale; }
//public static void drawSphere(SphereShape sphereShape, Vector3 color) //{ // // Draw the Box // { // Camera _camera = CamerasManager.Instance.GetActiveCamera(); // var _sphere = ResourceManager.Instance.Get<Model>("Sphere"); // var transforms = new Matrix[_sphere.Bones.Count]; // _sphere.CopyAbsoluteBoneTransformsTo(transforms); // foreach (ModelMesh mesh in _sphere.Meshes) // { // foreach (BasicEffect effect in mesh.Effects) // { // effect.DiffuseColor = color; // effect.EnableDefaultLighting(); // effect.World = Matrix.CreateScale(sphereShape.Radius, sphereShape.Radius, sphereShape.Radius)* // transforms[mesh.ParentBone.Index]*sphereShape.GlobalPose; // effect.View = _camera.View; // effect.Projection = _camera.Projection; // } // mesh.Draw(); // } // } //} //private static void DrawBox(BoxShape shape, Vector3 color) //{ // // Draw the Box // { // Camera _camera = CamerasManager.Instance.GetActiveCamera(); // var _box = ResourceManager.Instance.Get<Model>("Cube"); // var transforms = new Matrix[_box.Bones.Count]; // _box.CopyAbsoluteBoneTransformsTo(transforms); // foreach (ModelMesh mesh in _box.Meshes) // { // foreach (BasicEffect effect in mesh.Effects) // { // effect.DiffuseColor = color; // effect.EnableDefaultLighting(); // effect.World = Matrix.CreateScale(shape.Dimensions.X, shape.Dimensions.Y, shape.Dimensions.Z)* // transforms[mesh.ParentBone.Index]*shape.GlobalPose; // effect.View = _camera.View; // effect.Projection = _camera.Projection; // } // mesh.Draw(); // } // } //} //private static void DrawCapsule(CapsuleShape shape, Vector3 color) //{ // { // Camera _camera = CamerasManager.Instance.GetActiveCamera(); // var _capsule = ResourceManager.Instance.Get<Model>("Capsule"); // var transforms = new Matrix[_capsule.Bones.Count]; // _capsule.CopyAbsoluteBoneTransformsTo(transforms); // foreach (ModelMesh mesh in _capsule.Meshes) // { // foreach (BasicEffect effect in mesh.Effects) // { // effect.DiffuseColor = color; // effect.EnableDefaultLighting(); // effect.World = Matrix.CreateScale(shape.Radius, shape.Height, shape.Radius)* // transforms[mesh.ParentBone.Index]*shape.GlobalPose; // effect.View = _camera.View; // effect.Projection = _camera.Projection; // } // mesh.Draw(); // } // } //} //private static void DrawPlane(PlaneShape shape) //{ // { // Camera _camera = CamerasManager.Instance.GetActiveCamera(); // var _plane = ResourceManager.Instance.Get<Model>("Plane"); // var transforms = new Matrix[_plane.Bones.Count]; // _plane.CopyAbsoluteBoneTransformsTo(transforms); // foreach (ModelMesh mesh in _plane.Meshes) // { // foreach (BasicEffect effect in mesh.Effects) // { // effect.EnableDefaultLighting(); // effect.World = Matrix.CreateScale(10240.0f, 1.0f, 10240.0f)*transforms[mesh.ParentBone.Index]* // shape.GlobalPose; // effect.View = _camera.View; // effect.Projection = _camera.Projection; // } // mesh.Draw(); // } // } //} public static Actor RetrievePhysicsTriggerFromModel(Model model, Vector3 position, float orientation) { var actorDesc = new ActorDescription(); foreach (ModelMesh mesh in model.Meshes) { TriangleMeshShapeDescription shape = RetrievePhysicsTriangleMeshFromMesh(mesh, model.Root.Transform * mesh.ParentBone.Transform, true); shape.Flags |= ShapeFlag.TriggerOnLeave; actorDesc.Shapes.Add(shape); } //actorDesc.Flags = 0; actorDesc.GlobalPose = Matrix.CreateRotationY(orientation) * Matrix.CreateTranslation(position); //actorDesc.GlobalPose = modelSceneNode.Model.Root.Transform; return(PhysX.Instance.Scene.CreateActor(actorDesc)); }
/// <summary> /// Here is where the magic happens! It loads the physX file and get from it the triangle mesh. /// </summary> /// <param name="stream"></param> /// <param name="transforms"></param> /// <returns></returns> public static TriangleMeshShapeDescription GetPxMeshFromFile(string stream, Matrix transforms) { var fs = File.OpenRead(stream); TriangleMesh pMesh = PhysX.Instance.Core.CreateTriangleMesh(fs); fs.Close(); File.Delete(stream); // Create TriangleMesh above code segment. pMesh.SaveToDescription(); var tmsd = new TriangleMeshShapeDescription(); tmsd.TriangleMesh = pMesh; tmsd.LocalPose = transforms; tmsd.MeshPagingMode = MeshPagingMode.Auto; return(tmsd); }
/// <summary> /// Initializes a new instance of the <see cref="PhysxTriangleMesh"/> class. /// Cooks the Model on the fly /// </summary> /// <param name="PhysxPhysicWorld">The physx physic world.</param> /// <param name="model">The model.</param> /// <param name="worldTransformation">The world transformation.</param> /// <param name="scale">The scale.</param> /// <param name="density">The density.</param> /// <param name="material">The material.</param> public PhysxTriangleMesh(PhysxPhysicWorld PhysxPhysicWorld, IModelo model, Microsoft.Xna.Framework.Matrix worldTransformation, Microsoft.Xna.Framework.Vector3 scale, float density = 1, StillDesign.PhysX.Material material = null) { Microsoft.Xna.Framework.Vector3[] vertices = null; int[] indices = null; ExtractData(ref vertices, ref indices, model); TriangleMeshDescription meshDesc = new TriangleMeshDescription(); meshDesc.AllocateVertices <Microsoft.Xna.Framework.Vector3>(vertices.Count()); meshDesc.VerticesStream.SetData <Microsoft.Xna.Framework.Vector3>(vertices); meshDesc.AllocateTriangles <int>(indices.Count()); meshDesc.TriangleStream.SetData <int>(indices); meshDesc.Flags = 0; meshDesc.VertexCount = vertices.Count(); meshDesc.TriangleCount = indices.Count(); MemoryStream ms = new MemoryStream(); Cooking.InitializeCooking(); if (Cooking.CookTriangleMesh(meshDesc, ms) == false) { PloobsEngine.Engine.Logger.ActiveLogger.LogMessage("Cant Cook Model", Engine.Logger.LogLevel.FatalError); } Cooking.CloseCooking(); ms.Position = 0; TriangleMesh triangleMesh = PhysxPhysicWorld.Core.CreateTriangleMesh(ms); TriangleMeshShapeDescription bunnyShapeDesc = new TriangleMeshShapeDescription(); if (material != null) { bunnyShapeDesc.Material = material; } bunnyShapeDesc.TriangleMesh = triangleMesh; ActorDesc = new ActorDescription(); ActorDesc.Shapes.Add(bunnyShapeDesc); ActorDesc.BodyDescription = null; ActorDesc.GlobalPose = worldTransformation.AsPhysX(); this.Scale = scale; }
public TriangleMeshShapeDescription CreateTriangleMeshShape(Core core) { var triangleMeshDesc = new TriangleMeshDescription() { VertexCount = this.Vertices.Length, TriangleCount = this.Indices.Length }; triangleMeshDesc.AllocateVertices<Vector3>(this.Vertices.Length); triangleMeshDesc.AllocateTriangles<uint>(this.Indices.Length); foreach (Vector3 vec in this.Vertices) triangleMeshDesc.VerticesStream.Write(vec); triangleMeshDesc.Flags = 0; foreach (int ui in this.Indices) triangleMeshDesc.TriangleStream.Write<int>(ui); // Two ways on cooking mesh: 1. Saved in memory, 2. Saved in file // Cooking from memory MemoryStream stream = new MemoryStream(); Cooking.InitializeCooking(new ConsoleOutputStream()); Cooking.CookTriangleMesh(triangleMeshDesc, stream); Cooking.CloseCooking(); stream.Position = 0; TriangleMesh pMesh = core.CreateTriangleMesh(stream); // Create TriangleMesh above code segment. pMesh.SaveToDescription(); TriangleMeshShapeDescription tmsd = new TriangleMeshShapeDescription(); tmsd.TriangleMesh = pMesh; return tmsd; }
/// <summary> /// Initializes a new instance of the <see cref="PhysxTriangleMesh"/> class. /// Cooks the Model on the fly /// </summary> /// <param name="PhysxPhysicWorld">The physx physic world.</param> /// <param name="model">The model.</param> /// <param name="worldTransformation">The world transformation.</param> /// <param name="scale">The scale.</param> /// <param name="density">The density.</param> /// <param name="material">The material.</param> public PhysxTriangleMesh(PhysxPhysicWorld PhysxPhysicWorld, IModelo model, Microsoft.Xna.Framework.Matrix worldTransformation, Microsoft.Xna.Framework.Vector3 scale, float density = 1,StillDesign.PhysX.Material material = null) { Microsoft.Xna.Framework.Vector3[] vertices = null; int[] indices = null; ExtractData(ref vertices, ref indices, model); TriangleMeshDescription meshDesc = new TriangleMeshDescription(); meshDesc.AllocateVertices<Microsoft.Xna.Framework.Vector3>(vertices.Count()); meshDesc.VerticesStream.SetData<Microsoft.Xna.Framework.Vector3>(vertices); meshDesc.AllocateTriangles<int>(indices.Count()); meshDesc.TriangleStream.SetData<int>(indices); meshDesc.Flags = 0; meshDesc.VertexCount = vertices.Count(); meshDesc.TriangleCount = indices.Count(); MemoryStream ms = new MemoryStream(); Cooking.InitializeCooking(); if (Cooking.CookTriangleMesh(meshDesc, ms) == false) { PloobsEngine.Engine.Logger.ActiveLogger.LogMessage("Cant Cook Model",Engine.Logger.LogLevel.FatalError); } Cooking.CloseCooking(); ms.Position = 0; TriangleMesh triangleMesh = PhysxPhysicWorld.Core.CreateTriangleMesh(ms); TriangleMeshShapeDescription bunnyShapeDesc = new TriangleMeshShapeDescription(); if (material != null) bunnyShapeDesc.Material = material; bunnyShapeDesc.TriangleMesh = triangleMesh; ActorDesc = new ActorDescription(); ActorDesc.Shapes.Add(bunnyShapeDesc); ActorDesc.BodyDescription= null; ActorDesc.GlobalPose = worldTransformation.AsPhysX(); this.Scale = scale; }
protected override void LoadPhysics(Scene scene) { CCDSkeleton ccdSkeletonForBox; // Create a CCD Skeleton { Vector3 size = new Vector3(5, 5, 5); int[] indices = { 0, 1, 3, 0, 3, 2, 3, 7, 6, 3, 6, 2, 1, 5, 7, 1, 7, 3, 4, 6, 7, 4, 7, 5, 1, 0, 4, 5, 1, 4, 4, 0, 2, 4, 2, 6 }; Vector3[] vertices = { new Vector3( size.X, -size.Y, -size.Z ), new Vector3( size.X, -size.Y, size.Z ), new Vector3( size.X, size.Y, -size.Z ), new Vector3( size.X, size.Y, size.Z ), new Vector3( -size.X, -size.Y, -size.Z ), new Vector3( -size.X, -size.Y, size.Z ), new Vector3( -size.X, size.Y, -size.Z ), new Vector3( -size.X, size.Y, size.Z ) }; TriangleMeshDescription triangleMeshDesc = new TriangleMeshDescription(); triangleMeshDesc.AllocateVertices<Vector3>(vertices.Length); triangleMeshDesc.AllocateTriangles<int>(indices.Length); triangleMeshDesc.VerticesStream.SetData(vertices); triangleMeshDesc.TriangleStream.SetData(indices); triangleMeshDesc.VertexCount = vertices.Length; triangleMeshDesc.TriangleCount = indices.Length / 3; ccdSkeletonForBox = scene.Core.CreateCCDSkeleton(triangleMeshDesc); // Enable CCD and CCD Visualization scene.Core.SetParameter(PhysicsParameter.ContinuousCollisionDetection, true); scene.Core.SetParameter(PhysicsParameter.VisualizeContinuousCollisionDetectionTests, true); } // Create a large 2 polygon triangle mesh plane // For CCD to work/be used many conditions must be met (check the docs for full list) // One of those conditions is that one of the objects must be a triangle mesh or a convex mesh (for static-dynamic) { Vector3[] vertices = { new Vector3( -100, 5, -100 ), new Vector3( -100, 5, 100 ), new Vector3( 100, 5, -100 ), new Vector3( 100, 5, 100 ), }; int[] indices = { 0, 1, 2, 1, 3, 2 }; TriangleMeshDescription triangleMeshDesc = new TriangleMeshDescription(); triangleMeshDesc.TriangleCount = indices.Length / 3; triangleMeshDesc.VertexCount = vertices.Length; triangleMeshDesc.AllocateTriangles<int>(triangleMeshDesc.TriangleCount); triangleMeshDesc.AllocateVertices<Vector3>(triangleMeshDesc.VertexCount); triangleMeshDesc.TriangleStream.SetData(indices); triangleMeshDesc.VerticesStream.SetData(vertices); TriangleMesh triangleMesh; using (MemoryStream s = new MemoryStream()) { Cooking.InitializeCooking(); Cooking.CookTriangleMesh(triangleMeshDesc, s); Cooking.CloseCooking(); s.Position = 0; triangleMesh = scene.Core.CreateTriangleMesh(s); } TriangleMeshShapeDescription triangleMeshShapeDesc = new TriangleMeshShapeDescription() { TriangleMesh = triangleMesh, Flags = ShapeFlag.Visualization }; ActorDescription actorDesc = new ActorDescription() { Shapes = { triangleMeshShapeDesc } }; Actor actor = scene.CreateActor(actorDesc); } // Make 20 boxes fall down for (int x = 0; x < 20; x++) { BoxShapeDescription boxShapeDesc = new BoxShapeDescription(2, 3, 8); // Assign the CCD Skeleton to the shape boxShapeDesc.CCDSkeleton = ccdSkeletonForBox; ActorDescription actorDesc = new ActorDescription() { Name = String.Format("Box {0}", x), BodyDescription = new BodyDescription(10.0f), GlobalPose = Matrix.Translation(0, 15 + 3 * x, 0), Shapes = { boxShapeDesc } }; Actor actor = scene.CreateActor(actorDesc); } }
protected override void LoadContent() { CCDSkeleton ccdSkeletonForBox; // Create a CCD Skeleton { Vector3 size = new Vector3(5, 5, 5); int[] indices = { 0, 1, 3, 0, 3, 2, 3, 7, 6, 3, 6, 2, 1, 5, 7, 1, 7, 3, 4, 6, 7, 4, 7, 5, 1, 0, 4, 5, 1, 4, 4, 0, 2, 4, 2, 6 }; Vector3[] vertices = { new Vector3(size.X, -size.Y, -size.Z), new Vector3(size.X, -size.Y, size.Z), new Vector3(size.X, size.Y, -size.Z), new Vector3(size.X, size.Y, size.Z), new Vector3(-size.X, -size.Y, -size.Z), new Vector3(-size.X, -size.Y, size.Z), new Vector3(-size.X, size.Y, -size.Z), new Vector3(-size.X, size.Y, size.Z) }; TriangleMeshDescription triangleMeshDesc = new TriangleMeshDescription(); triangleMeshDesc.AllocateVertices <Vector3>(vertices.Length); triangleMeshDesc.AllocateTriangles <int>(indices.Length); triangleMeshDesc.VerticesStream.SetData(vertices); triangleMeshDesc.TriangleStream.SetData(indices); triangleMeshDesc.VertexCount = vertices.Length; triangleMeshDesc.TriangleCount = indices.Length / 3; ccdSkeletonForBox = _core.CreateCCDSkeleton(triangleMeshDesc); // Enable CCD and CCD Visualization _core.SetParameter(PhysicsParameter.ContinuousCollisionDetection, true); _core.SetParameter(PhysicsParameter.VisualizeContinuousCollisionDetectionTests, true); } // Create a large 2 polygon triangle mesh plane // For CCD to work/be used many conditions must be met (check the docs for full list) // One of those conditions is that one of the objects must be a triangle mesh or a convex mesh (for static-dynamic) { Vector3[] vertices = { new Vector3(-100, 5, -100), new Vector3(-100, 5, 100), new Vector3(100, 5, -100), new Vector3(100, 5, 100), }; int[] indices = { 0, 1, 2, 1, 3, 2 }; TriangleMeshDescription triangleMeshDesc = new TriangleMeshDescription(); triangleMeshDesc.TriangleCount = indices.Length / 3; triangleMeshDesc.VertexCount = vertices.Length; triangleMeshDesc.AllocateTriangles <int>(triangleMeshDesc.TriangleCount); triangleMeshDesc.AllocateVertices <Vector3>(triangleMeshDesc.VertexCount); triangleMeshDesc.TriangleStream.SetData(indices); triangleMeshDesc.VerticesStream.SetData(vertices); MemoryStream s = new MemoryStream(); Cooking.InitializeCooking(); Cooking.CookTriangleMesh(triangleMeshDesc, s); Cooking.CloseCooking(); s.Position = 0; TriangleMesh triangleMesh = _core.CreateTriangleMesh(s); TriangleMeshShapeDescription triangleMeshShapeDesc = new TriangleMeshShapeDescription() { TriangleMesh = triangleMesh, Flags = ShapeFlag.Visualization }; ActorDescription actorDesc = new ActorDescription() { Shapes = { triangleMeshShapeDesc } }; Actor actor = _scene.CreateActor(actorDesc); } // Make 20 boxes fall down for (int x = 0; x < 20; x++) { BoxShapeDescription boxShapeDesc = new BoxShapeDescription(2, 3, 8); // Assign the CCD Skeleton to the shape boxShapeDesc.CCDSkeleton = ccdSkeletonForBox; ActorDescription actorDesc = new ActorDescription() { Name = String.Format("Box {0}", x), BodyDescription = new BodyDescription(10.0f), GlobalPose = Matrix.CreateTranslation(0, 15 + 3 * x, 0), Shapes = { boxShapeDesc } }; Actor actor = _scene.CreateActor(actorDesc); } }
public static TriangleMeshShapeDescription RetrievePhysicsTriangleMeshFromMesh(ModelMesh mesh, Matrix transforms, bool flipNormals) { Vector3[] vertices; VertexPositionNormalTexture[] meshVerts; var triangleMeshDesc = new TriangleMeshDescription(); triangleMeshDesc.TriangleCount = mesh.MeshParts[0].PrimitiveCount; triangleMeshDesc.AllocateTriangles <int>(mesh.MeshParts[0].PrimitiveCount); meshVerts = new VertexPositionNormalTexture[mesh.MeshParts[0].NumVertices]; if (mesh.IndexBuffer.IndexElementSize == IndexElementSize.SixteenBits) { var indices = new short[mesh.IndexBuffer.SizeInBytes / 2]; mesh.IndexBuffer.GetData(indices); foreach (int ui in indices) { triangleMeshDesc.TriangleStream.Write(ui); } } else { var indices = new int[mesh.IndexBuffer.SizeInBytes / 4]; mesh.IndexBuffer.GetData(indices); foreach (int ui in indices) { triangleMeshDesc.TriangleStream.Write(ui); } } mesh.VertexBuffer.GetData(meshVerts); vertices = new Vector3[mesh.MeshParts[0].NumVertices]; for (int i = 0; i < meshVerts.Length; i++) { vertices[i] = meshVerts[i].Position; } triangleMeshDesc.VertexCount = vertices.Length; triangleMeshDesc.AllocateVertices <Vector3>(vertices.Length); foreach (Vector3 vec in vertices) { triangleMeshDesc.VerticesStream.Write(vec); } if (flipNormals) { triangleMeshDesc.Flags = MeshFlag.FlipNormals; } var stream = new MemoryStream(); Cooking.InitializeCooking(new ConsoleOutputStream()); Cooking.CookTriangleMesh(triangleMeshDesc, stream); Cooking.CloseCooking(); stream.Position = 0; TriangleMesh pMesh = PhysX.Instance.Core.CreateTriangleMesh(stream); // Create TriangleMesh above code segment. pMesh.SaveToDescription(); var tmsd = new TriangleMeshShapeDescription(); tmsd.TriangleMesh = pMesh; tmsd.LocalPose = transforms; tmsd.MeshPagingMode = MeshPagingMode.Auto; return(tmsd); }
public void TestObjImportPhysics() { XNAGame game = new XNAGame(); game.SpectaterCamera.CameraPosition = new Vector3(0, 0, -40); game.SpectaterCamera.FarClip = 10000; PhysicsEngine engine = new PhysicsEngine(); //game.AddXNAObject(engine); game.InitializeEvent += delegate { engine.Initialize(); PhysicsDebugRendererXNA debugRenderer = new PhysicsDebugRendererXNA(game, engine.Scene); game.AddXNAObject(debugRenderer); ObjImporter importer = new ObjImporter(); //importer.ImportObjFile(EmbeddedFile.GetStream(typeof(ObjImporter).Assembly, "MHGameWork.TheWizards.OBJParser.Files.Crate.obj", "Crate.obj")); importer.ImportObjFile(TestFiles.MerchantsHouseObj); List <Vector3> positions = importer.Vertices; Vector3[] transformedPositions = new Vector3[positions.Count]; Matrix objectMatrix = Matrix.CreateScale(5); Matrix transform = objectMatrix; Vector3.Transform(positions.ToArray(), ref transform, transformedPositions); var indices = new List <int>(); for (int i = 0; i < importer.Groups.Count; i++) { for (int j = 0; j < importer.Groups[i].SubObjects.Count; j++) { for (int k = 0; k < importer.Groups[i].SubObjects[j].Faces.Count; k++) { indices.Add(importer.Groups[i].SubObjects[j].Faces[k].V1.Position); indices.Add(importer.Groups[i].SubObjects[j].Faces[k].V2.Position); indices.Add(importer.Groups[i].SubObjects[j].Faces[k].V3.Position); } } } var triangleMesh = CreateTriangleMesh(transformedPositions, indices.ToArray(), engine.Scene); var triangleMeshShapeDesc = new TriangleMeshShapeDescription(); triangleMeshShapeDesc.TriangleMesh = triangleMesh; var actorDesc = new ActorDescription(triangleMeshShapeDesc); var actor = engine.Scene.CreateActor(actorDesc); }; game.UpdateEvent += delegate { if (game.Keyboard.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.F)) { Actor actor = PhysicsHelper.CreateDynamicSphereActor(engine.Scene, 1, 1); actor.GlobalPosition = game.SpectaterCamera.CameraPosition + game.SpectaterCamera.CameraDirection * 5; actor.LinearVelocity = game.SpectaterCamera.CameraDirection * 5; } engine.Update(game.Elapsed); }; game.Run(); engine.Dispose(); }
/// <summary> /// Initializes a new instance of the <see cref="PhysxTriangleMesh"/> class. /// For cooked Models /// </summary> /// <param name="PhysxPhysicWorld">The physx physic world.</param> /// <param name="FileStream">The file stream.</param> /// <param name="localTransformation">The local transformation.</param> /// <param name="worldTransformation">The world transformation.</param> /// <param name="scale">The scale.</param> /// <param name="MaterialDescription">The material description.</param> public PhysxTriangleMesh(PhysxPhysicWorld PhysxPhysicWorld, FileStream FileStream, Microsoft.Xna.Framework.Matrix localTransformation, Microsoft.Xna.Framework.Matrix worldTransformation, Microsoft.Xna.Framework.Vector3 scale, MaterialDescription MaterialDescription) { TriangleMesh triangleMesh = PhysxPhysicWorld.Core.CreateTriangleMesh(FileStream); TriangleMeshShapeDescription bunnyShapeDesc = new TriangleMeshShapeDescription(); bunnyShapeDesc.TriangleMesh = triangleMesh; BodyDescription bodyDesc = new BodyDescription(); ActorDesc.Shapes.Add(bunnyShapeDesc); ActorDesc.BodyDescription = bodyDesc; this.Scale = scale; }
public static Actor GenerateTrackActor(RaceFile file, CActorHierarchy actors, out List <NonCar> nonCarInstances) { List <Vector3> verts = new List <Vector3>(); List <ushort> indices = new List <ushort>(); List <ushort> materialIndices = new List <ushort>(); List <OpenC1.CActor> actorsList = actors.All(); nonCarInstances = new List <NonCar>(); for (int i = 0; i < actorsList.Count; i++) { CActor actor = actorsList[i]; if (actor.Model == null) { continue; } if (actor.Name.StartsWith("&")) { if (Char.IsDigit(actor.Name[1]) && Char.IsDigit(actor.Name[2])) { NonCar nc = GenerateNonCar(actor, file.NonCars); if (nc != null) { nonCarInstances.Add(nc); continue; //dont-merge with track } } } int baseIndex = verts.Count; for (int j = 0; j < actor.Model.VertexCount; j++) { verts.Add(Vector3.Zero); } foreach (Polygon poly in actor.Model.Polygons) { if (poly.MaterialIndex < 0) { continue; } string materialName = actor.Model.MaterialNames == null ? "none" : actor.Model.MaterialNames[poly.MaterialIndex]; //this is a non-solid material if (materialName.StartsWith("!")) { continue; } int index = baseIndex + poly.Vertex1; indices.Add((ushort)index); if (verts[index] == Vector3.Zero) { Vector3 transformedVec = Vector3.Transform(actors.Models._vertexPositions[actor.Model.VertexBaseIndex + poly.Vertex1], actor.Matrix); verts[index] = transformedVec; } index = baseIndex + poly.Vertex2; indices.Add((ushort)index); if (verts[index] == Vector3.Zero) { Vector3 transformedVec = Vector3.Transform(actors.Models._vertexPositions[actor.Model.VertexBaseIndex + poly.Vertex2], actor.Matrix); verts[index] = transformedVec; } index = baseIndex + poly.Vertex3; indices.Add((ushort)index); if (verts[index] == Vector3.Zero) { Vector3 transformedVec = Vector3.Transform(actors.Models._vertexPositions[actor.Model.VertexBaseIndex + poly.Vertex3], actor.Matrix); verts[index] = transformedVec; } if (Char.IsDigit(materialName[0])) { ushort matModiferId = (ushort)(ushort.Parse(materialName.Substring(0, 1)) + 1); if (matModiferId >= file.MaterialModifiers.Count) { matModiferId = 0; } materialIndices.Add(matModiferId); } else { materialIndices.Add(0); } } } TriangleMeshDescription meshDesc = new TriangleMeshDescription(); meshDesc.TriangleCount = indices.Count / 3; meshDesc.VertexCount = verts.Count; meshDesc.AllocateVertices <Vector3>(meshDesc.VertexCount); meshDesc.AllocateTriangles <ushort>(meshDesc.TriangleCount); meshDesc.AllocateMaterialIndices <ushort>(materialIndices.Count); meshDesc.TriangleStream.SetData(indices.ToArray()); meshDesc.VerticesStream.SetData(verts.ToArray()); meshDesc.MaterialIndicesStream.SetData(materialIndices.ToArray()); meshDesc.Flags = MeshFlag.Indices16Bit; MemoryStream s = new MemoryStream(); Cooking.InitializeCooking(); Cooking.CookTriangleMesh(meshDesc, s); Cooking.CloseCooking(); s.Position = 0; TriangleMesh triangleMesh = PhysX.Instance.Core.CreateTriangleMesh(s); TriangleMeshShapeDescription shape = new TriangleMeshShapeDescription() { TriangleMesh = triangleMesh, }; ActorDescription actorDescription = new ActorDescription() { GlobalPose = Matrix.CreateTranslation(0, 0, 0), Shapes = { shape } }; foreach (Checkpoint checkpoint in file.Checkpoints) { ActorDescription actorDesc = new ActorDescription(); BoxShapeDescription box = new BoxShapeDescription(checkpoint.BBox.GetSize()); box.Flags = ShapeFlag.TriggerOnEnter | ShapeFlag.Visualization; actorDesc.Shapes.Add(box); Actor actor = PhysX.Instance.Scene.CreateActor(actorDesc); actor.GlobalPosition = checkpoint.BBox.GetCenter(); actor.UserData = checkpoint; } StillDesign.PhysX.Actor environment = PhysX.Instance.Scene.CreateActor(actorDescription); environment.Group = PhysXConsts.TrackId; environment.Shapes[0].SetFlag(ShapeFlag.Visualization, false); CreateDefaultWaterSpecVols(file, actorsList, actors.Models); for (int i = 1; i < file.SpecialVolumes.Count; i++) { SpecialVolume vol = file.SpecialVolumes[i]; Vector3 scale = new Vector3(); Vector3 trans = new Vector3(); Quaternion q = new Quaternion(); Matrix matrix = vol.Matrix; bool success = matrix.Decompose(out scale, out q, out trans); if (scale.Z == 0) { scale.Z = 0.1f; } ActorDescription actorDesc = new ActorDescription(); BoxShapeDescription box = new BoxShapeDescription(scale); if (success) { if (float.IsNaN(q.X)) { continue; } box.LocalRotation = Matrix.CreateFromQuaternion(q); } else { //if the matrix cannot be decomposed, like part of the long tunnel in coasta... // get the rotation by calculating some points and working out rotation from them Vector3 v1 = Vector3.Transform(new Vector3(-1, -1, 1), matrix); Vector3 v2 = Vector3.Transform(new Vector3(-1, 1, -1), matrix); Vector3 forwards = v2 - v1; forwards.Normalize(); box.LocalRotation = Matrix.CreateWorld(Vector3.Zero, forwards, Vector3.Up); } box.Flags = ShapeFlag.TriggerOnEnter | ShapeFlag.TriggerOnLeave | ShapeFlag.Visualization; actorDesc.Shapes.Add(box); Actor actor = PhysX.Instance.Scene.CreateActor(actorDesc); actor.GlobalPosition = vol.Matrix.Translation; actor.UserData = vol; } return(environment); }
public static Actor GenerateTrackActor(RaceFile file, CActorHierarchy actors, out List<NonCar> nonCarInstances) { List<Vector3> verts = new List<Vector3>(); List<ushort> indices = new List<ushort>(); List<ushort> materialIndices = new List<ushort>(); List<OpenC1.CActor> actorsList = actors.All(); nonCarInstances = new List<NonCar>(); for (int i = 0; i < actorsList.Count; i++) { CActor actor = actorsList[i]; if (actor.Model == null) continue; if (actor.Name.StartsWith("&")) { if (Char.IsDigit(actor.Name[1]) && Char.IsDigit(actor.Name[2])) { NonCar nc = GenerateNonCar(actor, file.NonCars); if (nc != null) { nonCarInstances.Add(nc); continue; //dont-merge with track } } } int baseIndex = verts.Count; for (int j = 0; j < actor.Model.VertexCount; j++) verts.Add(Vector3.Zero); foreach (Polygon poly in actor.Model.Polygons) { if (poly.MaterialIndex < 0) continue; string materialName = actor.Model.MaterialNames == null ? "none" : actor.Model.MaterialNames[poly.MaterialIndex]; //this is a non-solid material if (materialName.StartsWith("!")) continue; int index = baseIndex + poly.Vertex1; indices.Add((ushort)index); if (verts[index] == Vector3.Zero) { Vector3 transformedVec = Vector3.Transform(actors.Models._vertexPositions[actor.Model.VertexBaseIndex + poly.Vertex1], actor.Matrix); verts[index] = transformedVec; } index = baseIndex + poly.Vertex2; indices.Add((ushort)index); if (verts[index] == Vector3.Zero) { Vector3 transformedVec = Vector3.Transform(actors.Models._vertexPositions[actor.Model.VertexBaseIndex + poly.Vertex2], actor.Matrix); verts[index] = transformedVec; } index = baseIndex + poly.Vertex3; indices.Add((ushort)index); if (verts[index] == Vector3.Zero) { Vector3 transformedVec = Vector3.Transform(actors.Models._vertexPositions[actor.Model.VertexBaseIndex + poly.Vertex3], actor.Matrix); verts[index] = transformedVec; } if (Char.IsDigit(materialName[0])) { ushort matModiferId = (ushort)(ushort.Parse(materialName.Substring(0, 1)) + 1); if (matModiferId >= file.MaterialModifiers.Count) matModiferId = 0; materialIndices.Add(matModiferId); } else materialIndices.Add(0); } } TriangleMeshDescription meshDesc = new TriangleMeshDescription(); meshDesc.TriangleCount = indices.Count / 3; meshDesc.VertexCount = verts.Count; meshDesc.AllocateVertices<Vector3>(meshDesc.VertexCount); meshDesc.AllocateTriangles<ushort>(meshDesc.TriangleCount); meshDesc.AllocateMaterialIndices<ushort>(materialIndices.Count); meshDesc.TriangleStream.SetData(indices.ToArray()); meshDesc.VerticesStream.SetData(verts.ToArray()); meshDesc.MaterialIndicesStream.SetData(materialIndices.ToArray()); meshDesc.Flags = MeshFlag.Indices16Bit; MemoryStream s = new MemoryStream(); Cooking.InitializeCooking(); Cooking.CookTriangleMesh(meshDesc, s); Cooking.CloseCooking(); s.Position = 0; TriangleMesh triangleMesh = PhysX.Instance.Core.CreateTriangleMesh(s); TriangleMeshShapeDescription shape = new TriangleMeshShapeDescription() { TriangleMesh = triangleMesh, }; ActorDescription actorDescription = new ActorDescription() { GlobalPose = Matrix.CreateTranslation(0, 0, 0), Shapes = { shape } }; foreach (Checkpoint checkpoint in file.Checkpoints) { ActorDescription actorDesc = new ActorDescription(); BoxShapeDescription box = new BoxShapeDescription(checkpoint.BBox.GetSize()); box.Flags = ShapeFlag.TriggerOnEnter | ShapeFlag.Visualization; actorDesc.Shapes.Add(box); Actor actor = PhysX.Instance.Scene.CreateActor(actorDesc); actor.GlobalPosition = checkpoint.BBox.GetCenter(); actor.UserData = checkpoint; } StillDesign.PhysX.Actor environment = PhysX.Instance.Scene.CreateActor(actorDescription); environment.Group = PhysXConsts.TrackId; environment.Shapes[0].SetFlag(ShapeFlag.Visualization, false); CreateDefaultWaterSpecVols(file, actorsList, actors.Models); for (int i = 1; i < file.SpecialVolumes.Count; i++) { SpecialVolume vol = file.SpecialVolumes[i]; Vector3 scale = new Vector3(); Vector3 trans = new Vector3(); Quaternion q = new Quaternion(); Matrix matrix = vol.Matrix; bool success = matrix.Decompose(out scale, out q, out trans); if (scale.Z == 0) scale.Z = 0.1f; ActorDescription actorDesc = new ActorDescription(); BoxShapeDescription box = new BoxShapeDescription(scale); if (success) { if (float.IsNaN(q.X)) continue; box.LocalRotation = Matrix.CreateFromQuaternion(q); } else { //if the matrix cannot be decomposed, like part of the long tunnel in coasta... // get the rotation by calculating some points and working out rotation from them Vector3 v1 = Vector3.Transform(new Vector3(-1, -1, 1), matrix); Vector3 v2 = Vector3.Transform(new Vector3(-1, 1, -1), matrix); Vector3 forwards = v2 - v1; forwards.Normalize(); box.LocalRotation = Matrix.CreateWorld(Vector3.Zero, forwards, Vector3.Up); } box.Flags = ShapeFlag.TriggerOnEnter | ShapeFlag.TriggerOnLeave | ShapeFlag.Visualization; actorDesc.Shapes.Add(box); Actor actor = PhysX.Instance.Scene.CreateActor(actorDesc); actor.GlobalPosition = vol.Matrix.Translation; actor.UserData = vol; } return environment; }