void Start() { meshes = new MeshBase[5]; meshes[0] = AddGear(); meshes[1] = AddStar(); meshes[2] = AddBox(); meshes[3] = AddPointedCircle(); meshes[4] = AddTriangleMesh(); int verticesCount = 0; foreach (MeshBase mesh in meshes) { verticesCount += mesh.Vertices.Length; mesh.AddHingeJoint(C_JM2D); mesh.SetCollidersEnabled(false); } allVertices = new Vector3[verticesCount]; convexMesh = ConvexMesh.AddConvexMesh(Vector3.zero, GetUpdatedVertices(), convexMaterial, false); //move body back a bit convexMesh.transform.Translate(Vector3.forward * 0.1f); }
public static ConvexShapeDesc CreateConvexHull(this Physics physics, StaticMeshData meshData) { // create descriptor for convex hull ConvexShapeDesc convexMeshShapeDesc = null; ConvexMeshDesc convexMeshDesc = new ConvexMeshDesc(); convexMeshDesc.PinPoints <float>(meshData.Points, 0, sizeof(float) * 3); convexMeshDesc.PinTriangles <uint>(meshData.Indices, 0, sizeof(uint) * 3); convexMeshDesc.VertexCount = (uint)meshData.Vertices.Length; convexMeshDesc.TriangleCount = (uint)meshData.TriangleCount; convexMeshDesc.Flags = ConvexFlags.ComputeConvex; MemoryStream stream = new MemoryStream(1024); CookingInterface.InitCooking(); if (CookingInterface.CookConvexMesh(convexMeshDesc, stream)) { stream.Seek(0, SeekOrigin.Begin); ConvexMesh convexMesh = physics.CreateConvexMesh(stream); convexMeshShapeDesc = new ConvexShapeDesc(convexMesh); CookingInterface.CloseCooking(); } convexMeshDesc.UnpinAll(); return(convexMeshShapeDesc); }
private MeshBase GetChoosenMesh(MeshCreator meshCreator) { switch (meshCreator.meshType) { case MeshCreator.MeshType.Triangle: return(TriangleMesh.AddTriangle(meshCreator.transform.position, meshCreator.triangleVertex1, meshCreator.triangleVertex2, meshCreator.triangleVertex3, Space.World, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Rectangle: return(RectangleMesh.AddRectangle(meshCreator.transform.position, meshCreator.boxSize, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Circle: return(CircleMesh.AddCircle(meshCreator.transform.position, meshCreator.circleRadius, meshCreator.circleSides, meshCreator.circleUseCircleCollider, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Quadrangle: Vector2[] verts = new Vector2[4] { meshCreator.quadrangleVertex1, meshCreator.quadrangleVertex2, meshCreator.quadrangleVertex3, meshCreator.quadrangleVertex4 }; return(QuadrangleMesh.AddQuadrangle(meshCreator.transform.position, verts, Space.World, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Ellipse: return(EllipseMesh.AddEllipse(meshCreator.transform.position, meshCreator.ellipseHorizontalRadius, meshCreator.ellipseVerticalRadius, meshCreator.ellipseSides, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.PointedCircle: return(PointedCircleMesh.AddPointedCircle(meshCreator.transform.position, meshCreator.pointedCircleRadius, meshCreator.pointedCircleSides, meshCreator.pointedCircleShift, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Cake: return(CakeMesh.AddCakeMesh(meshCreator.transform.position, meshCreator.cakeRadius, meshCreator.cakeSides, meshCreator.cakeSidesToFill, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Convex: return(ConvexMesh.AddConvexMesh(meshCreator.transform.position, MeshHelper.ConvertVec2ToVec3(meshCreator.convexPoints), Space.World, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Star: return(StarMesh.AddStar(meshCreator.transform.position, meshCreator.starRadiusA, meshCreator.starRadiusB, meshCreator.starSides, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Gear: return(GearMesh.AddGear(meshCreator.transform.position, meshCreator.gearInnerRadius, meshCreator.gearRootRadius, meshCreator.gearOuterRadius, meshCreator.gearSides, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Line: return(LineMesh.AddLine(meshCreator.transform.position, meshCreator.linePoints.ToArray(), meshCreator.lineWidth, meshCreator.lineUseDoubleCollider, Space.World, meshCreator.material, meshCreator.attachRigidbody)); } return(null); }
private void AddConvex(Vector3 pos) { Vector3[] verts = new Vector3[20]; for (int i = 0; i < verts.Length; i++) { float x = Random.Range(-1f, 1f); float y = Random.Range(-1f, 1f); verts[i] = new Vector3(x, y); } ConvexMesh convex = ConvexMesh.AddConvexMesh(pos, verts, Space.Self, material); convex.SetTexture(uvGridTexture); }
public PxGhRigidStaticCMesh(Plane plane, List <Mesh> meshes, Material material) { ghMeshes = new List <GH_Mesh>(); List <Mesh> initialMeshes = new List <Mesh>(meshes); actor = PhysXManager.Physics.CreateRigidStatic(); foreach (Mesh initialMesh in initialMeshes) { Mesh meshLocal = initialMesh.DuplicateMesh(); meshLocal.Transform(Transform.PlaneToPlane(plane, Plane.WorldXY)); List <Vector3> points = new List <Vector3>(); foreach (Point3d v in meshLocal.Vertices) { points.Add(new Vector3((float)v.X, (float)v.Y, (float)v.Z)); } List <int> faceVertexIndices = new List <int>(); foreach (MeshFace face in meshLocal.Faces) { faceVertexIndices.Add(face.A); faceVertexIndices.Add(face.B); faceVertexIndices.Add(face.C); } ConvexMeshDesc convexMeshDescription = new ConvexMeshDesc(); convexMeshDescription.Flags = ConvexFlag.ComputeConvex; convexMeshDescription.SetPositions(points.ToArray()); convexMeshDescription.SetTriangles(faceVertexIndices.ToArray()); MemoryStream memoryStream = new MemoryStream(); PhysXManager.Physics.CreateCooking().CookConvexMesh(convexMeshDescription, memoryStream); memoryStream.Position = 0; ConvexMesh convexMesh = PhysXManager.Physics.CreateConvexMesh(memoryStream); ConvexMeshGeometry convexMeshGeometry = new ConvexMeshGeometry(convexMesh); actor.CreateShape(convexMeshGeometry, material); ghMeshes.Add(new GH_Mesh(meshLocal)); } actor.GlobalPose = plane.ToMatrix(); }
public PxGhRigidDynamiCompoundConvexMesh(List <Mesh> meshes, Plane frame, Material material, float mass, Vector3d initialLinearVelocity, Vector3d initialAngularVelocity) : base(frame, initialLinearVelocity, initialAngularVelocity) { DisplayMeshes = new List <Mesh>(meshes); foreach (Mesh mesh in DisplayMeshes) { mesh.Transform(Transform.PlaneToPlane(frame, Plane.WorldXY)); Vector3[] vertices = new Vector3[mesh.Vertices.Count]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = mesh.Vertices[i].ToSystemVector(); } int[] faceVertexIndices = new int[mesh.Faces.Count * 3]; for (int i = 0; i < mesh.Faces.Count; i++) { MeshFace face = mesh.Faces[i]; faceVertexIndices[3 * i + 0] = face.A; faceVertexIndices[3 * i + 1] = face.B; faceVertexIndices[3 * i + 2] = face.C; } ConvexMeshDesc convexMeshDescription = new ConvexMeshDesc(); convexMeshDescription.Flags = ConvexFlag.ComputeConvex; convexMeshDescription.SetPositions(vertices); convexMeshDescription.SetTriangles(faceVertexIndices); MemoryStream memoryStream = new MemoryStream(); PxGhManager.Physics.CreateCooking().CookConvexMesh(convexMeshDescription, memoryStream); memoryStream.Position = 0; ConvexMesh convexMesh = PxGhManager.Physics.CreateConvexMesh(memoryStream); ConvexMeshGeometry convexMeshGeometry = new ConvexMeshGeometry(convexMesh); Actor.CreateShape(convexMeshGeometry, material); } Actor.SetMassAndUpdateInertia(mass); }
void Start() { meshes = new MeshBase[5]; meshes[0] = AddGear(); meshes[1] = AddStar(); meshes[2] = AddBox(); meshes[3] = AddPointedCircle(); meshes[4] = AddTriangleMesh(); int v = 0; for (int i = 0; i < meshes.Length; i++) { v += meshes[i].Vertices.Length; meshes[i].AddHingeJoint(C_JM2D); meshes[i].SetCollidersEnabled(false); } allVertices = new Vector3[v]; convexMesh = ConvexMesh.AddConvexMesh(Vector3.zero, UpdateVertices(), Space.World, convexMaterial, false); convexMesh.C_MR.sortingOrder = -1; }
private void CreateVehicle4WSimulationData( float chassisMass, ConvexMesh chassisConvexMesh, float wheelMass, ConvexMesh[] wheelConvexMeshes, Vector3[] wheelCentreOffsets, VehicleWheelsSimData wheelsData, VehicleDriveSimData4W driveData, VehicleChassisData chassisData) { const int TIRE_TYPE_SLICKS = 0; //Extract the chassis AABB dimensions from the chassis convex mesh. //Vector3 chassisDims = computeChassisAABBDimensions(chassisConvexMesh); Vector3 chassisDims = new Vector3(10, 10, 10); //The origin is at the center of the chassis mesh. //Set the center of mass to be below this point and a little towards the front. Vector3 chassisCMOffset = new Vector3(0.0f, -chassisDims.Y * 0.5f + 0.65f, 0.25f); //Now compute the chassis mass and moment of inertia. //Use the moment of inertia of a cuboid as an approximate value for the chassis moi. Vector3 chassisMOI = new Vector3 ( (chassisDims.Y * chassisDims.Y + chassisDims.Z * chassisDims.Z) * chassisMass / 12.0f, (chassisDims.X * chassisDims.X + chassisDims.Z * chassisDims.Z) * chassisMass / 12.0f, (chassisDims.X * chassisDims.X + chassisDims.Y * chassisDims.Y) * chassisMass / 12.0f ); //A bit of tweaking here. The car will have more responsive turning if we reduce the //y-component of the chassis moment of inertia. chassisMOI.Y *= 0.8f; //Let's set up the chassis data structure now. chassisData.Mass = chassisMass; chassisData.MomentOfInertia = chassisMOI; chassisData.CenterOfMassOffset = chassisCMOffset; //Work out the front/rear mass split from the cm offset. //This is a very approximate calculation with lots of assumptions. //massRear*zRear + massFront*zFront = mass*cm (1) //massRear + massFront = mass (2) //Rearrange (2) //massFront = mass - massRear (3) //Substitute (3) into (1) //massRear(zRear - zFront) + mass*zFront = mass*cm (4) //Solve (4) for massRear //massRear = mass(cm - zFront)/(zRear-zFront) (5) //Now we also have //zFront = (z-cm)/2 (6a) //zRear = (-z-cm)/2 (6b) //Substituting (6a-b) into (5) gives //massRear = 0.5*mass*(z-3cm)/z (7) float massRear = 0.5f * chassisMass * (chassisDims.Z - 3 * chassisCMOffset.Z) / chassisDims.Z; float massFront = chassisMass - massRear; //Extract the wheel radius and width from the wheel convex meshes. float[] wheelWidths = new float[4]; float[] wheelRadii = new float[4]; //ComputeWheelWidthsAndRadii(wheelConvexMeshes, wheelWidths, wheelRadii); wheelWidths = new[] { 3f, 3, 3, 3 }; wheelRadii = new[] { 1f, 1, 1, 1 }; //Now compute the wheel masses and inertias components around the axle's axis. //http://en.wikipedia.org/wiki/List_of_moments_of_inertia float[] wheelMOIs = new float[4]; for (int i = 0; i < 4; i++) { wheelMOIs[i] = 0.5f * wheelMass * wheelRadii[i] * wheelRadii[i]; } //Let's set up the wheel data structures now with radius, mass, and moi. VehicleWheelData[] wheels = new VehicleWheelData[4] { new VehicleWheelData(), new VehicleWheelData(), new VehicleWheelData(), new VehicleWheelData() }; for (int i = 0; i < 4; i++) { wheels[i].Radius = wheelRadii[i]; wheels[i].Mass = wheelMass; wheels[i].MomentOfInertia = wheelMOIs[i]; wheels[i].Width = wheelWidths[i]; } //Disable the handbrake from the front wheels and enable for the rear wheels wheels[(int)VehicleWheelOrdering.FrontLeft].MaxHandBrakeTorque = 0.0f; wheels[(int)VehicleWheelOrdering.FrontRight].MaxHandBrakeTorque = 0.0f; wheels[(int)VehicleWheelOrdering.RearLeft].MaxHandBrakeTorque = 4000.0f; wheels[(int)VehicleWheelOrdering.RearRight].MaxHandBrakeTorque = 4000.0f; //Enable steering for the front wheels and disable for the front wheels. wheels[(int)VehicleWheelOrdering.FrontLeft].MaxSteer = (float)System.Math.PI * 0.3333f; wheels[(int)VehicleWheelOrdering.FrontRight].MaxSteer = (float)System.Math.PI * 0.3333f; wheels[(int)VehicleWheelOrdering.RearLeft].MaxSteer = 0.0f; wheels[(int)VehicleWheelOrdering.RearRight].MaxSteer = 0.0f; //Let's set up the tire data structures now. //Put slicks on the front tires and wets on the rear tires. VehicleTireData[] tires = new VehicleTireData[4] { new VehicleTireData(), new VehicleTireData(), new VehicleTireData(), new VehicleTireData() }; tires[(int)VehicleWheelOrdering.FrontLeft].Type = TIRE_TYPE_SLICKS; tires[(int)VehicleWheelOrdering.FrontRight].Type = TIRE_TYPE_SLICKS; tires[(int)VehicleWheelOrdering.RearLeft].Type = TIRE_TYPE_SLICKS; tires[(int)VehicleWheelOrdering.RearRight].Type = TIRE_TYPE_SLICKS; //Let's set up the suspension data structures now. VehicleSuspensionData[] susps = new VehicleSuspensionData[4] { new VehicleSuspensionData(), new VehicleSuspensionData(), new VehicleSuspensionData(), new VehicleSuspensionData() }; for (int i = 0; i < 4; i++) { susps[i].MaxCompression = 0.3f; susps[i].MaxDroop = 0.1f; susps[i].SpringStrength = 35000.0f; susps[i].SpringDamperRate = 4500.0f; } susps[(int)VehicleWheelOrdering.FrontLeft].SprungMass = massFront * 0.5f; susps[(int)VehicleWheelOrdering.FrontRight].SprungMass = massFront * 0.5f; susps[(int)VehicleWheelOrdering.RearLeft].SprungMass = massRear * 0.5f; susps[(int)VehicleWheelOrdering.RearRight].SprungMass = massRear * 0.5f; //We need to set up geometry data for the suspension, wheels, and tires. //We already know the wheel centers described as offsets from the rigid body centre of mass. //From here we can approximate application points for the tire and suspension forces. //Lets assume that the suspension travel directions are absolutely vertical. //Also assume that we apply the tire and suspension forces 30cm below the centre of mass. Vector3[] suspTravelDirections = new Vector3[] { new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0) }; Vector3[] wheelCentreCMOffsets = new Vector3[4]; Vector3[] suspForceAppCMOffsets = new Vector3[4]; Vector3[] tireForceAppCMOffsets = new Vector3[4]; for (int i = 0; i < 4; i++) { wheelCentreCMOffsets[i] = wheelCentreOffsets[i] - chassisCMOffset; suspForceAppCMOffsets[i] = new Vector3(wheelCentreCMOffsets[i].X, -0.3f, wheelCentreCMOffsets[i].Z); tireForceAppCMOffsets[i] = new Vector3(wheelCentreCMOffsets[i].X, -0.3f, wheelCentreCMOffsets[i].Z); } //Now add the wheel, tire and suspension data. for (int i = 0; i < 4; i++) { wheelsData.SetWheelData(i, wheels[i]); wheelsData.SetTireData(i, tires[i]); wheelsData.SetSuspensionData(i, susps[i]); wheelsData.SetSuspensionTravelDirection(i, suspTravelDirections[i]); wheelsData.SetWheelCentreOffset(i, wheelCentreCMOffsets[i]); wheelsData.SetSuspensionForceApplicationPointOffset(i, suspForceAppCMOffsets[i]); wheelsData.SetTireForceApplicationPointOffset(i, tireForceAppCMOffsets[i]); } //Now set up the differential, engine, gears, clutch, and ackermann steering. //Diff VehicleDifferential4WData diff = new VehicleDifferential4WData(); diff.Type = VehicleDifferentialType.LimitedSlip4WheelDrive; driveData.SetDifferentialData(diff); //Engine VehicleEngineData engine = new VehicleEngineData() { PeakTorque = 500.0f, MaxOmega = 600.0f//approx 6000 rpm }; driveData.SetEngineData(engine); //Gears VehicleGearsData gears = new VehicleGearsData() { SwitchTime = 0.5f }; driveData.SetGearsData(gears); //Clutch VehicleClutchData clutch = new VehicleClutchData() { Strength = 10.0f }; driveData.SetClutchData(clutch); //Ackermann steer accuracy var ackermann = new VehicleAckermannGeometryData() { Accuracy = 1.0f, AxleSeparation = wheelCentreOffsets[(int)VehicleWheelOrdering.FrontLeft].Z - wheelCentreOffsets[(int)VehicleWheelOrdering.RearLeft].Z, FrontWidth = wheelCentreOffsets[(int)VehicleWheelOrdering.FrontRight].X - wheelCentreOffsets[(int)VehicleWheelOrdering.FrontLeft].X, RearWidth = wheelCentreOffsets[(int)VehicleWheelOrdering.RearRight].X - wheelCentreOffsets[(int)VehicleWheelOrdering.RearLeft].X }; driveData.SetAckermannGeometryData(ackermann); }
public Geometry(string id, string name, ConvexMesh convexMesh) : this(id, name) { this.convexMesh = convexMesh; }
private MeshBase GetChoosenMesh(MeshCreator meshCreator) { float?minArea = meshCreator.splineSimplification != SplineSimplification.Type.None ? meshCreator.minAbsoluteSplineArea : (float?)null; switch (meshCreator.meshType) { case MeshCreator.MeshType.Triangle: return(TriangleMesh.AddTriangle(meshCreator.transform.position, meshCreator.triangleVertex1, meshCreator.triangleVertex2, meshCreator.triangleVertex3, Space.World, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Rectangle: return(RectangleMesh.AddRectangle(meshCreator.transform.position, meshCreator.boxSize, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Circle: return(CircleMesh.AddCircle(meshCreator.transform.position, meshCreator.circleRadius, meshCreator.circleSides, meshCreator.circleUseCircleCollider, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Quadrangle: Vector2[] verts = new Vector2[4] { meshCreator.quadrangleVertex1, meshCreator.quadrangleVertex2, meshCreator.quadrangleVertex3, meshCreator.quadrangleVertex4 }; return(QuadrangleMesh.AddQuadrangle(meshCreator.transform.position, verts, Space.World, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Ellipse: return(EllipseMesh.AddEllipse(meshCreator.transform.position, meshCreator.ellipseHorizontalRadius, meshCreator.ellipseVerticalRadius, meshCreator.ellipseSides, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.PointedCircle: return(PointedCircleMesh.AddPointedCircle(meshCreator.transform.position, meshCreator.pointedCircleRadius, meshCreator.pointedCircleSides, meshCreator.pointedCircleShift, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Cake: return(CakeMesh.AddCakeMesh(meshCreator.transform.position, meshCreator.cakeRadius, meshCreator.cakeSides, meshCreator.cakeSidesToFill, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Convex: return(ConvexMesh.AddConvexMesh(meshCreator.transform.position, MeshHelper.ConvertVec2ToVec3(meshCreator.convexPoints), meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Star: return(StarMesh.AddStar(meshCreator.transform.position, meshCreator.starRadiusA, meshCreator.starRadiusB, meshCreator.starSides, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Gear: return(GearMesh.AddGear(meshCreator.transform.position, meshCreator.gearInnerRadius, meshCreator.gearRootRadius, meshCreator.gearOuterRadius, meshCreator.gearSides, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.Line: return(LineMesh.AddLine(meshCreator.transform.position, meshCreator.linePoints.ToArray(), meshCreator.lineWidth, meshCreator.lineUseDoubleCollider, Space.World, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.TriangulatedMesh: return(TriangulatedMesh.Add(meshCreator.transform.position, meshCreator.triangulatedPoints.ToArray(), meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.SplineShape: return(SplineShapeMesh.AddSplineShape(meshCreator.transform.position, meshCreator.splinePoints.ToArray(), meshCreator.splineResolution, minArea, Space.World, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.SplineCurve: return(SplineCurveMesh.AddSplineCurve(meshCreator.transform.position, meshCreator.splineCurvePoints.ToArray(), meshCreator.splineResolution, meshCreator.splineCurveWidth, meshCreator.splineCurveUseDoubleCollider, minArea, Space.World, meshCreator.material, meshCreator.attachRigidbody)); case MeshCreator.MeshType.SplineConvexShape: return(ConvexSplineMesh.AddConvexSpline(meshCreator.transform.position, meshCreator.convexSplinePoints.ToArray(), meshCreator.splineResolution, minArea, Space.World, meshCreator.material, meshCreator.attachRigidbody)); default: throw new System.ArgumentOutOfRangeException(); } }
/// <summary>Simple examples of all the PhysX bits running together</summary> private void LoadPhysics() { // The ground plane (if created) sould be the first actor _groundActor = _scene.Actors.First(); _groundActor.Name = "Default Ground Plane"; // #region Some Boxes for (int x = 0; x < 5; x++) { BoxShapeDescription boxShapeDesc = new BoxShapeDescription(2, 3, 8); ActorDescription actorDesc = new ActorDescription() { Name = String.Format("Box {0}", x), BodyDescription = new BodyDescription(10.0f), GlobalPose = Matrix.CreateTranslation(100, 15 + 3 * x, 20), Shapes = { boxShapeDesc } }; Actor actor = _scene.CreateActor(actorDesc); } #endregion #region Cloth (Flag) { // Create a Grid of Points VertexGrid grid = VertexGrid.CreateGrid(10, 10); ClothMeshDescription clothMeshDesc = new ClothMeshDescription(); clothMeshDesc.AllocateVertices <Vector3>(grid.Points.Length); clothMeshDesc.AllocateTriangles <int>(grid.Indices.Length / 3); clothMeshDesc.VertexCount = grid.Points.Length; clothMeshDesc.TriangleCount = grid.Indices.Length / 3; clothMeshDesc.VerticesStream.SetData(grid.Points); clothMeshDesc.TriangleStream.SetData(grid.Indices); // We are using 32 bit integers, so make sure the 16 bit flag is removed. // 32 bits are the default, so this isn't technically needed clothMeshDesc.Flags &= ~MeshFlag.Indices16Bit; // Write the cooked data to memory MemoryStream memoryStream = new MemoryStream(); Cooking.InitializeCooking(); Cooking.CookClothMesh(clothMeshDesc, memoryStream); Cooking.CloseCooking(); // Need to reset the position of the stream to the beginning memoryStream.Position = 0; ClothMesh clothMesh = _core.CreateClothMesh(memoryStream); // ClothDescription clothDesc = new ClothDescription() { ClothMesh = clothMesh, Flags = ClothFlag.Gravity | ClothFlag.Bending | ClothFlag.CollisionTwoway | ClothFlag.Visualization, GlobalPose = Matrix.CreateFromYawPitchRoll(0, (float)Math.PI / 2.0f, (float)Math.PI / 2.0f) * Matrix.CreateTranslation(0, 20, 0) }; clothDesc.MeshData.AllocatePositions <Vector3>(grid.Points.Length); clothDesc.MeshData.AllocateIndices <int>(grid.Indices.Length); clothDesc.MeshData.MaximumVertices = grid.Points.Length; clothDesc.MeshData.MaximumIndices = grid.Indices.Length; clothDesc.MeshData.NumberOfVertices = grid.Points.Length; clothDesc.MeshData.NumberOfIndices = grid.Indices.Length; _flag = _scene.CreateCloth(clothDesc); // Flag Pole ActorDescription flagPoleActorDesc = new ActorDescription() { GlobalPose = Matrix.CreateTranslation(0, 10, 0), Shapes = { new BoxShapeDescription(1.0f, 20.0f, 1.0f) } }; Actor flagPoleActor = _scene.CreateActor(flagPoleActorDesc); _flag.AttachToShape(flagPoleActor.Shapes[0], 0); _flag.WindAcceleration = new Vector3(10, 10, 10); _flag.BendingStiffness = 0.1f; } #endregion #region Revolute Joint { BoxShapeDescription boxShapeDescA = new BoxShapeDescription(3, 3, 3); BoxShapeDescription boxShapeDescB = new BoxShapeDescription(3, 3, 3); ActorDescription actorDescA = new ActorDescription() { BodyDescription = new BodyDescription(10.0f), GlobalPose = Matrix.CreateTranslation(75, 1.5f, 55), Shapes = { boxShapeDescA } }; Actor actorA = _scene.CreateActor(actorDescA); ActorDescription actorDescB = new ActorDescription() { BodyDescription = new BodyDescription(10.0f), GlobalPose = Matrix.CreateTranslation(70, 1.5f, 55), Shapes = { boxShapeDescB } }; Actor actorB = _scene.CreateActor(actorDescB); // RevoluteJointDescription revoluteJointDesc = new RevoluteJointDescription() { Actor1 = actorA, Actor2 = actorB, Motor = new MotorDescription(20, 20.1f, true) }; revoluteJointDesc.Flags |= RevoluteJointFlag.MotorEnabled; revoluteJointDesc.SetGlobalAnchor(new Vector3(73.5f, 1.5f, 55)); revoluteJointDesc.SetGlobalAxis(new Vector3(1, 0, 0)); RevoluteJoint revoluteJoint = _scene.CreateJoint(revoluteJointDesc) as RevoluteJoint; } #endregion #region Prismatic Joint with Limit { Actor actorA, actorB; { BoxShapeDescription boxShapeDesc = new BoxShapeDescription(3, 3, 3); BodyDescription bodyDesc = new BodyDescription(10.0f); bodyDesc.BodyFlags |= BodyFlag.Kinematic; ActorDescription actorDesc = new ActorDescription() { BodyDescription = bodyDesc, GlobalPose = Matrix.CreateTranslation(70, 25, 65), Shapes = { boxShapeDesc } }; actorA = _scene.CreateActor(actorDesc); } { BoxShapeDescription boxShapeDesc = new BoxShapeDescription(3, 3, 3); ActorDescription actorDesc = new ActorDescription() { BodyDescription = new BodyDescription(10.0f), GlobalPose = Matrix.CreateTranslation(70, 15, 65), Shapes = { boxShapeDesc } }; actorB = _scene.CreateActor(actorDesc); } PrismaticJointDescription prismaticJointDesc = new PrismaticJointDescription() { Actor1 = actorA, Actor2 = actorB, }; prismaticJointDesc.SetGlobalAnchor(new Vector3(70, 20, 65)); prismaticJointDesc.SetGlobalAxis(new Vector3(0, 1, 0)); PrismaticJoint prismaticJoint = _scene.CreateJoint(prismaticJointDesc) as PrismaticJoint; LimitPlane limitPlane = new LimitPlane(new Vector3(0, 1, 0), new Vector3(-30, 8, -30), 0); prismaticJoint.AddLimitPlane(limitPlane); } #endregion #region Fluid { const int maximumParticles = 1000; FluidEmitterDescription fluidEmitterDesc = new FluidEmitterDescription() { DimensionX = 0.5f, DimensionY = 0.5f, Rate = 15, RelativePose = Matrix.CreateTranslation(-40, 10, 50), Shape = EmitterShape.Rectangular, Type = EmitterType.ConstantFlowRate, RandomAngle = 0.5f }; fluidEmitterDesc.Flags |= (FluidEmitterFlag.Enabled | FluidEmitterFlag.Visualization); FluidDescription fluidDesc = new FluidDescription() { Emitters = { fluidEmitterDesc }, Flags = FluidFlag.Enabled | FluidFlag.Visualization, MaximumParticles = maximumParticles }; fluidDesc.ParticleWriteData.AllocatePositionBuffer <Vector3>(maximumParticles); fluidDesc.ParticleWriteData.NumberOfParticles = maximumParticles; Fluid fluid = _scene.CreateFluid(fluidDesc); // Ledge { BoxShapeDescription boxShapeDesc = new BoxShapeDescription(5, 0.1f, 5); ActorDescription drainActorDesc = new ActorDescription() { GlobalPose = Matrix.CreateRotationX(0.5f) * Matrix.CreateTranslation(-40, 5, 52), Shapes = { boxShapeDesc } }; Actor drianActor = _scene.CreateActor(drainActorDesc); } // Drain { BoxShapeDescription boxShapeDesc = new BoxShapeDescription(5, 0.1f, 5); boxShapeDesc.Flags |= ShapeFlag.FluidDrain; ActorDescription drainActorDesc = new ActorDescription() { GlobalPose = Matrix.CreateTranslation(-40, 0, 55), Shapes = { boxShapeDesc } }; Actor drianActor = _scene.CreateActor(drainActorDesc); } } #endregion #region Force Field { BoxForceFieldShapeDescription boxForceFieldShapeDesc = new BoxForceFieldShapeDescription() { Size = new Vector3(10, 10, 10) }; ForceFieldLinearKernelDescription kernelDesc = new ForceFieldLinearKernelDescription() { Constant = new Vector3(0, 100.0f, 0) }; ForceFieldLinearKernel kernel = _scene.CreateForceFieldLinearKernel(kernelDesc); ForceFieldShapeGroupDescription shapeGroupDesc = new ForceFieldShapeGroupDescription() { Shapes = { boxForceFieldShapeDesc } }; ForceFieldShapeGroup shapeGroup = _scene.CreateForceFieldShapeGroup(shapeGroupDesc); BoxForceFieldShape boxForceFieldShape = shapeGroup.CreateShape(boxForceFieldShapeDesc) as BoxForceFieldShape; boxForceFieldShape.Pose = Matrix.CreateTranslation(30, 5, 0); ForceFieldDescription forceFieldDesc = new ForceFieldDescription() { Kernel = kernel, ShapeGroups = { shapeGroup } }; ForceField forceField = _scene.CreateForceField(forceFieldDesc); } #endregion #region Heightfield { int rows = 25; int columns = 25; HeightFieldSample[] samples = new HeightFieldSample[rows * columns]; for (int r = 0; r < rows; r++) { for (int c = 0; c < columns; c++) { // Put a z and x curve together double h = Math.Sin(c) * Math.Cos(r) * short.MaxValue; HeightFieldSample sample = new HeightFieldSample(); sample.Height = (short)h; sample.MaterialIndex0 = 0; sample.MaterialIndex1 = 1; sample.TessellationFlag = 0; samples[r * columns + c] = sample; } } HeightFieldDescription heightFieldDesc = new HeightFieldDescription() { NumberOfRows = rows, NumberOfColumns = columns, Samples = samples }; HeightField heightField = _core.CreateHeightField(heightFieldDesc); // HeightFieldShapeDescription heightFieldShapeDesc = new HeightFieldShapeDescription() { HeightField = heightField, HoleMaterial = 2, // The max height of our samples is short.MaxValue and we want it to be 1 HeightScale = 1.0f / (float)short.MaxValue, RowScale = 3, ColumnScale = 3 }; heightFieldShapeDesc.LocalPosition = new Vector3(-0.5f * rows * 1 * heightFieldShapeDesc.RowScale, 0, -0.5f * columns * 1 * heightFieldShapeDesc.ColumnScale); ActorDescription actorDesc = new ActorDescription() { GlobalPose = Matrix.CreateTranslation(100, 0, 0), Shapes = { heightFieldShapeDesc } }; Actor actor = _scene.CreateActor(actorDesc); } #endregion #region Convex Mesh { ModelMesh mesh = _torusModel.Meshes.First(); Matrix[] transforms = new Matrix[_torusModel.Bones.Count]; _torusModel.CopyAbsoluteBoneTransformsTo(transforms); // Gets the vertices from the mesh VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[mesh.MeshParts[0].NumVertices]; mesh.VertexBuffer.GetData <VertexPositionNormalTexture>(vertices); // // Allocate memory for the points and triangles var convexMeshDesc = new ConvexMeshDescription() { PointCount = vertices.Length }; convexMeshDesc.Flags |= ConvexFlag.ComputeConvex; convexMeshDesc.AllocatePoints <Vector3>(vertices.Length); // Write in the points and triangles // We only want the Position component of the vertex. Also scale down the mesh foreach (VertexPositionNormalTexture vertex in vertices) { Vector3 position = Vector3.Transform(vertex.Position, Matrix.CreateScale(0.1f, 0.1f, 0.1f) * transforms[0]); convexMeshDesc.PointsStream.Write(position); } // // Cook to memory or to a file MemoryStream stream = new MemoryStream(); //FileStream stream = new FileStream( @"Convex Mesh.cooked", FileMode.CreateNew ); Cooking.InitializeCooking(new ConsoleOutputStream()); Cooking.CookConvexMesh(convexMeshDesc, stream); Cooking.CloseCooking(); stream.Position = 0; ConvexMesh convexMesh = _core.CreateConvexMesh(stream); ConvexShapeDescription convexShapeDesc = new ConvexShapeDescription(convexMesh); ActorDescription actorDesc = new ActorDescription() { BodyDescription = new BodyDescription(10.0f), GlobalPose = Matrix.CreateTranslation(30, 30, 0) }; actorDesc.Shapes.Add(convexShapeDesc); _torusActor = _scene.CreateActor(actorDesc); } #endregion #region SoftBody if (false) // Enable to view soft bodies, they run slowly { XmlDocument doc = new XmlDocument(); doc.Load("Teapot.xml"); // Not how NxuStream are meant to used but what ever :S Vector3[] vertices = ReadVertices(doc.SelectSingleNode("/NXUSTREAM2/NxuPhysicsCollection/NxSoftBodyMeshDesc/vertices")); int[] tetrahedraSingles = ReadTetrahedra(doc.SelectSingleNode("/NXUSTREAM2/NxuPhysicsCollection/NxSoftBodyMeshDesc/tetrahedra")); var softBodyMeshDesc = new SoftBodyMeshDescription() { VertexCount = vertices.Length, TetrahedraCount = tetrahedraSingles.Length / 4 // Tetrahedras come in quadruples of ints }; softBodyMeshDesc.AllocateVertices <Vector3>(softBodyMeshDesc.VertexCount); softBodyMeshDesc.AllocateTetrahedra <int>(softBodyMeshDesc.TetrahedraCount); // Note: T is an int. T is the type of each point softBodyMeshDesc.VertexStream.SetData(vertices); softBodyMeshDesc.TetrahedraStream.SetData(tetrahedraSingles); MemoryStream memoryStream = new MemoryStream(); Cooking.InitializeCooking(); Cooking.CookSoftBodyMesh(softBodyMeshDesc, memoryStream); Cooking.CloseCooking(); memoryStream.Position = 0; SoftBodyMesh softBodyMesh = _core.CreateSoftBodyMesh(memoryStream); SoftBodyDescription desc = new SoftBodyDescription() { GlobalPose = Matrix.CreateTranslation(-30, 20, -30), SoftBodyMesh = softBodyMesh }; desc.Flags |= SoftBodyFlag.Visualization; desc.MeshData.AllocatePositions <Vector3>(vertices.Length); desc.MeshData.AllocateIndices <int>(tetrahedraSingles.Length); SoftBody softBody = _scene.CreateSoftBody(desc); } #endregion #region Reports // Contact report // When the capsule actor hits the ground make it bounce by using the conact report { CapsuleShapeDescription capsuleShapeDesc = new CapsuleShapeDescription(1, 5); ActorDescription actorDesc = new ActorDescription() { GlobalPose = Matrix.CreateTranslation(-30, 20, 0), BodyDescription = new BodyDescription(10.0f), Name = "Report Capsule", Shapes = { capsuleShapeDesc } }; _contactReportActor = _scene.CreateActor(actorDesc); _scene.SetActorPairFlags(_contactReportActor, _groundActor, ContactPairFlag.All); _scene.UserContactReport = new ContactReport(this); } // Trigger Reports { BoxShapeDescription boxShapeDesc = new BoxShapeDescription(15, 8, 15); boxShapeDesc.Flags |= (ShapeFlag.TriggerOnEnter | ShapeFlag.TriggerOnLeave); ActorDescription actorDesc = new ActorDescription() { GlobalPose = Matrix.CreateTranslation(-30, 4, 0), Shapes = { boxShapeDesc } }; _scene.CreateActor(actorDesc); _scene.UserTriggerReport = new TriggerReport(this); } _scene.UserNotify = new Notify(this); #endregion #region Wheel { _basicVehicle = new Vehicle(this); } #endregion #region Controller { ControllerManager manager = _scene.CreateControllerManager(); CapsuleControllerDescription capsuleControllerDesc = new CapsuleControllerDescription(4, 3) { Callback = new ControllerHitReport() }; CapsuleController capsuleController = manager.CreateController <CapsuleController>(capsuleControllerDesc); capsuleController.Position = new Vector3(0, 1.5f + 2, -15); capsuleController.Actor.Name = "BoxController"; capsuleController.SetCollisionEnabled(true); } #endregion }
private List <Vector3> GetConvexPoints() { return(ConvexMesh.QuickHull(new List <Vector3>(MeshHelper.ConvertVec2ToVec3(convexPoints)))); }
private void CreateVehicle4WSimulationData( float chassisMass, ConvexMesh chassisConvexMesh, float wheelMass, ConvexMesh[] wheelConvexMeshes, Vector3[] wheelCentreOffsets, VehicleWheelsSimData wheelsData, VehicleDriveSimData4W driveData, VehicleChassisData chassisData) { const int TIRE_TYPE_SLICKS = 0; //Extract the chassis AABB dimensions from the chassis convex mesh. //Vector3 chassisDims = computeChassisAABBDimensions(chassisConvexMesh); Vector3 chassisDims = new Vector3(10, 10, 10); //The origin is at the center of the chassis mesh. //Set the center of mass to be below this point and a little towards the front. Vector3 chassisCMOffset = new Vector3(0.0f, -chassisDims.Y * 0.5f + 0.65f, 0.25f); //Now compute the chassis mass and moment of inertia. //Use the moment of inertia of a cuboid as an approximate value for the chassis moi. Vector3 chassisMOI = new Vector3 ( (chassisDims.Y * chassisDims.Y + chassisDims.Z * chassisDims.Z) * chassisMass / 12.0f, (chassisDims.X * chassisDims.X + chassisDims.Z * chassisDims.Z) * chassisMass / 12.0f, (chassisDims.X * chassisDims.X + chassisDims.Y * chassisDims.Y) * chassisMass / 12.0f ); //A bit of tweaking here. The car will have more responsive turning if we reduce the //y-component of the chassis moment of inertia. chassisMOI.Y *= 0.8f; //Let's set up the chassis data structure now. chassisData.Mass = chassisMass; chassisData.MomentOfInertia = chassisMOI; chassisData.CenterOfMassOffset = chassisCMOffset; //Work out the front/rear mass split from the cm offset. //This is a very approximate calculation with lots of assumptions. //massRear*zRear + massFront*zFront = mass*cm (1) //massRear + massFront = mass (2) //Rearrange (2) //massFront = mass - massRear (3) //Substitute (3) into (1) //massRear(zRear - zFront) + mass*zFront = mass*cm (4) //Solve (4) for massRear //massRear = mass(cm - zFront)/(zRear-zFront) (5) //Now we also have //zFront = (z-cm)/2 (6a) //zRear = (-z-cm)/2 (6b) //Substituting (6a-b) into (5) gives //massRear = 0.5*mass*(z-3cm)/z (7) float massRear = 0.5f * chassisMass * (chassisDims.Z - 3 * chassisCMOffset.Z) / chassisDims.Z; float massFront = chassisMass - massRear; //Extract the wheel radius and width from the wheel convex meshes. float[] wheelWidths = new float[4]; float[] wheelRadii = new float[4]; //ComputeWheelWidthsAndRadii(wheelConvexMeshes, wheelWidths, wheelRadii); wheelWidths = new[] { 3f, 3, 3, 3 }; wheelRadii = new[] { 1f, 1, 1, 1 }; //Now compute the wheel masses and inertias components around the axle's axis. //http://en.wikipedia.org/wiki/List_of_moments_of_inertia float[] wheelMOIs = new float[4]; for (int i = 0; i < 4; i++) { wheelMOIs[i] = 0.5f * wheelMass * wheelRadii[i] * wheelRadii[i]; } //Let's set up the wheel data structures now with radius, mass, and moi. VehicleWheelData[] wheels = new VehicleWheelData[4] { new VehicleWheelData(), new VehicleWheelData(), new VehicleWheelData(), new VehicleWheelData() }; for (int i = 0; i < 4; i++) { wheels[i].Radius = wheelRadii[i]; wheels[i].Mass = wheelMass; wheels[i].MomentOfInertia = wheelMOIs[i]; wheels[i].Width = wheelWidths[i]; } //Disable the handbrake from the front wheels and enable for the rear wheels wheels[(int)VehicleWheelOrdering.FrontLeftWheel].MaxHandBrakeTorque = 0.0f; wheels[(int)VehicleWheelOrdering.FrontRightWheel].MaxHandBrakeTorque = 0.0f; wheels[(int)VehicleWheelOrdering.RearLeftWheel].MaxHandBrakeTorque = 4000.0f; wheels[(int)VehicleWheelOrdering.RearRightWheel].MaxHandBrakeTorque = 4000.0f; //Enable steering for the front wheels and disable for the front wheels. wheels[(int)VehicleWheelOrdering.FrontLeftWheel].MaxSteer = (float)System.Math.PI * 0.3333f; wheels[(int)VehicleWheelOrdering.FrontRightWheel].MaxSteer = (float)System.Math.PI * 0.3333f; wheels[(int)VehicleWheelOrdering.RearLeftWheel].MaxSteer = 0.0f; wheels[(int)VehicleWheelOrdering.RearRightWheel].MaxSteer = 0.0f; //Let's set up the tire data structures now. //Put slicks on the front tires and wets on the rear tires. VehicleTireData[] tires = new VehicleTireData[4] { new VehicleTireData(), new VehicleTireData(), new VehicleTireData(), new VehicleTireData() }; tires[(int)VehicleWheelOrdering.FrontLeftWheel].Type = TIRE_TYPE_SLICKS; tires[(int)VehicleWheelOrdering.FrontRightWheel].Type = TIRE_TYPE_SLICKS; tires[(int)VehicleWheelOrdering.RearLeftWheel].Type = TIRE_TYPE_SLICKS; tires[(int)VehicleWheelOrdering.RearRightWheel].Type = TIRE_TYPE_SLICKS; //Let's set up the suspension data structures now. VehicleSuspensionData[] susps = new VehicleSuspensionData[4] { new VehicleSuspensionData(), new VehicleSuspensionData(), new VehicleSuspensionData(), new VehicleSuspensionData() }; for (int i = 0; i < 4; i++) { susps[i].MaxCompression = 0.3f; susps[i].MaxDroop = 0.1f; susps[i].SpringStrength = 35000.0f; susps[i].SpringDamperRate = 4500.0f; } susps[(int)VehicleWheelOrdering.FrontLeftWheel].SprungMass = massFront * 0.5f; susps[(int)VehicleWheelOrdering.FrontRightWheel].SprungMass = massFront * 0.5f; susps[(int)VehicleWheelOrdering.RearLeftWheel].SprungMass = massRear * 0.5f; susps[(int)VehicleWheelOrdering.RearRightWheel].SprungMass = massRear * 0.5f; //We need to set up geometry data for the suspension, wheels, and tires. //We already know the wheel centers described as offsets from the rigid body centre of mass. //From here we can approximate application points for the tire and suspension forces. //Lets assume that the suspension travel directions are absolutely vertical. //Also assume that we apply the tire and suspension forces 30cm below the centre of mass. Vector3[] suspTravelDirections = new Vector3[] { new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0) }; Vector3[] wheelCentreCMOffsets = new Vector3[4]; Vector3[] suspForceAppCMOffsets = new Vector3[4]; Vector3[] tireForceAppCMOffsets = new Vector3[4]; for (int i = 0; i < 4; i++) { wheelCentreCMOffsets[i] = wheelCentreOffsets[i] - chassisCMOffset; suspForceAppCMOffsets[i] = new Vector3(wheelCentreCMOffsets[i].X, -0.3f, wheelCentreCMOffsets[i].Z); tireForceAppCMOffsets[i] = new Vector3(wheelCentreCMOffsets[i].X, -0.3f, wheelCentreCMOffsets[i].Z); } //Now add the wheel, tire and suspension data. for (int i = 0; i < 4; i++) { wheelsData.SetWheelData(i, wheels[i]); wheelsData.SetTireData(i, tires[i]); wheelsData.SetSuspensionData(i, susps[i]); wheelsData.SetSuspensionTravelDirection(i, suspTravelDirections[i]); wheelsData.SetWheelCentreOffset(i, wheelCentreCMOffsets[i]); wheelsData.SetSuspensionForceApplicationPointOffset(i, suspForceAppCMOffsets[i]); wheelsData.SetTireForceApplicationPointOffset(i, tireForceAppCMOffsets[i]); } //Now set up the differential, engine, gears, clutch, and ackermann steering. //Diff VehicleDifferential4WData diff = new VehicleDifferential4WData(); diff.Type = VehicleDifferentialType.LimitedSlip4WheelDrive; driveData.SetDifferentialData(diff); //Engine VehicleEngineData engine = new VehicleEngineData() { PeakTorque = 500.0f, MaxOmega = 600.0f //approx 6000 rpm }; driveData.SetEngineData(engine); //Gears VehicleGearsData gears = new VehicleGearsData() { SwitchTime = 0.5f }; driveData.SetGearsData(gears); //Clutch VehicleClutchData clutch = new VehicleClutchData() { Strength = 10.0f }; driveData.SetClutchData(clutch); //Ackermann steer accuracy VehicleAckermannGeometryData ackermann = new VehicleAckermannGeometryData() { Accuracy = 1.0f, AxleSeparation = wheelCentreOffsets[(int)VehicleWheelOrdering.FrontLeftWheel].Z - wheelCentreOffsets[(int)VehicleWheelOrdering.RearLeftWheel].Z, FrontWidth = wheelCentreOffsets[(int)VehicleWheelOrdering.FrontRightWheel].X - wheelCentreOffsets[(int)VehicleWheelOrdering.FrontLeftWheel].X, RearWidth = wheelCentreOffsets[(int)VehicleWheelOrdering.RearRightWheel].X - wheelCentreOffsets[(int)VehicleWheelOrdering.RearLeftWheel].X }; driveData.SetAckermannGeometryData(ackermann); }
public override void addConvexMesh(string name, ConvexMesh mesh) { throw new NotImplementedException(); }
/// <summary> /// Add a convex mesh that will be managed by this reposotory. This will /// be released when this object is disposed. /// </summary> /// <param name="mesh">The mesh to add.</param> public abstract void addConvexMesh(String name, ConvexMesh mesh);