/// <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();
        }
Beispiel #3
0
        /// <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));
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        /// <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;
        }
Beispiel #7
0
        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;
        }
Beispiel #9
0
		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;
 }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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;
        }