// Used with soft bodies public void SetDynamicVertexBuffer(Device device, Vector3[] vectors) { if (VertexBuffer != null && VertexCount * 2 == vectors.Length) { DataBox db = device.ImmediateContext.MapSubresource(VertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None); SharpDX.Utilities.Write(db.DataPointer, vectors, 0, vectors.Length); device.ImmediateContext.UnmapSubresource(VertexBuffer, 0); } else { // Create new buffer if (VertexBuffer != null) VertexBuffer.Dispose(); BufferDescription vertexBufferDesc = new BufferDescription() { SizeInBytes = Vector3.SizeInBytes * vectors.Length, Usage = ResourceUsage.Dynamic, BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.Write }; using (var data = new DataStream(vertexBufferDesc.SizeInBytes, false, true)) { data.WriteRange(vectors); data.Position = 0; VertexBuffer = new Buffer(device, data, vertexBufferDesc); } VertexCount = vectors.Length / 2; BufferBindings[0] = new VertexBufferBinding(VertexBuffer, 24, 0); } }
public void SetVertexBuffer(Device device, Vector3[] vectors) { BufferDescription vertexBufferDesc = new BufferDescription() { SizeInBytes = Vector3.SizeInBytes * vectors.Length, Usage = ResourceUsage.Default, BindFlags = BindFlags.VertexBuffer }; using (var data = new DataStream(vertexBufferDesc.SizeInBytes, false, true)) { data.WriteRange(vectors); data.Position = 0; VertexBuffer = new Buffer(device, data, vertexBufferDesc); } BufferBindings[0] = new VertexBufferBinding(VertexBuffer, 24, 0); }
BulletSharp.RigidBody createRigidBody (BulletSharp.CollisionShape shape, UnityEngine.Transform transform, float mass) { Matrix4x4 unityMatrix = Matrix4x4.TRS (transform.position, transform.rotation, UnityEngine.Vector3.one); BulletSharp.Matrix bulletMatrix = new BulletSharp.Matrix ( unityMatrix.m00, unityMatrix.m10, unityMatrix.m20, unityMatrix.m30, unityMatrix.m01, unityMatrix.m11, unityMatrix.m21, unityMatrix.m31, unityMatrix.m02, unityMatrix.m12, unityMatrix.m22, unityMatrix.m32, unityMatrix.m03, unityMatrix.m13, unityMatrix.m23, unityMatrix.m33); BulletSharp.MotionState motionState = new BulletSharp.DefaultMotionState (bulletMatrix); BulletSharp.Vector3 inertia = new BulletSharp.Vector3 (0f, 0f, 0f); if (!Mathf.Approximately (mass, 0f)) { shape.CalculateLocalInertia (mass, out inertia); } BulletSharp.RigidBodyConstructionInfo myRigidBodyCI = new BulletSharp.RigidBodyConstructionInfo (mass, motionState, shape, inertia); BulletSharp.RigidBody myRigidBody = new BulletSharp.RigidBody (myRigidBodyCI); myRigidBodyCI.Dispose (); return myRigidBody; }
ShapeData CreateShape(CollisionShape shape) { ShapeData shapeData = new ShapeData(); uint[] indices; BulletSharp.Vector3[] vertexBuffer = CreateShape(shape, out indices); if (vertexBuffer != null) { shapeData.VertexCount = vertexBuffer.Length / 2; Vector3[] vertices = new Vector3[shapeData.VertexCount]; Vector3[] normals = new Vector3[shapeData.VertexCount]; int i; for (i = 0; i < shapeData.VertexCount; i++) { vertices[i] = vertexBuffer[i * 2]; normals[i] = vertexBuffer[i * 2 + 1]; } shapeData.SetVertexBuffer(vertices); shapeData.SetNormalBuffer(normals); } if (indices != null) { ushort[] indices_s = CompactIndexBuffer(indices); if (indices_s != null) { shapeData.SetIndexBuffer(indices_s); } else { shapeData.SetIndexBuffer(indices); } shapeData.ElementCount = indices.Length; } return(shapeData); }
void PlaneSpace1(BulletSharp.Vector3 n, out BulletSharp.Vector3 p, out BulletSharp.Vector3 q) { if (Math.Abs(n[2]) > (Math.Sqrt(2) / 2)) { // choose p in y-z plane float a = n[1] * n[1] + n[2] * n[2]; float k = 1.0f / (float)Math.Sqrt(a); p = new BulletSharp.Vector3(0, -n[2] * k, n[1] * k); // set q = n x p q = BulletSharp.Vector3.Cross(n, p); } else { // choose p in x-y plane float a = n[0] * n[0] + n[1] * n[1]; float k = 1.0f / (float)Math.Sqrt(a); p = new BulletSharp.Vector3(-n[1] * k, n[0] * k, 0); // set q = n x p q = BulletSharp.Vector3.Cross(n, p); } }
// Used with soft bodies public void SetDynamicVertexBuffer(Device device, Vector3[] vectors) { if (VertexBuffer != null && VertexCount * 2 == vectors.Length) { // Update existing buffer using (var data = VertexBuffer.Map(MapMode.WriteDiscard)) { data.WriteRange(vectors, 0, vectors.Length); VertexBuffer.Unmap(); } } else { // Create new buffer if (VertexBuffer != null) VertexBuffer.Dispose(); BufferDescription vertexBufferDesc = new BufferDescription() { SizeInBytes = Vector3.SizeInBytes * vectors.Length, Usage = ResourceUsage.Dynamic, BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.Write }; using (var data = new DataStream(vertexBufferDesc.SizeInBytes, false, true)) { data.WriteRange(vectors); data.Position = 0; VertexBuffer = new Buffer(device, data, vertexBufferDesc); } VertexCount = vectors.Length / 2; BufferBindings[0] = new VertexBufferBinding(VertexBuffer, 24, 0); } }
/// <summary> /// レイキャスト /// </summary> /// <param name="start">開始地点(ワールド座標)</param> /// <param name="end">終了地点(ワールド座標)</param> /// <param name="collideWith">コリジョン対象のビット列</param> /// <returns></returns> public IEnumerable<RaycastResult> RayCast(Vector3 start, Vector3 end, int collideWith = -1) { var from = new BulletSharp.Vector3 (start.X, start.Y, start.Z); var to = new BulletSharp.Vector3 (end.X, end.Y, end.Z); using (var result = new CollisionWorld.AllHitsRayResultCallback (from, to)) { result.CollisionFilterMask = (CollisionFilterGroups)collideWith; // BulletPhysics のレイキャスト wld.RayTest (from, to, result); if (!result.HasHit) { return new RaycastResult[0]; } var n = result.HitFractions.Count (); var results = new RaycastResult[n]; for (var i = 0; i < n; i++) { var frac = result.HitFractions[i]; var dist = frac * (start - end).Length; var node = ((CollisionObject)result.CollisionObjects[i].UserObject).Node; var point = result.HitPointWorld[i].ToDD (); var normal = result.HitNormalWorld[i].ToDD(); results[i] = new RaycastResult (frac, dist, node, point, normal); } return results.OrderBy (x => x.Fraction); } }
public void RenderSoftBody(SoftBody softBody) { Cull cullMode = device.GetRenderState <Cull>(RenderState.CullMode); device.SetRenderState(RenderState.CullMode, Cull.None); AlignedFaceArray faces = softBody.Faces; int faceCount = faces.Count; if (faceCount > 0) { PositionedNormal[] vectors = new PositionedNormal[faceCount * 6]; int v = 0; int i; for (i = 0; i < faceCount; i++) { NodePtrArray nodes = faces[i].N; Node n0 = nodes[0]; Node n1 = nodes[1]; Node n2 = nodes[2]; n0.GetX(out vectors[v].Position); n0.GetNormal(out vectors[v].Normal); n1.GetX(out vectors[v + 1].Position); n1.GetNormal(out vectors[v + 1].Normal); n2.GetX(out vectors[v + 2].Position); n2.GetNormal(out vectors[v + 2].Normal); v += 3; } device.VertexFormat = VertexFormat.PositionNormal; device.DrawUserPrimitives(PrimitiveType.TriangleList, faces.Count, vectors); } else { AlignedTetraArray tetras = softBody.Tetras; int tetraCount = tetras.Count; if (tetraCount > 0) { PositionedNormal[] vectors = new PositionedNormal[tetraCount * 12]; int v = 0; for (int i = 0; i < tetraCount; i++) { NodePtrArray nodes = tetras[i].Nodes; BulletSharp.Vector3 v0 = nodes[0].X; BulletSharp.Vector3 v1 = nodes[1].X; BulletSharp.Vector3 v2 = nodes[2].X; BulletSharp.Vector3 v3 = nodes[3].X; BulletSharp.Vector3 v10 = v1 - v0; BulletSharp.Vector3 v02 = v0 - v2; BulletSharp.Vector3 normal = BulletSharp.Vector3.Cross(v10, v02); normal.Normalize(); vectors[v].Position = v0; vectors[v].Normal = normal; vectors[v + 1].Position = v1; vectors[v + 1].Normal = normal; vectors[v + 2].Position = v2; vectors[v + 2].Normal = normal; normal = BulletSharp.Vector3.Cross(v10, v3 - v0); normal.Normalize(); vectors[v + 3].Position = v0; vectors[v + 3].Normal = normal; vectors[v + 4].Position = v1; vectors[v + 4].Normal = normal; vectors[v + 5].Position = v3; vectors[v + 5].Normal = normal; normal = BulletSharp.Vector3.Cross(v2 - v1, v3 - v1); normal.Normalize(); vectors[v + 6].Position = v1; vectors[v + 6].Normal = normal; vectors[v + 7].Position = v2; vectors[v + 7].Normal = normal; vectors[v + 8].Position = v3; vectors[v + 8].Normal = normal; normal = BulletSharp.Vector3.Cross(v02, v3 - v2); normal.Normalize(); vectors[v + 9].Position = v2; vectors[v + 9].Normal = normal; vectors[v + 10].Position = v0; vectors[v + 10].Normal = normal; vectors[v + 11].Position = v3; vectors[v + 11].Normal = normal; v += 12; } device.VertexFormat = VertexFormat.PositionNormal; device.DrawUserPrimitives(PrimitiveType.TriangleList, tetraCount * 4, vectors); } else if (softBody.Links.Count > 0) { AlignedLinkArray links = softBody.Links; int linkCount = links.Count; int linkColor = System.Drawing.Color.Black.ToArgb(); device.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse; PositionColored[] linkArray = new PositionColored[linkCount * 2]; for (int i = 0; i < linkCount; i++) { Link link = links[i]; linkArray[i * 2].Position = link.Nodes[0].X; linkArray[i * 2].Color = linkColor; linkArray[i * 2 + 1].Position = link.Nodes[1].X; linkArray[i * 2 + 1].Color = linkColor; } device.DrawUserPrimitives(PrimitiveType.LineList, links.Count, linkArray); } } device.SetRenderState(RenderState.CullMode, cullMode); }
/// <summary> /// Converts a Bullet vector. /// </summary> /// <param name="vector"></param> /// <returns></returns> public static OpenTK.Vector3 ToOpenTK(this BulletSharp.Vector3 vector) { return(new OpenTK.Vector3(vector.X, vector.Y, vector.Z)); }
public static Tuple <RigidBody, int> CreateRigidBody(this IRigidBodyContainer world, CollisionShape collisionShape, ref RigidBodyPose initialPose, ref RigidBodyProperties bodyProperties, ref BulletSharp.Vector3 localInertia, float mass, string customString) { DefaultMotionState motionState = new DefaultMotionState((BulletSharp.Matrix)initialPose); RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(mass, motionState, collisionShape, localInertia); constructionInfo.ApplyRigidBodyProperties(ref bodyProperties); RigidBody rigidBody = new RigidBody(constructionInfo); rigidBody.CollisionFlags = CollisionFlags.None; rigidBody.ApplyProperties(ref bodyProperties); BodyCustomData customData = new BodyCustomData(world.GetNewRigidBodyId()); customData.Custom = customString; rigidBody.UserObject = customData; world.Register(rigidBody); return(new Tuple <RigidBody, int>(rigidBody, customData.Id)); }
/// <summary> /// コリジョン形状1つに対するレイキャスト /// </summary> /// <param name="colA">キャスト対象のコリジョン オブジェクト</param> /// <param name="start">開始地点(ワールド座標)</param> /// <param name="end">終了地点(ワールド座標)</param> /// <returns>ヒットした時はその地点までの距離(0以上)の値、ヒットしなかった時は <see cref="Single.NaN"/>.</returns> public static float RayCast(CollisionObject colA, Vector3 start, Vector3 end) { var from = new BulletSharp.Vector3 (start.X, start.Y, start.Z); var to = new BulletSharp.Vector3 (end.X, end.Y, end.Z); var result = new CollisionWorld.ClosestRayResultCallback (from, to); colA.ghostObject.RayTest (from, to, result); if (!result.HasHit) { return Single.NaN; } return result.ClosestHitFraction * (end - start).Length; }