/// <summary> /// Starts the component. /// </summary> /// <param name="time">Time snapshot</param> protected override void OnStart(GameTime time) { base.OnStart(time); while (!this.Model.IsLoaded) { Thread.Sleep(0); } List <Vector3> positions = new List <Vector3>(); List <int> indexList = new List <int>(); int offset = 0; foreach (var mesh in this.Model.GetMeshes()) { offset = positions.Count; foreach (var vertex in mesh.GetVertices()) { positions.Add(new Vector3(vertex.Position.X, vertex.Position.Y, vertex.Position.Z)); } uint[] indexes = mesh.GetIndexes(); for (int i = 0; i < indexes.Length; i++) { indexList.Add(offset + (int)indexes[i]); } } var triangleMesh = new TriangleIndexVertexArray(indexList.ToArray(), positions.ToArray()); this.shape = new BvhTriangleMeshShape(triangleMesh, true, true); this.shape.UserObject = this; }
protected override CollisionShape CreateShape() { TriangleIndexVertexArray tiv = new TriangleIndexVertexArray(this.indices, this.vertices); BvhTriangleMeshShape bvh = new BvhTriangleMeshShape(tiv, true, true); return(bvh); }
public void SetUp() { conf = new DefaultCollisionConfiguration(); dispatcher = new CollisionDispatcher(conf); broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)); world = new DiscreteDynamicsWorld(dispatcher, broadphase, null, conf); // Initialize TriangleIndexVertexArray with float array indexVertexArray = new TriangleIndexVertexArray(TorusMesh.Indices, TorusMesh.Vertices); gImpactMeshShape = new GImpactMeshShape(indexVertexArray); gImpactMeshShape.CalculateLocalInertia(1.0f); gImpactMesh = CreateBody(1.0f, gImpactMeshShape, Vector3.Zero); // Initialize TriangleIndexVertexArray with Vector3 array Vector3[] torusVertices = new Vector3[TorusMesh.Vertices.Length / 3]; for (int i = 0; i < torusVertices.Length; i++) { torusVertices[i] = new Vector3( TorusMesh.Vertices[i * 3], TorusMesh.Vertices[i * 3 + 1], TorusMesh.Vertices[i * 3 + 2]); } indexVertexArray2 = new TriangleIndexVertexArray(TorusMesh.Indices, torusVertices); triangleMeshShape = new BvhTriangleMeshShape(indexVertexArray2, true); // CalculateLocalInertia must fail for static shapes (shapes based on TriangleMeshShape) //triangleMeshShape.CalculateLocalInertia(1.0f); triangleMesh = CreateBody(0.0f, triangleMeshShape, Vector3.Zero); }
CollisionShape BuildLargeMesh() { //int vertStride = sizeof(IndexedVector3); //int indexStride = 3*sizeof(int); int vertStride = 1; int indexStride = 3; ObjectArray <IndexedVector3> vertexArray = new ObjectArray <IndexedVector3>(); for (int i = 0; i < vertices.Length; ++i) { vertexArray.Add(vertices[i]); } ObjectArray <int> intArray = new ObjectArray <int>(); for (int i = 0; i < indices.Length; ++i) { intArray.Add(indices[i]); } //TriangleIndexVertexArray indexVertexArray = new TriangleIndexVertexArray(DemoMeshes.BUNNY_NUM_TRIANGLES, DemoMeshes.gBunnyIndices, 3, DemoMeshes.BUNNY_NUM_VERTICES, DemoMeshes.gBunnyVertices, 3); TriangleIndexVertexArray indexVertexArray = new TriangleIndexVertexArray(numTriangles, intArray, indexStride, vertexArray.Count, vertexArray, vertStride); TriangleMeshShape triangleMesh = new TriangleMeshShape(indexVertexArray); //TriangleMeshShape triangleMesh = new BvhTriangleMeshShape(indexVertexArray,true,true); return(triangleMesh); }
private void TestTriangleArray(TriangleIndexVertexArray triangleArray) { Assert.AreSame(triangleArray.IndexedMeshArray, triangleArray.IndexedMeshArray); // check caching foreach (var indexedMesh in triangleArray.IndexedMeshArray) { Assert.NotNull(indexedMesh); } var initialMesh = triangleArray.IndexedMeshArray[0]; Assert.AreEqual(PhyScalarType.Int32, initialMesh.IndexType); Assert.AreEqual(PhyScalarType.Single, initialMesh.VertexType); Assert.AreEqual(TorusMesh.Vertices.Length / 3, initialMesh.NumVertices); Assert.AreEqual(TorusMesh.Indices.Length / 3, initialMesh.NumTriangles); Assert.AreEqual(sizeof(float) * 3, initialMesh.VertexStride); Assert.AreEqual(sizeof(int) * 3, initialMesh.TriangleIndexStride); var triangleIndices = initialMesh.TriangleIndices; Assert.AreEqual(TorusMesh.Indices.Length, triangleIndices.Count); for (int i = 0; i < triangleIndices.Count; i++) { Assert.AreEqual(triangleIndices[i], TorusMesh.Indices[i]); } }
public void SetUp() { int[] triangles1 = new[] { 0, 1, 2 }; Vector3[] vertices1 = new Vector3[] { new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0) }; _meshInterface = new TriangleIndexVertexArray(triangles1, vertices1); int[] triangles2 = new[] { 0, 1, 2 }; Vector3[] vertices2 = new Vector3[] { new Vector3(0, 0, 3), new Vector3(1, 0, 3), new Vector3(0, 1, 3) }; _indexedMesh = new IndexedMesh(); _indexedMesh.Allocate(triangles2.Length / 3, vertices2.Length); _indexedMesh.SetData(triangles2, vertices2); _meshInterface.AddIndexedMesh(_indexedMesh); _impactMesh = new GImpactMeshShape(_meshInterface); }
internal void LoadScenarioCollision(ScenarioStructureBspBlock structureBSP) { foreach (var cluster in structureBSP.clusters) { var triangleMesh = new TriangleMesh(); var vertices = new Vector3[cluster.clusterData[0].section.vertexBuffers[0].vertexBuffer.Data.Length / 12]; for (int i = 0; i < vertices.Length; ++i) { var data = cluster.clusterData[0].section.vertexBuffers[0].vertexBuffer.Data; vertices[i] = new Vector3( BitConverter.ToSingle(data, i * 12 + 0), BitConverter.ToSingle(data, i * 12 + 4), BitConverter.ToSingle(data, i * 12 + 8)); } TriangleIndexVertexArray inte = new TriangleIndexVertexArray( cluster.clusterData[0].section.stripIndices.Select(x => (int)x.index).ToArray(), vertices); CollisionObject o = new CollisionObject(); o.CollisionShape = new BvhTriangleMeshShape(inte, true); o.CollisionFlags = CollisionFlags.StaticObject; World.AddCollisionObject(o, CollisionFilterGroups.StaticFilter, CollisionFilterGroups.AllFilter); } }
void InitGImpactCollision() { // Create Torus Shape indexVertexArrays = new TriangleIndexVertexArray(TorusMesh.Indices, TorusMesh.Vertices); #if BULLET_GIMPACT #if BULLET_GIMPACT_CONVEX_DECOMPOSITION //GImpactConvexDecompositionShape trimesh = // new GImpactConvexDecompositionShape(indexVertexArrays, new Vector3(1), 0.01f); //trimesh.Margin = 0.07f; //trimesh.UpdateBound(); #else GImpactMeshShape trimesh = new GImpactMeshShape(indexVertexArrays); trimesh.LocalScaling = new Vector3(1); #if BULLET_TRIANGLE_COLLISION trimesh.Margin = 0.07f; //????? #else trimesh.Margin = 0; #endif trimesh.UpdateBound(); #endif trimeshShape = trimesh; #else //trimeshShape = new GImpactMeshData(indexVertexArrays); #endif /// Create Bunny Shape indexVertexArrays2 = new TriangleIndexVertexArray(BunnyMesh.Indices, BunnyMesh.Vertices); #if BULLET_GIMPACT #if BULLET_GIMPACT_CONVEX_DECOMPOSITION //GImpactConvexDecompositionShape trimesh2 = // new GImpactConvexDecompositionShape(indexVertexArrays, new Vector3(1), 0.01f); //trimesh.Margin = 0.07f; //trimesh.UpdateBound(); //trimeshShape = trimesh2; #else GImpactMeshShape trimesh2 = new GImpactMeshShape(indexVertexArrays2); trimesh2.LocalScaling = new Vector3(1); #if BULLET_TRIANGLE_COLLISION trimesh2.Margin = 0.07f; //????? #else trimesh2.Margin = 0; #endif trimesh2.UpdateBound(); trimeshShape2 = trimesh2; #endif #else //trimeshShape2 = new GImpactMeshData(indexVertexArrays2); #endif //register GIMPACT algorithm #if BULLET_GIMPACT GImpactCollisionAlgorithm.RegisterAlgorithm(Dispatcher); #else //ConcaveConcaveCollisionAlgorithm.RegisterAlgorithm(Dispatcher); #endif }
internal static object CreateMeshShapeF(object pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) { ObjectArray <int> indicesarr = new ObjectArray <int>(indices); ObjectArray <float> vertices = new ObjectArray <float>(verticesAsFloats); var world = pWorld as DiscreteDynamicsWorld; IndexedMesh mesh = new IndexedMesh(); mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; mesh.m_numTriangles = pIndicesCount / 3; mesh.m_numVertices = pVerticesCount; mesh.m_triangleIndexBase = indicesarr; mesh.m_vertexBase = vertices; mesh.m_vertexStride = 3; mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; mesh.m_triangleIndexStride = 3; TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(tribuilder, false, true); //TriangleMeshShape meshShape = new TriangleMeshShape(tribuilder); //meshShape.SetMargin(world.WorldSettings.Params.collisionMargin); float margin = 0.02f; meshShape.SetMargin(margin); return(meshShape); }
private GImpactMeshShape CreateGImpactShape(TriangleIndexVertexArray shapeData) { var shape = new GImpactMeshShape(shapeData); shape.Margin = 0; shape.UpdateBound(); return(shape); }
private GImpactMeshShape CreateGImpactConvexDecompositionShape(TriangleIndexVertexArray shapeData) { //GImpactConvexDecompositionShape shape = // new GImpactConvexDecompositionShape(indexVertexArrays, new Vector3(1), 0.01f); //shape.Margin = 0.07f; //shape.UpdateBound(); //return shape; throw new NotImplementedException(); }
public override void Run() { var conf = new DefaultCollisionConfiguration(); var dispatcher = new CollisionDispatcher(conf); var broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)); world = new DiscreteDynamicsWorld(dispatcher, broadphase, null, conf); var indexVertexArray = new TriangleIndexVertexArray(TorusMesh.Indices, TorusMesh.Vertices); foreach (var indexedMesh in indexVertexArray.IndexedMeshArray) { indexedMesh.ToString(); } AddToDisposeQueue(indexVertexArray); var gImpactMesh = new GImpactMeshShape(indexVertexArray); Vector3 aabbMin, aabbMax; gImpactMesh.GetAabb(Matrix.Identity, out aabbMin, out aabbMax); CreateBody(1.0f, gImpactMesh, Vector3.Zero); AddToDisposeQueue(gImpactMesh); gImpactMesh = null; var triangleMesh = new BvhTriangleMeshShape(indexVertexArray, true); triangleMesh.CalculateLocalInertia(1.0f); triangleMesh.GetAabb(Matrix.Identity, out aabbMin, out aabbMax); CreateBody(1.0f, triangleMesh, Vector3.Zero); AddToDisposeQueue(triangleMesh); triangleMesh = null; indexVertexArray = null; AddToDisposeQueue(conf); AddToDisposeQueue(dispatcher); AddToDisposeQueue(broadphase); AddToDisposeQueue(world); //conf.Dispose(); conf = null; //dispatcher.Dispose(); dispatcher = null; //broadphase.Dispose(); broadphase = null; for (int i = 0; i < 600; i++) { world.StepSimulation(1.0f / 60.0f); } world.Dispose(); world = null; ForceGC(); TestWeakRefs(); ClearRefs(); }
public BvhTriangleMeshShape GetAccurateCollisionShape() { //if (CachedBvhTriangleMeshShape != null) return CachedBvhTriangleMeshShape; List <Vector3> vectors = GetRawVertexList(); var smesh = new TriangleIndexVertexArray(Enumerable.Range(0, Vertices.Count).ToArray(), vectors.Select((a) => a).ToArray()); CachedBvhTriangleMeshShape = new BvhTriangleMeshShape(smesh, false); //CachedBvhTriangleMeshShape.LocalScaling = new Vector3(scale); return(CachedBvhTriangleMeshShape); }
protected override CollisionShape CreateShape() { //ConvexHullShape shape = new ConvexHullShape(this.vertices); //BvhTriangleMeshShape bvh = new BvhTriangleMeshShape( //StridingMeshInterface smi = new StridingMeshInterface(); TriangleIndexVertexArray tiv = new TriangleIndexVertexArray(this.indices, this.vertices); BvhTriangleMeshShape bvh = new BvhTriangleMeshShape(tiv, true, true); //StridingMeshInterface return(bvh); }
// Loads the given OBJ file, creates a RigidBody with the given mess, and places // at the origin of the ground. protected void PrepareSimObj(string objFile, float mass, BulletSharp.Math.Vector3 inertia) { Debug.Log("Loading " + objFile + "..."); // Load wavefront file OBJLoader.OBJMesh objloadermesh = OBJLoader.LoadOBJMesh(objFile); Debug.Assert(objloadermesh.vertices.Count > 0); Debug.Assert(objloadermesh.faces.Count > 0); // Debug.Log("VERTS: " + objloadermesh.vertices.Count.ToString()); // Debug.Log("FACES: " + objloadermesh.faces.Count.ToString()); m_btmesh = DataGenUtils.BulletMeshFromUnity(objloadermesh); Debug.Assert(m_btmesh.vertices.Length > 0); Debug.Assert(m_btmesh.indices.Length > 0); // Debug.Log("btVERTS: " + (btmesh.vertices.Length / 3).ToString()); // Debug.Log("btFACES: " + (btmesh.indices.Length / 3).ToString()); // Create a GImpactMeshShape for collider var triVtxarray = new TriangleIndexVertexArray(m_btmesh.indices, m_btmesh.vertices); m_cs = new GImpactMeshShape(triVtxarray); m_cs.LocalScaling = new BulletSharp.Math.Vector3(1); m_cs.Margin = bodyMargin; m_cs.UpdateBound(); AddCollisionShape(m_cs); // move it up so resting on the ground plane float miny = float.MaxValue; float cury; for (int i = 0; i < objloadermesh.vertices.Count; i++) { cury = objloadermesh.vertices[i][1]; if (cury < miny) { miny = cury; } } miny = -miny; m_rbInitTransVec = new BulletSharp.Math.Vector3(0, miny + bodyMargin + m_groundMargin, 0); m_rbInitTrans = Matrix.Translation(m_rbInitTransVec); // * Matrix.RotationY(Random.Range(0.0f, 360.0f)); m_rb = CreateRigidBody(mass, inertia, m_rbInitTrans, m_cs, bodyMat, bodyFriction, viz: RENDER_MODE); m_rb.AngularFactor = angularFactor; m_rb.SetSleepingThresholds(linearSleepThresh, angularSleepThresh); if (DEBUG) { Debug.Log("LOADED MOMENT: " + m_rb.LocalInertia.ToString()); } // if (DEBUG) Debug.Log("WORLD MOMENT: " + m_rb.InvInertiaTensorWorld.ToString()); // Debug.Log("Min y: " + (-miny).ToString()); if (DEBUG) { Debug.Log(m_rb.CenterOfMassPosition.ToString()); } }
protected override void OnInitialize() { Freelook.SetEyeTarget(eye, target); Graphics.SetFormText("BulletSharp - Concave Convexcast Demo"); Graphics.SetInfoText("Move using mouse and WASD+shift\n" + "F3 - Toggle debug\n" + //"F11 - Toggle fullscreen\n" + "Space - Shoot box"); IsDebugDrawEnabled = false; DebugDrawMode = debugMode; const int totalVerts = NumVertsX * NumVertsY; const int totalTriangles = 2 * (NumVertsX - 1) * (NumVertsY - 1); indexVertexArrays = new TriangleIndexVertexArray(); IndexedMesh mesh = new IndexedMesh(); mesh.NumTriangles = totalTriangles; mesh.NumVertices = totalVerts; mesh.TriangleIndexStride = 3 * sizeof(int); mesh.VertexStride = Vector3.SizeInBytes; mesh.TriangleIndexBase = Marshal.AllocHGlobal(mesh.TriangleIndexStride * totalTriangles); mesh.VertexBase = Marshal.AllocHGlobal(mesh.VertexStride * totalVerts); var indicesStream = mesh.GetTriangleStream(); var indices = new BinaryWriter(indicesStream); for (int i = 0; i < NumVertsX - 1; i++) { for (int j = 0; j < NumVertsY - 1; j++) { indices.Write(j * NumVertsX + i); indices.Write(j * NumVertsX + i + 1); indices.Write((j + 1) * NumVertsX + i + 1); indices.Write(j * NumVertsX + i); indices.Write((j + 1) * NumVertsX + i + 1); indices.Write((j + 1) * NumVertsX + i); } } indices.Dispose(); indexVertexArrays.AddIndexedMesh(mesh); convexcastBatch = new ConvexcastBatch(40.0f, 0.0f, -10.0f, 80.0f); //convexcastBatch = new ConvexcastBatch(true, 40.0f, -50.0f, 50.0f); }
public void InitGImpactCollision() { /// Create Torus Shape { m_indexVertexArrays = new TriangleIndexVertexArray(DemoMeshes.TORUS_NUM_TRIANGLES, DemoMeshes.gTorusIndices, 3, DemoMeshes.TORUS_NUM_VERTICES, DemoMeshes.gTorusVertices, 3); #if BULLET_GIMPACT_CONVEX_DECOMPOSITION btGImpactConvexDecompositionShape *trimesh = new btGImpactConvexDecompositionShape( m_indexVertexArrays, IndexedVector3(1.f, 1.f, 1.f), btScalar(0.01)); trimesh->setMargin(0.07); trimesh->updateBound(); #else //GImpactMeshShape trimesh = new GImpactMeshShape(m_indexVertexArrays); //IndexedVector3 scaling = IndexedVector3.One; //trimesh.SetLocalScaling(ref scaling); //trimesh.SetMargin(0.07f); ///????? //trimesh.UpdateBound(); #endif //m_trimeshShape = trimesh; } /// Create Bunny Shape { m_indexVertexArrays2 = new TriangleIndexVertexArray(DemoMeshes.BUNNY_NUM_TRIANGLES, DemoMeshes.gBunnyIndices, 3, DemoMeshes.BUNNY_NUM_VERTICES, DemoMeshes.gBunnyVertices, 3); #if BULLET_GIMPACT_CONVEX_DECOMPOSITION btGImpactConvexDecompositionShape *trimesh2 = new btGImpactConvexDecompositionShape( m_indexVertexArrays2, IndexedVector3(4.f, 4.f, 4.f), btScalar(0.01)); trimesh2->setMargin(0.07); trimesh2->updateBound(); #else GImpactMeshShape trimesh2 = new GImpactMeshShape(m_indexVertexArrays2); IndexedVector3 scaling = new IndexedVector3(4.0f, 4.0f, 4.0f); trimesh2.SetLocalScaling(ref scaling); //trimesh2.SetMargin(0.07f); ///????? trimesh2.UpdateBound(); #endif m_trimeshShape2 = trimesh2; } ///register GIMPACT algorithm CollisionDispatcher dispatcher = m_dynamicsWorld.GetDispatcher() as CollisionDispatcher; GImpactCollisionAlgorithm.RegisterAlgorithm(dispatcher); }
private void CreateGround() { const int totalVerts = NumVertsX * NumVertsY; const int totalTriangles = 2 * (NumVertsX - 1) * (NumVertsY - 1); const int triangleIndexStride = 3 * sizeof(int); const int vertexStride = Vector3.SizeInBytes; var mesh = new IndexedMesh(); mesh.Allocate(totalTriangles, totalVerts, triangleIndexStride, vertexStride); var indicesStream = mesh.GetTriangleStream(); using (var indices = new BinaryWriter(indicesStream)) { for (int x = 0; x < NumVertsX - 1; x++) { for (int y = 0; y < NumVertsY - 1; y++) { int row1Index = x * NumVertsX + y; int row2Index = row1Index + NumVertsX; indices.Write(row1Index); indices.Write(row1Index + 1); indices.Write(row2Index + 1); indices.Write(row1Index); indices.Write(row2Index + 1); indices.Write(row2Index); } } } indexVertexArrays = new TriangleIndexVertexArray(); indexVertexArrays.AddIndexedMesh(mesh); SetVertexPositions(waveHeight, 0.0f); const bool useQuantizedAabbCompression = true; groundShape = new BvhTriangleMeshShape(indexVertexArrays, useQuantizedAabbCompression); CollisionShapes.Add(groundShape); staticBody = LocalCreateRigidBody(0.0f, Matrix.Identity, groundShape); staticBody.CollisionFlags |= CollisionFlags.StaticObject; staticBody.UserObject = "Ground"; }
private void CreateGround() { const int totalVerts = NumVertsX * NumVertsY; const int totalTriangles = 2 * (NumVertsX - 1) * (NumVertsY - 1); const int triangleIndexStride = 3 * sizeof(int); indexVertexArrays = new TriangleIndexVertexArray(); var mesh = new IndexedMesh(); mesh.Allocate(totalTriangles, totalVerts, triangleIndexStride, Vector3.SizeInBytes, PhyScalarType.Int32, PhyScalarType.Single); DataStream indices = mesh.LockIndices(); for (int x = 0; x < NumVertsX - 1; x++) { for (int y = 0; y < NumVertsY - 1; y++) { int row1Index = x * NumVertsX + y; int row2Index = row1Index + NumVertsX; indices.Write(row1Index); indices.Write(row1Index + 1); indices.Write(row2Index + 1); indices.Write(row1Index); indices.Write(row2Index + 1); indices.Write(row2Index); } } indices.Dispose(); indexVertexArrays = new TriangleIndexVertexArray(); indexVertexArrays.AddIndexedMesh(mesh); SetVertexPositions(WaveHeight, 0.0f); const bool useQuantizedAabbCompression = true; groundShape = new BvhTriangleMeshShape(indexVertexArrays, useQuantizedAabbCompression); staticBody = LocalCreateRigidBody(0.0f, Matrix.Identity, groundShape); staticBody.CollisionFlags |= CollisionFlags.StaticObject; staticBody.UserObject = "Ground"; }
protected override void OnInitialize() { Freelook.SetEyeTarget(eye, target); Graphics.SetFormText("BulletSharp - Concave Raycast Demo"); Graphics.SetInfoText("Move using mouse and WASD+shift\n" + "F3 - Toggle debug\n" + //"F11 - Toggle fullscreen\n" + "Space - Shoot box"); DebugDrawMode = debugMode; const int totalVerts = NUM_VERTS_X * NUM_VERTS_Y; const int totalTriangles = 2 * (NUM_VERTS_X - 1) * (NUM_VERTS_Y - 1); indexVertexArrays = new TriangleIndexVertexArray(); IndexedMesh mesh = new IndexedMesh(); mesh.Allocate(totalVerts, Vector3.SizeInBytes, totalTriangles, 3 * sizeof(int)); DataStream indices = mesh.LockIndices(); for (int i = 0; i < NUM_VERTS_X - 1; i++) { for (int j = 0; j < NUM_VERTS_Y - 1; j++) { indices.Write(j * NUM_VERTS_X + i); indices.Write(j * NUM_VERTS_X + i + 1); indices.Write((j + 1) * NUM_VERTS_X + i + 1); indices.Write(j * NUM_VERTS_X + i); indices.Write((j + 1) * NUM_VERTS_X + i + 1); indices.Write((j + 1) * NUM_VERTS_X + i); } } indices.Dispose(); indexVertexArrays.AddIndexedMesh(mesh); raycastBar = new RaycastBar(4000.0f, 0.0f); //raycastBar = new RaycastBar(true, 40.0f, -50.0f, 50.0f); }
public IGImpactMeshShapeImp AddGImpactMeshShape(int[] meshTriangles, float3[] meshVertices) { Vector3[] btMeshVertices = new Vector3[meshVertices.Length]; for (int i = 0; i < meshVertices.Length; i++) { btMeshVertices[i].X = meshVertices[i].x; btMeshVertices[i].Y = meshVertices[i].y; btMeshVertices[i].Z = meshVertices[i].z; } var btTriangleIndexVertexArray = new TriangleIndexVertexArray(meshTriangles, btMeshVertices); var btGimpactMeshShape = new GImpactMeshShape(btTriangleIndexVertexArray); btGimpactMeshShape.UpdateBound(); BtCollisionShapes.Add(btGimpactMeshShape); var retval = new GImpactMeshShapeImp(); retval.BtGImpactMeshShape = btGimpactMeshShape; btGimpactMeshShape.UserObject = retval; return(retval); }
public CollisionShape BuildCorner() { // slope. IndexedVector3[] vertices = new IndexedVector3[] { new IndexedVector3(0, 0, 0), new IndexedVector3(1, 0, 0), new IndexedVector3(0, 0, 1), new IndexedVector3(1, 0, 1), new IndexedVector3(0, 1, 0), new IndexedVector3(1, 1, 0), new IndexedVector3(0, 1, 1), new IndexedVector3(1, 1, 1) }; //int[] indices = new int[] { 0, 4, 5, 4, 6, 7, 7, 5, 4, 0, 4, 6, 6, 2, 0, 2, 6, 7, 4,5,0,2,2,7,5}; //int[] indices = new int[] { 0, 4, 5, 4, 6, 7, 7, 5, 4, 6, 4,0,0,2,6, 7, 6, 2, 4, 5, 0, 2, 2, 7, 5 }; int[] indices = new int[] { 1, 4, 5, 1, 5, 7, 7, 3, 1, 3, 7, 6, 7, 5, 4, 4, 6, 7, 4, 1, 3, 3, 6, 4 }; int vertStride = 1; int indexStride = 3; ObjectArray <IndexedVector3> vertexArray = new ObjectArray <IndexedVector3>(); for (int i = 0; i < vertices.Length; ++i) { vertexArray.Add(vertices[i]); } ObjectArray <int> intArray = new ObjectArray <int>(); for (int i = 0; i < indices.Length; ++i) { intArray.Add(indices[i]); } TriangleIndexVertexArray indexVertexArray = new TriangleIndexVertexArray(indices.Length / 3, intArray, indexStride, vertexArray.Count, vertexArray, vertStride); TriangleMeshShape triangleMesh = new TriangleMeshShape(indexVertexArray); //TriangleMeshShape triangleMesh = new BvhTriangleMeshShape(indexVertexArray,true,true); return(triangleMesh); }
public GImpactTestDemoSimulation() { CollisionConfiguration = new DefaultCollisionConfiguration(); Dispatcher = new CollisionDispatcher(CollisionConfiguration); //Broadphase = new SimpleBroadphase(); Broadphase = new AxisSweep3_32Bit(new Vector3(-10000, -10000, -10000), new Vector3(10000, 10000, 10000), 1024); World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, null, CollisionConfiguration); GImpactCollisionAlgorithm.RegisterAlgorithm(Dispatcher); _torusShapeData = new TriangleIndexVertexArray(Torus.Indices, Torus.Vertices); _torusShape = CreateGImpactShape(_torusShapeData); _bunnyShapeData = new TriangleIndexVertexArray(Bunny.Indices, Bunny.Vertices); _bunnyShape = CreateGImpactShape(_bunnyShapeData); CreateStaticScene(); CreateTorusChain(); CreateBoxes(); }
public MeshCollider(GameObject obj) { gameObject = obj; MeshIndices.AddRange(gameObject.GetMeshRender()._mesh._indices); for (int i = 0; i < gameObject.GetMeshRender()._mesh._vertices.Length; i += 3) { Vector3 pos = new Vector3(gameObject.GetMeshRender()._mesh._vertices[i], gameObject.GetMeshRender()._mesh._vertices[i + 1], gameObject.GetMeshRender()._mesh._vertices[i + 2]); MeshVertices.Add(pos); } //ANTIGO ANTIGO ANTIGO // Initialize TriangleIndexVertexArray with float array /*indexVertexArray = new TriangleIndexVertexArray(MeshIndices.ToArray(), MeshVertices.ToArray()); * gImpactMeshShape = new GImpactMeshShape(indexVertexArray); * gImpactMeshShape.CalculateLocalInertia(1.0f); * gImpactMesh = CreateBody(1.0f, gImpactMeshShape, Vector3.Zero);*/ indexVertexArray2 = new TriangleIndexVertexArray(MeshIndices.ToArray(), MeshVertices.ToArray()); triangleMeshShape = new BvhTriangleMeshShape(indexVertexArray2, true); _collisionObject = new CollisionObject(); _collisionObject.WorldTransform = gameObject._transform.RotationMatrix * gameObject._transform.PositionMatrix * Matrix4.CreateScale(gameObject._transform.Size); _collisionObject.CollisionShape = triangleMeshShape; //TestTriangleArray(indexVertexArray); //TestTriangleArray(indexVertexArray2); Vector3 aabbMin, aabbMax; //gImpactMeshShape.GetAabb(Matrix4.Identity, out aabbMin, out aabbMax); triangleMeshShape.GetAabb(Matrix4.Identity, out aabbMin, out aabbMax); Physics.AddCollisionObject(_collisionObject); }
public static CollisionShape BuildCorner(IndexedVector3[] vertices, int[] indices) { int vertStride = 1; int indexStride = 3; ObjectArray <IndexedVector3> vertexArray = new ObjectArray <IndexedVector3>(); for (int i = 0; i < vertices.Length; ++i) { vertexArray.Add(vertices[i]); } ObjectArray <int> intArray = new ObjectArray <int>(); for (int i = 0; i < indices.Length; ++i) { intArray.Add(indices[i]); } TriangleIndexVertexArray indexVertexArray = new TriangleIndexVertexArray(indices.Length / 3, intArray, indexStride, vertexArray.Count, vertexArray, vertStride); TriangleMeshShape triangleMesh = new TriangleMeshShape(indexVertexArray); return(triangleMesh); }
public void SetScene(OpenTK.Mathematics.Vector3[] mesh, int[] indexes, OpenTK.Mathematics.Matrix4 startTransform) { //convert openTK to BulentSharp var meshP = new Vector3[mesh.Length]; for (int i = 0; i < mesh.Length; i++) { meshP[i] = mesh[i].Convert(); } TriangleIndexVertexArray triangles = new TriangleIndexVertexArray(indexes, meshP); CollisionShape shape = new BvhTriangleMeshShape(triangles, true); shape.CalculateLocalInertia(0); RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(0, new DefaultMotionState(startTransform.Convert()), shape, Vector3.Zero); RigidBody Body = new RigidBody(rbInfo); Body.CollisionFlags = CollisionFlags.StaticObject; Body.UserObject = "Ground"; Body.UserIndex = 10; World.AddRigidBody(Body, CollisionFilterGroups.StaticFilter, CollisionFilterGroups.CharacterFilter); /* * const float staticMass = 0; * RigidBody body; * CollisionShape shape = new TriangleMesh() * Matrix groundTransform = Matrix.Translation(0, -0.5f, 0); * using (var rbInfo = new RigidBodyConstructionInfo(staticMass, null, shape) * { * StartWorldTransform = groundTransform, * }) * { * body = new RigidBody(rbInfo); * } * World.AddRigidBody(body, CollisionFilterGroups.StaticFilter, CollisionFilterGroups.AllFilter); */ }
public Physics(VehicleDemo game) { CollisionShape groundShape = new BoxShape(50, 3, 50); CollisionShapes.Add(groundShape); CollisionConf = new DefaultCollisionConfiguration(); Dispatcher = new CollisionDispatcher(CollisionConf); Solver = new SequentialImpulseConstraintSolver(); Vector3 worldMin = new Vector3(-10000, -10000, -10000); Vector3 worldMax = new Vector3(10000, 10000, 10000); Broadphase = new AxisSweep3(worldMin, worldMax); //Broadphase = new DbvtBroadphase(); World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf); int i; Matrix tr; Matrix vehicleTr; if (UseTrimeshGround) { const float scale = 20.0f; //create a triangle-mesh ground int vertStride = Vector3.SizeInBytes; int indexStride = 3 * sizeof(int); const int NUM_VERTS_X = 20; const int NUM_VERTS_Y = 20; const int totalVerts = NUM_VERTS_X * NUM_VERTS_Y; const int totalTriangles = 2 * (NUM_VERTS_X - 1) * (NUM_VERTS_Y - 1); TriangleIndexVertexArray vertexArray = new TriangleIndexVertexArray(); IndexedMesh mesh = new IndexedMesh(); mesh.Allocate(totalVerts, vertStride, totalTriangles, indexStride, PhyScalarType.Int32, PhyScalarType.Single); BulletSharp.DataStream data = mesh.LockVerts(); for (i = 0; i < NUM_VERTS_X; i++) { for (int j = 0; j < NUM_VERTS_Y; j++) { float wl = .2f; float height = 20.0f * (float)(Math.Sin(i * wl) * Math.Cos(j * wl)); data.Write((i - NUM_VERTS_X * 0.5f) * scale); data.Write(height); data.Write((j - NUM_VERTS_Y * 0.5f) * scale); } } int index = 0; IntArray idata = mesh.TriangleIndices; for (i = 0; i < NUM_VERTS_X - 1; i++) { for (int j = 0; j < NUM_VERTS_Y - 1; j++) { idata[index++] = j * NUM_VERTS_X + i; idata[index++] = j * NUM_VERTS_X + i + 1; idata[index++] = (j + 1) * NUM_VERTS_X + i + 1; idata[index++] = j * NUM_VERTS_X + i; idata[index++] = (j + 1) * NUM_VERTS_X + i + 1; idata[index++] = (j + 1) * NUM_VERTS_X + i; } } vertexArray.AddIndexedMesh(mesh); groundShape = new BvhTriangleMeshShape(vertexArray, true); tr = Matrix.Identity; vehicleTr = Matrix.Translation(0, -2, 0); } else { // Use HeightfieldTerrainShape int width = 40, length = 40; //int width = 128, length = 128; // Debugging is too slow for this float maxHeight = 10.0f; float heightScale = maxHeight / 256.0f; Vector3 scale = new Vector3(20.0f, maxHeight, 20.0f); //PhyScalarType scalarType = PhyScalarType.PhyUChar; //FileStream file = new FileStream(heightfieldFile, FileMode.Open, FileAccess.Read); // Use float data PhyScalarType scalarType = PhyScalarType.Single; byte[] terr = new byte[width * length * 4]; MemoryStream file = new MemoryStream(terr); BinaryWriter writer = new BinaryWriter(file); for (i = 0; i < width; i++) { for (int j = 0; j < length; j++) { writer.Write((float)((maxHeight / 2) + 4 * Math.Sin(j * 0.5f) * Math.Cos(i))); } } writer.Flush(); file.Position = 0; HeightfieldTerrainShape heightterrainShape = new HeightfieldTerrainShape(width, length, file, heightScale, 0, maxHeight, upIndex, scalarType, false); heightterrainShape.SetUseDiamondSubdivision(true); groundShape = heightterrainShape; groundShape.LocalScaling = new Vector3(scale.X, 1, scale.Z); tr = Matrix.Translation(new Vector3(-scale.X / 2, scale.Y / 2, -scale.Z / 2)); vehicleTr = Matrix.Translation(new Vector3(20, 3, -3)); // Create graphics object file.Position = 0; BinaryReader reader = new BinaryReader(file); int totalTriangles = (width - 1) * (length - 1) * 2; int totalVerts = width * length; game.groundMesh = new Mesh(game.Device, totalTriangles, totalVerts, MeshFlags.SystemMemory | MeshFlags.Use32Bit, VertexFormat.Position | VertexFormat.Normal); SlimDX.DataStream data = game.groundMesh.LockVertexBuffer(LockFlags.None); for (i = 0; i < width; i++) { for (int j = 0; j < length; j++) { float height; if (scalarType == PhyScalarType.Single) { // heightScale isn't applied internally for float data height = reader.ReadSingle(); } else if (scalarType == PhyScalarType.Byte) { height = file.ReadByte() * heightScale; } else { height = 0.0f; } data.Write((j - length * 0.5f) * scale.X); data.Write(height); data.Write((i - width * 0.5f) * scale.Z); // Normals will be calculated later data.Position += 12; } } game.groundMesh.UnlockVertexBuffer(); file.Close(); data = game.groundMesh.LockIndexBuffer(LockFlags.None); for (i = 0; i < width - 1; i++) { for (int j = 0; j < length - 1; j++) { // Using diamond subdivision if ((j + i) % 2 == 0) { data.Write(j * width + i); data.Write((j + 1) * width + i + 1); data.Write(j * width + i + 1); data.Write(j * width + i); data.Write((j + 1) * width + i); data.Write((j + 1) * width + i + 1); } else { data.Write(j * width + i); data.Write((j + 1) * width + i); data.Write(j * width + i + 1); data.Write(j * width + i + 1); data.Write((j + 1) * width + i); data.Write((j + 1) * width + i + 1); } /* * // Not using diamond subdivision * data.Write(j * width + i); * data.Write((j + 1) * width + i); * data.Write(j * width + i + 1); * * data.Write(j * width + i + 1); * data.Write((j + 1) * width + i); * data.Write((j + 1) * width + i + 1); */ } } game.groundMesh.UnlockIndexBuffer(); game.groundMesh.ComputeNormals(); } CollisionShapes.Add(groundShape); //create ground object RigidBody ground = LocalCreateRigidBody(0, tr, groundShape); ground.UserObject = "Ground"; CollisionShape chassisShape = new BoxShape(1.0f, 0.5f, 2.0f); CollisionShapes.Add(chassisShape); CompoundShape compound = new CompoundShape(); CollisionShapes.Add(compound); //localTrans effectively shifts the center of mass with respect to the chassis Matrix localTrans = Matrix.Translation(Vector3.UnitY); compound.AddChildShape(localTrans, chassisShape); RigidBody carChassis = LocalCreateRigidBody(800, Matrix.Identity, compound); carChassis.UserObject = "Chassis"; //carChassis.SetDamping(0.2f, 0.2f); //CylinderShapeX wheelShape = new CylinderShapeX(wheelWidth, wheelRadius, wheelRadius); // clientResetScene(); // create vehicle RaycastVehicle.VehicleTuning tuning = new RaycastVehicle.VehicleTuning(); IVehicleRaycaster vehicleRayCaster = new DefaultVehicleRaycaster(World); vehicle = new RaycastVehicle(tuning, carChassis, vehicleRayCaster); carChassis.ActivationState = ActivationState.DisableDeactivation; World.AddAction(vehicle); float connectionHeight = 1.2f; bool isFrontWheel = true; // choose coordinate system vehicle.SetCoordinateSystem(rightIndex, upIndex, forwardIndex); Vector3 connectionPointCS0 = new Vector3(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, 2 * CUBE_HALF_EXTENTS - wheelRadius); WheelInfo a = vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel); connectionPointCS0 = new Vector3(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, 2 * CUBE_HALF_EXTENTS - wheelRadius); vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel); isFrontWheel = false; connectionPointCS0 = new Vector3(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, -2 * CUBE_HALF_EXTENTS + wheelRadius); vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel); connectionPointCS0 = new Vector3(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, -2 * CUBE_HALF_EXTENTS + wheelRadius); vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel); for (i = 0; i < vehicle.NumWheels; i++) { WheelInfo wheel = vehicle.GetWheelInfo(i); wheel.SuspensionStiffness = suspensionStiffness; wheel.WheelsDampingRelaxation = suspensionDamping; wheel.WheelsDampingCompression = suspensionCompression; wheel.FrictionSlip = wheelFriction; wheel.RollInfluence = rollInfluence; } vehicle.RigidBody.WorldTransform = vehicleTr; }
//----------------------------------------------------------------------------------------------- public override void InitializeDemo() { //string filename = @"C:\users\man\bullett\xna-concave-output.txt"; //FileStream filestream = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Read); //BulletGlobals.g_streamWriter = new StreamWriter(filestream); m_animatedMesh = true; base.InitializeDemo(); int totalTriangles = 2 * (NUM_VERTS_X - 1) * (NUM_VERTS_Y - 1); gVertices = new ObjectArray <IndexedVector3>(totalVerts); int indicesTotal = totalTriangles * 3; gIndices = new ObjectArray <int>(indicesTotal); //BulletGlobals.gContactAddedCallback = new CustomMaterialCombinerCallback(); SetVertexPositions(waveheight, 0f); int vertStride = 1; int indexStride = 3; int index = 0; for (int i = 0; i < NUM_VERTS_X - 1; i++) { for (int j = 0; j < NUM_VERTS_Y - 1; j++) { gIndices[index++] = j * NUM_VERTS_X + i; gIndices[index++] = j * NUM_VERTS_X + i + 1; gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1; gIndices[index++] = j * NUM_VERTS_X + i; gIndices[index++] = (j + 1) * NUM_VERTS_X + i + 1; gIndices[index++] = (j + 1) * NUM_VERTS_X + i; } } if (BulletGlobals.g_streamWriter != null) { index = 0; BulletGlobals.g_streamWriter.WriteLine("setIndexPositions"); for (int i = 0; i < gIndices.Count; i++) { BulletGlobals.g_streamWriter.WriteLine(String.Format("{0} {1}", i, gIndices[i])); } } TriangleIndexVertexArray indexVertexArrays = new TriangleIndexVertexArray(totalTriangles, gIndices, indexStride, totalVerts, gVertices, vertStride); bool useQuantizedAabbCompression = true; OptimizedBvh bvh = new OptimizedBvh(); IndexedVector3 aabbMin = new IndexedVector3(-1000, -1000, -1000); IndexedVector3 aabbMax = new IndexedVector3(1000, 1000, 1000); m_trimeshShape = new BvhTriangleMeshShape(indexVertexArrays, useQuantizedAabbCompression, ref aabbMin, ref aabbMax, true); //CollisionShape trimeshShape = new TriangleMeshShape(indexVertexArrays); IndexedVector3 scaling = IndexedVector3.One; //m_trimeshShape.SetOptimizedBvh(bvh, ref scaling); //BulletWorldImporter import = new BulletWorldImporter(0);//don't store info into the world //if (import.loadFile("myShape.bullet")) //{ // int numBvh = import.getNumBvhs(); // if (numBvh != 0) // { // OptimizedBvh bvh = import.getBvhByIndex(0); // IndexedVector3 aabbMin = new IndexedVector3(-1000,-1000,-1000); // IndexedVector3 aabbMax = new IndexedVector3(1000,1000,1000); // trimeshShape = new indexVertexArrays,useQuantizedAabbCompression,ref aabbMin,ref aabbMax,false); // IndexedVector3 scaling = IndexedVector3.One; // trimeshShape.setOptimizedBvh(bvh, ref scaling); // //trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax); // //trimeshShape.setOptimizedBvh(bvh); // } // int numShape = import.getNumCollisionShapes(); // if (numShape != 0) // { // trimeshShape = (BvhTriangleMeshShape)import.getCollisionShapeByIndex(0); // //if you know the name, you can also try to get the shape by name: // String meshName = import.getNameForPointer(trimeshShape); // if (meshName != null) // { // trimeshShape = (BvhTriangleMeshShape)import.getCollisionShapeByName(meshName); // } // } //} //CollisionShape groundShape = trimeshShape;//m_trimeshShape; CollisionShape groundShape = m_trimeshShape;//m_trimeshShape; //groundShape = new TriangleShape(new IndexedVector3(0,` 0, 100), new IndexedVector3(100, 0, 0),new IndexedVector3(-100, 0, -100)); //groundShape = new StaticPlaneShape(IndexedVector3.Up, 0f); //groundShape = new BoxShape(new IndexedVector3(100f, 0.1f, 100f)); IndexedVector3 up = new IndexedVector3(0.4f, 1, 0); up.Normalize(); //groundShape = new StaticPlaneShape(up, 0f); //groundShape = new TriangleMeshShape(indexVertexArrays); m_collisionConfiguration = new DefaultCollisionConfiguration(); m_dispatcher = new CollisionDispatcher(m_collisionConfiguration); IndexedVector3 worldMin = new IndexedVector3(-1000, -1000, -1000); IndexedVector3 worldMax = new IndexedVector3(1000, 1000, 1000); //m_broadphase = new AxisSweep3Internal(ref worldMin, ref worldMax, 0xfffe, 0xffff, 16384, null, false); m_broadphase = new DbvtBroadphase(); m_constraintSolver = new SequentialImpulseConstraintSolver(); m_dynamicsWorld = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_constraintSolver, m_collisionConfiguration); float mass = 0f; IndexedMatrix startTransform = IndexedMatrix.CreateTranslation(new IndexedVector3(2, -2, 0)); //CompoundShape colShape = new CompoundShape(); //IndexedVector3 halfExtents = new IndexedVector3(4, 1, 1); //CollisionShape cylinderShape = new CylinderShapeX(ref halfExtents); //CollisionShape boxShape = new BoxShape(new IndexedVector3(4, 1, 1)); //IndexedMatrix localTransform = IndexedMatrix.Identity; //colShape.addChildShape(ref localTransform, boxShape); //Quaternion orn = Quaternion.CreateFromYawPitchRoll(MathUtil.SIMD_HALF_PI, 0f, 0f); //localTransform = IndexedMatrix.CreateFromQuaternion(orn); //colShape.addChildShape(ref localTransform, cylinderShape); ////BoxShape colShape = new BoxShape(new IndexedVector3(1, 1, 1)); //int numCollideObjects = 1; //m_collisionShapes.Add(colShape); //{ // for (int i = 0; i < numCollideObjects; i++) // { // startTransform._origin = new IndexedVector3(4,10+i*2,1); // localCreateRigidBody(1, ref startTransform,colShape); // } //} CollisionShape boxShape = new BoxShape(new IndexedVector3(1, 1, 1)); //CollisionShape boxShape = new SphereShape(1); //CollisionShape boxShape = new SphereShape(1); //CollisionShape boxShape = new CapsuleShapeZ(0.5f, 1); m_collisionShapes.Add(boxShape); for (int i = 0; i < 1; i++) { startTransform._origin = new IndexedVector3(2f * i, 5, 1); LocalCreateRigidBody(1, ref startTransform, boxShape); } startTransform = IndexedMatrix.Identity; staticBody = LocalCreateRigidBody(mass, ref startTransform, groundShape); staticBody.SetCollisionFlags(staticBody.GetCollisionFlags() | CollisionFlags.CF_KINEMATIC_OBJECT); //STATIC_OBJECT); //enable custom material callback staticBody.SetCollisionFlags(staticBody.GetCollisionFlags() | CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK); //clientResetScene(); }
protected internal override CollisionShape CreateShape() { var epsilon = 0.0001f; //clear data processedVertices = null; processedIndices = null; processedTrianglesToSourceIndex = null; //get source geometry if (!GetSourceData(out var sourceVertices, out var sourceIndices)) { return(null); } //check valid data if (CheckValidData) { if (!MathAlgorithms.CheckValidVertexIndexBuffer(sourceVertices.Length, sourceIndices, false)) { Log.Info("Component_CollisionShape_Mesh: CreateShape: Invalid source data."); return(null); } } //process geometry if (MergeEqualVerticesRemoveInvalidTriangles) { //!!!!slowly. later use cached precalculated bullet shape. MathAlgorithms.MergeEqualVerticesRemoveInvalidTriangles(sourceVertices, sourceIndices, epsilon, out processedVertices, out processedIndices, out processedTrianglesToSourceIndex); } else { processedVertices = sourceVertices; processedIndices = sourceIndices; } //create bullet shape if (ShapeType.Value == ShapeTypeEnum.Auto && ParentRigidBody.MotionType.Value == Component_RigidBody.MotionTypeEnum.Dynamic && MathAlgorithms.IsMeshConvex(processedVertices, processedIndices, epsilon) || ShapeType.Value == ShapeTypeEnum.Convex) { if (MathAlgorithms.IsPlaneMesh(processedVertices, processedIndices, epsilon)) { Log.Info("Component_CollisionShape_Mesh: CreateShape: Unable to create shape as convex hull. All vertices on the one plane."); return(null); } //!!!!тут иначе? возможно лучше получить результирующие processed данные из буллета. как получить processedTrianglesToSourceIndex - это вопрос. возможно ли? //если нельзя то processedTrianglesToSourceIndex = new int[ 0 ]; - что означает нельзя сконвертировать. //если processedTrianglesToSourceIndex == null, то конвертация 1:1. try { ConvexHullAlgorithm.Create(processedVertices.ToVector3Array(), processedIndices, out var processedVertices2, out processedIndices); processedVertices = processedVertices2.ToVector3FArray(); //var convex = ConvexHullAlgorithm.Create( processedVertices, processedIndices ); //var vlist = new List<Vec3F>( convex.Faces.Length * 3 ); //foreach( var f in convex.Faces ) // for( int v = 0; v < f.Vertices.Length; v++ ) // vlist.Add( f.Vertices[ v ].ToVec3F() ); //processedVertices = vlist.ToArray(); //processedIndices = null; //BulletUtils.GetHullVertices( processedVertices.ToVec3Array(), processedIndices, out var processedVertices2, out processedIndices ); //processedVertices = processedVertices2.ToVec3FArray(); //BulletUtils.GetHullVertices( processedVertices, processedIndices, out processedVertices, out processedIndices ); //если нельзя то processedTrianglesToSourceIndex = new int[ 0 ]; - что означает нельзя сконвертировать. processedTrianglesToSourceIndex = Array.Empty <int>(); } catch (Exception e) { Log.Info("Component_CollisionShape_Mesh: CreateShape: Unable to create shape as convex hull. " + e.Message); return(null); } //!!!! var processedVerticesBullet = BulletPhysicsUtility.Convert(processedVertices); return(new ConvexHullShape(processedVerticesBullet)); } else { //!!!проверки на ошибки данных //!!!!can create without making of Vector3[] array. IntPtr constructor? internally the memory will copied? indexVertexArrays = new TriangleIndexVertexArray(processedIndices, BulletPhysicsUtility.Convert(processedVertices)); //indexVertexArrays = new TriangleIndexVertexArray(); //var indexedMesh = new IndexedMesh(); //indexedMesh.Allocate( totalTriangles, totalVerts, triangleIndexStride, vertexStride ); //indexedMesh SetData( ICollection<int> triangles, ICollection<Vector3> vertices ); //indexVertexArrays.AddIndexedMesh( indexedMesh ); //!!!!расшаривать данные которые тут. одинаковые в разных объектах //!!!!определять когда не считать кеш //It is better to use "useQuantizedAabbCompression=true", because it makes the tree data structure 4 times smaller: sizeof( btOptimizedBvhNode ) = 64 and sizeof( btQuantizedBvhNode ) = 16 bytes.Note that the number of AABB tree nodes is twice the number of triangles. //Instead of creating the tree on the XBox 360 console, it is better to deserialize it directly from disk to memory. See btOptimizedBvh::deSerializeInPlace in Demos/ConcaveDemo/ConcavePhysicsDemo.cpp //без useQuantizedAabbCompression в три раза быстрее создается //!!!!enable when cache support bool useQuantizedAabbCompression = false; //bool useQuantizedAabbCompression = true; bool buildBvh = true; //!!!!в другом конструкторе можно еще указать какие-то bound min max //public BvhTriangleMeshShape( StridingMeshInterface meshInterface, bool useQuantizedAabbCompression, Vector3 bvhAabbMin, Vector3 bvhAabbMax, bool buildBvh = true ); return(new BvhTriangleMeshShape(indexVertexArrays, useQuantizedAabbCompression, buildBvh)); } }
protected internal void CreateRigidBody(BulletXScene parent_scene, IMesh mesh, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 size) { //For RigidBody Constructor. The next values might change float _linearDamping = 0.0f; float _angularDamping = 0.0f; float _friction = 1.0f; float _restitution = 0.0f; Matrix _startTransform = Matrix.Identity; Matrix _centerOfMassOffset = Matrix.Identity; //added by jed zhu _mesh = mesh; lock (BulletXScene.BulletXLock) { _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos); //For now all prims are boxes CollisionShape _collisionShape; if (mesh == null) { _collisionShape = new BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size)/2.0f); } else { int iVertexCount = mesh.getVertexList().Count; int[] indices = mesh.getIndexListAsInt(); Vector3[] v3Vertices = new Vector3[iVertexCount]; for (int i = 0; i < iVertexCount; i++) { OpenMetaverse.Vector3 v = mesh.getVertexList()[i]; if (v != null) // Note, null has special meaning. See meshing code for details v3Vertices[i] = BulletXMaths.PhysicsVectorToXnaVector3(v); else v3Vertices[i] = Vector3.Zero; } TriangleIndexVertexArray triMesh = new TriangleIndexVertexArray(indices, v3Vertices); _collisionShape = new TriangleMeshShape(triMesh); } DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset); Vector3 _localInertia = new Vector3(); if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0 rigidBody = new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution); //rigidBody.ActivationState = ActivationState.DisableDeactivation; //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition Vector3 _vDebugTranslation; _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition; rigidBody.Translate(_vDebugTranslation); //--- parent_scene.ddWorld.AddRigidBody(rigidBody); } }
private void CreateTrimeshGround() { const float scale = 20.0f; //create a triangle-mesh ground const int NumVertsX = 20; const int NumVertsY = 20; const int totalVerts = NumVertsX * NumVertsY; const int totalTriangles = 2 * (NumVertsX - 1) * (NumVertsY - 1); _groundVertexArray = new TriangleIndexVertexArray(); _groundMesh = new IndexedMesh(); _groundMesh.Allocate(totalTriangles, totalVerts); _groundMesh.NumTriangles = totalTriangles; _groundMesh.NumVertices = totalVerts; _groundMesh.TriangleIndexStride = 3 * sizeof(int); _groundMesh.VertexStride = Vector3.SizeInBytes; using (var indicesStream = _groundMesh.GetTriangleStream()) { var indices = new BinaryWriter(indicesStream); for (int i = 0; i < NumVertsX - 1; i++) { for (int j = 0; j < NumVertsY - 1; j++) { indices.Write(j * NumVertsX + i); indices.Write(j * NumVertsX + i + 1); indices.Write((j + 1) * NumVertsX + i + 1); indices.Write(j * NumVertsX + i); indices.Write((j + 1) * NumVertsX + i + 1); indices.Write((j + 1) * NumVertsX + i); } } indices.Dispose(); } using (var vertexStream = _groundMesh.GetVertexStream()) { var vertices = new BinaryWriter(vertexStream); for (int i = 0; i < NumVertsX; i++) { for (int j = 0; j < NumVertsY; j++) { const float waveLength = .2f; float height = (float)(Math.Sin(i * waveLength) * Math.Cos(j * waveLength)); vertices.Write(i - NumVertsX * 0.5f); vertices.Write(height); vertices.Write(j - NumVertsY * 0.5f); } } vertices.Dispose(); } _groundVertexArray.AddIndexedMesh(_groundMesh); var groundShape = new BvhTriangleMeshShape(_groundVertexArray, true); var groundScaled = new ScaledBvhTriangleMeshShape(groundShape, new Vector3(scale)); RigidBody ground = PhysicsHelper.CreateStaticBody(Matrix.Identity, groundScaled, World); ground.UserObject = "Ground"; Matrix vehicleTransform = Matrix.Translation(0, -2, 0); CreateVehicle(vehicleTransform); }