Ejemplo n.º 1
0
    /// <summary>
    /// Generates a convex hull collision mesh from the given original mesh.
    /// </summary>
    /// <param name="original"></param>
    /// <returns></returns>
    public static Mesh GenerateCollisionMesh(Mesh original, Vector3 offset = default(Vector3))
    {
        ConvexHullShape tempShape = new ConvexHullShape(Array.ConvertAll(original.vertices, x => x.ToBullet()), original.vertices.Length);

        tempShape.Margin = 0f;

        ShapeHull shapeHull = new ShapeHull(tempShape);
        bool      b         = shapeHull.BuildHull(0f);

        Mesh collisionMesh = new Mesh();

        Vector3[] vertices = new Vector3[shapeHull.NumVertices];
        for (int i = 0; i < vertices.Length; i++)
        {
            vertices[i] = shapeHull.Vertices[i].ToUnity() - offset;
        }

        int[] triangles = new int[shapeHull.NumIndices];
        for (int i = 0; i < triangles.Length; i++)
        {
            triangles[i] = (int)shapeHull.Indices[i];
        }

        collisionMesh.vertices  = vertices;
        collisionMesh.triangles = triangles;
        collisionMesh.RecalculateNormals();
        collisionMesh.RecalculateBounds();

        // TODO: Find a way to implement embedded margins. See https://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=2358

        return(collisionMesh);
    }
Ejemplo n.º 2
0
        public static void CreateConvexHull(ConvexHullShape shape, Mesh mesh)
        {
            ShapeHull hull = new ShapeHull(shape);

            hull.BuildHull(shape.Margin);

            int          vertexCount = hull.NumIndices;
            UIntArray    indices     = hull.Indices;
            Vector3Array points      = hull.Vertices;

            UnityEngine.Vector3[] vertices = new UnityEngine.Vector3[vertexCount];
            for (int i = 0; i < vertexCount; i++)
            {
                vertices[i] = points[(int)indices[i]].ToUnity();
            }
            int[] tris = new int[indices.Count];
            for (int i = 0; i < indices.Count; i++)
            {
                tris[i] = (int)indices[i];
            }
            mesh.vertices  = vertices;
            mesh.triangles = tris;
            mesh.RecalculateBounds();
            mesh.RecalculateNormals();
        }
Ejemplo n.º 3
0
        public override void SetupFromMesh(Mesh mesh)
        {
            var triMesh = new TriangleMesh();

            int i = 0;

            var vertices = mesh.Vertices;

            while (i < mesh.Indices.Length)
            {
                triMesh.AddTriangle(
                    vertices[mesh.Indices[i++]],
                    vertices[mesh.Indices[i++]],
                    vertices[mesh.Indices[i++]]
                    );
            }

            var tempShape = new ConvexTriangleMeshShape(triMesh);

            using var tempHull = new ShapeHull(tempShape);

            tempHull.BuildHull(tempShape.Margin);

            collisionShape = new ConvexHullShape(tempHull.Vertices);
        }
Ejemplo n.º 4
0
        public static Vector3[] CreateConvexHull(ConvexHullShape shape)
        {
            var hull = new ShapeHull(shape);

            hull.BuildHull(shape.Margin);

            int          vertexCount = hull.NumIndices;
            UIntArray    indices     = hull.Indices;
            Vector3Array points      = hull.Vertices;

            var vertices = new Vector3[vertexCount * 2];

            int v = 0;

            for (int i = 0; i < vertexCount; i += 3)
            {
                Vector3 v0 = points[(int)indices[i]];
                Vector3 v1 = points[(int)indices[i + 1]];
                Vector3 v2 = points[(int)indices[i + 2]];

                Vector3 v01    = v0 - v1;
                Vector3 v02    = v0 - v2;
                Vector3 normal = Vector3.Cross(v01, v02);
                normal.Normalize();

                vertices[v++] = v0;
                vertices[v++] = normal;
                vertices[v++] = v1;
                vertices[v++] = normal;
                vertices[v++] = v2;
                vertices[v++] = normal;
            }

            return(vertices);
        }
Ejemplo n.º 5
0
        public static void CreateConvexHull(ConvexHullShape shape, Mesh mesh)
        {
            ShapeHull hull = new ShapeHull(shape);

            hull.BuildHull(shape.Margin);

            List <UnityEngine.Vector3> verts = new List <UnityEngine.Vector3>();
            List <int> tris = new List <int>();

            //int vertexCount = hull.NumVertices;
            UIntArray    indices = hull.Indices;
            Vector3Array points  = hull.Vertices;

            for (int i = 0; i < indices.Count; i += 3)
            {
                verts.Add(points[(int)indices[i]].ToUnity());
                verts.Add(points[(int)indices[i + 1]].ToUnity());
                verts.Add(points[(int)indices[i + 2]].ToUnity());
                tris.Add(i);
                tris.Add(i + 1);
                tris.Add(i + 2);
            }

            mesh.vertices  = verts.ToArray();
            mesh.triangles = tris.ToArray();
            mesh.RecalculateBounds();
            mesh.RecalculateNormals();
        }
Ejemplo n.º 6
0
        private static void CreateHullGizmoMesh(ConvexHullShape shape, ref Mesh mesh)
        {
            if (mesh == null)
            {
                mesh = new Mesh();
            }
            else
            {
                mesh.Clear();
            }

            Vector3[] vertexBuffer;
            int[]     triangleBuffer;
            using (ShapeHull hull = new ShapeHull(shape)) {
                hull.BuildHull(0.0f);
                vertexBuffer = hull.Vertices
                               .Select(v => v.ToUnity())
                               .ToArray();

                triangleBuffer = hull.Indices
                                 .Select(i => (int)i)
                                 .ToArray();
            }

            MergeVertices(vertexBuffer, 0.05f);

            mesh.vertices  = vertexBuffer;
            mesh.triangles = triangleBuffer;
            mesh.RecalculateBounds();
            mesh.RecalculateNormals();
        }
Ejemplo n.º 7
0
        Mesh CreateConvexHullShape(ConvexHullShape shape)
        {
            ShapeHull hull = new ShapeHull(shape);

            hull.BuildHull(shape.Margin);

            UIntArray    hullIndices = hull.Indices;
            Vector3Array points      = hull.Vertices;


            int vertexCount = hull.NumIndices;
            int faceCount   = hull.NumTriangles;

            bool index32 = vertexCount > 65536;

            Mesh mesh = new Mesh(device, faceCount, vertexCount,
                                 MeshFlags.SystemMemory | (index32 ? MeshFlags.Use32Bit : 0), VertexFormat.Position | VertexFormat.Normal);


            SlimDX.DataStream indices = mesh.LockIndexBuffer(LockFlags.Discard);
            int i;

            if (index32)
            {
                for (i = 0; i < vertexCount; i++)
                {
                    indices.Write(i);
                }
            }
            else
            {
                for (i = 0; i < vertexCount; i++)
                {
                    indices.Write((short)i);
                }
            }
            mesh.UnlockIndexBuffer();

            SlimDX.DataStream verts = mesh.LockVertexBuffer(LockFlags.Discard);
            Vector3           scale = Vector3.Multiply(shape.LocalScaling, 1.0f + shape.Margin);

            for (i = 0; i < vertexCount; i += 3)
            {
                verts.Write(Vector3.Modulate(points[(int)hullIndices[i]], scale));
                verts.Position += 12;
                verts.Write(Vector3.Modulate(points[(int)hullIndices[i + 1]], scale));
                verts.Position += 12;
                verts.Write(Vector3.Modulate(points[(int)hullIndices[i + 2]], scale));
                verts.Position += 12;
            }
            mesh.UnlockVertexBuffer();

            mesh.ComputeNormals();
            shapes.Add(shape, mesh);

            return(mesh);
        }
Ejemplo n.º 8
0
        ShapeData CreateConvexHullShape(ConvexHullShape shape)
        {
            ConvexPolyhedron poly = shape.ConvexPolyhedron;

            if (poly != null)
            {
                throw new NotImplementedException();
            }

            ShapeHull hull = new ShapeHull(shape);

            hull.BuildHull(shape.Margin);

            int          indexCount = hull.NumIndices;
            UIntArray    indices    = hull.Indices;
            Vector3Array points     = hull.Vertices;

            ShapeData shapeData = new ShapeData();

            shapeData.VertexCount = indexCount;

            Vector3[] vertices = new Vector3[indexCount * 2];

            int v = 0, i;

            for (i = 0; i < indexCount; i += 3)
            {
                Vector3 v0 = points[(int)indices[i]];
                Vector3 v1 = points[(int)indices[i + 1]];
                Vector3 v2 = points[(int)indices[i + 2]];

                Vector3 v01    = v0 - v1;
                Vector3 v02    = v0 - v2;
                Vector3 normal = Vector3.Cross(v01, v02);
                normal.Normalize();

                vertices[v++] = v0;
                vertices[v++] = normal;
                vertices[v++] = v1;
                vertices[v++] = normal;
                vertices[v++] = v2;
                vertices[v++] = normal;
            }

            shapeData.SetVertexBuffer(device, vertices);

            return(shapeData);
        }
Ejemplo n.º 9
0
 private ConvexHullShape CreateHullApproximation(TriangleMesh triangleMesh)
 {
     using (var tmpConvexShape = new ConvexTriangleMeshShape(triangleMesh))
     {
         using (var hull = new ShapeHull(tmpConvexShape))
         {
             hull.BuildHull(tmpConvexShape.Margin);
             var convexShape = new ConvexHullShape(hull.Vertices);
             if (_enableSat)
             {
                 convexShape.InitializePolyhedralFeatures();
             }
             return(convexShape);
         }
     }
 }
Ejemplo n.º 10
0
        private static CollisionShape loadConvexHull(Mesh mesh, Vector3 scale)
        {
            TriangleMesh trimesh = new TriangleMesh();

            // Shift vertices in so margin is not visible
            Vector3 shift = Vector3.Normalize(scale) - new Vector3(0.04f);

            for (int i = 0; i < mesh.submeshes[0].vertex_data.Length; i += 3)
            {
                int index0 = (int)mesh.submeshes[0].index_data[i];
                int index1 = (int)mesh.submeshes[0].index_data[i + 1];
                int index2 = (int)mesh.submeshes[0].index_data[i + 2];

                Vector3 vertex0 = new Vector3(mesh.submeshes[0].vertex_data[index0].position.X, mesh.submeshes[0].vertex_data[index0].position.Y, mesh.submeshes[0].vertex_data[index0].position.Z) * (scale);
                //vertex0 *= shift;
                Vector3 vertex1 = new Vector3(mesh.submeshes[0].vertex_data[index1].position.X, mesh.submeshes[0].vertex_data[index1].position.Y, mesh.submeshes[0].vertex_data[index1].position.Z) * (scale);
                //vertex1 *= shift;
                Vector3 vertex2 = new Vector3(mesh.submeshes[0].vertex_data[index2].position.X, mesh.submeshes[0].vertex_data[index2].position.Y, mesh.submeshes[0].vertex_data[index2].position.Z) * (scale);
                //vertex2 *= shift;

                trimesh.AddTriangle(vertex0, vertex1, vertex2);
            }
            ConvexShape tmpShape = new ConvexTriangleMeshShape(trimesh);

            ShapeHull hull   = new ShapeHull(tmpShape);
            float     margin = tmpShape.Margin;

            hull.BuildHull(margin);
            tmpShape.UserObject = hull;

            ConvexHullShape convexShape = new ConvexHullShape();

            foreach (Vector3 v in hull.Vertices)
            {
                convexShape.AddPoint(v);
            }

            hull.Dispose();
            tmpShape.Dispose();


            return(convexShape);
        }
Ejemplo n.º 11
0
        public IConvexHullShapeImp AddConvexHullShape(float3[] points, bool optimized)
        {
            var btPoints = new Vector3[points.Count()];

            for (int i = 0; i < btPoints.Count(); i++)
            {
                var point = Translater.Float3ToBtVector3(points[i]);
                btPoints[i] = point;
            }


            var btConvexHullShape = new ConvexHullShape(btPoints);

            //btConvexHullShape.LocalScaling = new Vector3(3, 3, 3);
            if (optimized == true)
            {
                var btShapeHull = new ShapeHull(btConvexHullShape);
                var margin      = btConvexHullShape.Margin;
                btShapeHull.BuildHull(margin);
                ConvexHullShape simplifiedConvexShape = new ConvexHullShape(btShapeHull.Vertices);

                BtCollisionShapes.Add(simplifiedConvexShape);

                var retval = new ConvexHullShapeImp();
                retval.BtConvexHullShape         = simplifiedConvexShape;
                simplifiedConvexShape.UserObject = retval;
                return(retval);
            }
            else
            {
                BtCollisionShapes.Add(btConvexHullShape);

                var retval = new ConvexHullShapeImp();
                retval.BtConvexHullShape     = btConvexHullShape;
                btConvexHullShape.UserObject = retval;
                return(retval);
            }
        }
Ejemplo n.º 12
0
    /// <summary>
    /// Generates a convex hull collision mesh from the given original mesh.
    /// </summary>
    /// <param name="original"></param>
    /// <returns></returns>
    public static Mesh GenerateCollisionMesh(Mesh original, Vector3 offset = default(Vector3), float margin = 0f)
    {
        if (margin > 0f)
        {
            ConvexHullShape tempShape = new ConvexHullShape(Array.ConvertAll(original.vertices, x => x.ToBullet()), original.vertices.Length);
            tempShape.Margin = 0f;

            ShapeHull shapeHull = new ShapeHull(tempShape);
            bool      b         = shapeHull.BuildHull(0f);

            AlignedVector3Array initialVertices = new AlignedVector3Array();
            for (int i = 0; i < shapeHull.NumVertices; i++)
            {
                initialVertices.Add(shapeHull.Vertices[i]);
            }

            List <BulletSharp.Math.Vector4> planeEquations = GeometryUtilEx.GetPlaneEquationsFromVertices(initialVertices);

            List <BulletSharp.Math.Vector4> shiftedPlaneEquations = new List <BulletSharp.Math.Vector4>();

            for (int i = 0; i < planeEquations.Count; i++)
            {
                BulletSharp.Math.Vector4 plane = planeEquations[i];
                plane.W += margin;
                shiftedPlaneEquations.Add(plane);
            }

            List <BulletSharp.Math.Vector3> shiftedVertices = GeometryUtilEx.GetVerticesFromPlaneEquations(shiftedPlaneEquations);

            Vector3[] finalVertices = new Vector3[shiftedVertices.Count];

            Mesh collisionMesh = new Mesh();

            for (int i = 0; i < finalVertices.Length; i++)
            {
                finalVertices[i] = shiftedVertices[i].ToUnity() - offset;
            }

            collisionMesh.vertices = finalVertices;
            collisionMesh.RecalculateBounds();

            return(collisionMesh);
        }
        else
        {
            ConvexHullShape tempShape = new ConvexHullShape(Array.ConvertAll(original.vertices, x => x.ToBullet()), original.vertices.Length);
            tempShape.Margin = 0f;

            ShapeHull shapeHull = new ShapeHull(tempShape);
            bool      b         = shapeHull.BuildHull(0f);

            Mesh collisionMesh = new Mesh();

            Vector3[] vertices = new Vector3[shapeHull.NumVertices];
            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = shapeHull.Vertices[i].ToUnity() - offset;
            }

            int[] triangles = new int[shapeHull.NumIndices];
            for (int i = 0; i < triangles.Length; i++)
            {
                triangles[i] = (int)shapeHull.Indices[i];
            }

            collisionMesh.vertices  = vertices;
            collisionMesh.triangles = triangles;
            collisionMesh.RecalculateNormals();
            collisionMesh.RecalculateBounds();

            return(collisionMesh);
        }
    }
Ejemplo n.º 13
0
 public ShapeCache(ConvexShape s)
 {
     m_shapehull = new ShapeHull(s);
 }
Ejemplo n.º 14
0
        public void DrawXNA(ref IndexedMatrix m, CollisionShape shape, ref IndexedVector3 color, DebugDrawModes debugMode, ref IndexedVector3 worldBoundsMin, ref IndexedVector3 worldBoundsMax, ref IndexedMatrix view, ref IndexedMatrix projection)
        {
            //btglMultMatrix(m);
            if (shape == null)
            {
                return;
            }

            if (shape.GetShapeType() == BroadphaseNativeTypes.UNIFORM_SCALING_SHAPE_PROXYTYPE)
            {
                UniformScalingShape scalingShape = (UniformScalingShape)shape;
                ConvexShape         convexShape  = scalingShape.GetChildShape();
                float         scalingFactor      = scalingShape.GetUniformScalingFactor();
                IndexedMatrix scaleMatrix        = IndexedMatrix.CreateScale(scalingFactor);
                IndexedMatrix finalMatrix        = scaleMatrix * m;
                DrawXNA(ref finalMatrix, convexShape, ref color, debugMode, ref worldBoundsMin, ref worldBoundsMax, ref view, ref projection);
                return;
            }
            if (shape.GetShapeType() == BroadphaseNativeTypes.COMPOUND_SHAPE_PROXYTYPE)
            {
                CompoundShape compoundShape = (CompoundShape)shape;
                for (int i = compoundShape.GetNumChildShapes() - 1; i >= 0; i--)
                {
                    IndexedMatrix  childTrans = compoundShape.GetChildTransform(i);
                    CollisionShape colShape   = compoundShape.GetChildShape(i);
                    IndexedMatrix  childMat   = childTrans;

                    //childMat = MathUtil.bulletMatrixMultiply(m, childMat);
                    //childMat = childMat * m;
                    childMat = m * childMat;



                    DrawXNA(ref childMat, colShape, ref color, debugMode, ref worldBoundsMin, ref worldBoundsMax, ref view, ref projection);
                }
            }
            else
            {
                bool useWireframeFallback = true;

                if ((debugMode & DebugDrawModes.DBG_DrawWireframe) == 0)
                {
                    ///you can comment out any of the specific cases, and use the default
                    ///the benefit of 'default' is that it approximates the actual collision shape including collision margin
                    //BroadphaseNativeTypes shapetype = m_textureEnabled ? BroadphaseNativeTypes.MAX_BROADPHASE_COLLISION_TYPES : shape.getShapeType();
                    BroadphaseNativeTypes shapetype = shape.GetShapeType();
                    switch (shapetype)
                    {
                    case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE:
                    {
                        BoxShape       boxShape    = shape as BoxShape;
                        IndexedVector3 halfExtents = boxShape.GetHalfExtentsWithMargin();

                        DrawSolidCube(ref halfExtents, ref m, ref view, ref projection, ref color);
                        //drawSolidSphere(halfExtents.X, 10, 10, ref m, ref view, ref projection);
                        //drawCylinder(halfExtents.X, halfExtents.Y, 1, ref m, ref view, ref projection);
                        //drawSolidCone(halfExtents.Y, halfExtents.X, ref m, ref view, ref projection);

                        //DrawText("Hello World", new IndexedVector3(20, 20, 0), new IndexedVector3(255, 255, 255));
                        useWireframeFallback = false;
                        break;
                    }


                    case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE:
                    {
                        SphereShape sphereShape = shape as SphereShape;
                        float       radius      = sphereShape.GetMargin();//radius doesn't include the margin, so draw with margin
                        DrawSolidSphere(radius, 10, 10, ref m, ref view, ref projection, ref color);
                        //glutSolidSphere(radius,10,10);
                        useWireframeFallback = false;
                        break;
                    }

                    case BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE:
                    {
                        CapsuleShape capsuleShape = shape as CapsuleShape;

                        float radius     = capsuleShape.GetRadius();
                        float halfHeight = capsuleShape.GetHalfHeight();

                        int upAxis = capsuleShape.GetUpAxis();

                        IndexedVector3 capStart = IndexedVector3.Zero;
                        capStart[upAxis] = -halfHeight;

                        IndexedVector3 capEnd = IndexedVector3.Zero;
                        capEnd[upAxis] = halfHeight;

                        // Draw the ends
                        {
                            IndexedMatrix childTransform = IndexedMatrix.Identity;
                            childTransform._origin = m * capStart;
                            DrawSolidSphere(radius, 5, 5, ref childTransform, ref view, ref projection, ref color);
                        }

                        {
                            IndexedMatrix childTransform = IndexedMatrix.Identity;
                            childTransform._origin = m * capEnd;
                            DrawSolidSphere(radius, 5, 5, ref childTransform, ref view, ref projection, ref color);
                        }

                        DrawCylinder(radius, halfHeight, upAxis, ref m, ref view, ref projection, ref color);
                        break;
                    }

                    case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE:
                    {
                        ConeShape     coneShape    = (ConeShape)(shape);
                        int           upIndex      = coneShape.GetConeUpIndex();
                        float         radius       = coneShape.GetRadius(); //+coneShape.getMargin();
                        float         height       = coneShape.GetHeight(); //+coneShape.getMargin();
                        IndexedMatrix rotateMatrix = IndexedMatrix.Identity;


                        switch (upIndex)
                        {
                        case 0:
                            rotateMatrix = IndexedMatrix.CreateRotationX(-MathUtil.SIMD_HALF_PI);
                            break;

                        case 1:
                            break;

                        case 2:
                            rotateMatrix = IndexedMatrix.CreateRotationX(MathUtil.SIMD_HALF_PI);
                            break;

                        default:
                        {
                            break;
                        }
                        }
                        ;

                        IndexedMatrix translationMatrix = IndexedMatrix.CreateTranslation(0f, 0f, -0.5f * height);

                        IndexedMatrix resultant = m * rotateMatrix * translationMatrix;

                        DrawSolidCone(height, radius, ref resultant, ref view, ref projection, ref color);
                        useWireframeFallback = false;
                        break;
                    }


                    case BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE:
                    {
                        StaticPlaneShape staticPlaneShape = shape as StaticPlaneShape;
                        float            planeConst = staticPlaneShape.GetPlaneConstant();
                        IndexedVector3   planeNormal = staticPlaneShape.GetPlaneNormal();
                        IndexedVector3   planeOrigin = planeNormal * planeConst;
                        IndexedVector3   vec0, vec1;
                        TransformUtil.PlaneSpace1(ref planeNormal, out vec0, out vec1);
                        float          vecLen = 100f;
                        IndexedVector3 pt0 = planeOrigin + vec0 * vecLen;
                        IndexedVector3 pt1 = planeOrigin - vec0 * vecLen;
                        IndexedVector3 pt2 = planeOrigin + vec1 * vecLen;
                        IndexedVector3 pt3 = planeOrigin - vec1 * vecLen;

                        // Fallback to debug draw - needs tidying
                        IndexedVector3 colour = new IndexedVector3(255, 255, 255);
                        DrawLine(ref pt0, ref pt1, ref colour);
                        DrawLine(ref pt1, ref pt2, ref colour);
                        DrawLine(ref pt2, ref pt3, ref colour);
                        DrawLine(ref pt3, ref pt1, ref colour);

                        break;
                    }

                    case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE:
                    {
                        CylinderShape cylinder = (CylinderShape)(shape);
                        int           upAxis   = cylinder.GetUpAxis();

                        float radius     = cylinder.GetRadius();
                        float halfHeight = cylinder.GetHalfExtentsWithMargin()[upAxis];
                        DrawCylinder(radius, halfHeight, upAxis, ref m, ref view, ref projection, ref color);
                        break;
                    }

                    default:
                    {
                        if (shape.IsConvex())
                        {
                            ShapeCache sc = Cache(shape as ConvexShape);

                            //if (shape.getUserPointer())
                            {
                                //glutSolidCube(1.0);
                                ShapeHull hull = sc.m_shapehull /*(btShapeHull*)shape.getUserPointer()*/;

                                int numTriangles = hull.NumTriangles();
                                int numIndices   = hull.NumIndices();
                                int numVertices  = hull.NumVertices();
                                if (numTriangles > 0)
                                {
                                    int                    index = 0;
                                    IList <int>            idx   = hull.m_indices;
                                    IList <IndexedVector3> vtx   = hull.m_vertices;

                                    for (int i = 0; i < numTriangles; i++)
                                    {
                                        int i1 = index++;
                                        int i2 = index++;
                                        int i3 = index++;
                                        Debug.Assert(i1 < numIndices &&
                                                     i2 < numIndices &&
                                                     i3 < numIndices);

                                        int index1 = idx[i1];
                                        int index2 = idx[i2];
                                        int index3 = idx[i3];
                                        Debug.Assert(index1 < numVertices &&
                                                     index2 < numVertices &&
                                                     index3 < numVertices);

                                        IndexedVector3 v1     = m * vtx[index1];
                                        IndexedVector3 v2     = m * vtx[index2];
                                        IndexedVector3 v3     = m * vtx[index3];
                                        IndexedVector3 normal = IndexedVector3.Cross((v3 - v1), (v2 - v1));
                                        normal.Normalize();

                                        Vector2 tex = new Vector2(0, 0);
                                        AddVertex(ref v1, ref normal, ref tex);
                                        AddVertex(ref v2, ref normal, ref tex);
                                        AddVertex(ref v3, ref normal, ref tex);
                                    }
                                }
                            }
                        }
                        break;
                    }
                    }
                }

                /// for polyhedral shapes
                if (debugMode == DebugDrawModes.DBG_DrawFeaturesText && (shape.IsPolyhedral()))
                {
                    PolyhedralConvexShape polyshape = (PolyhedralConvexShape)shape;
                    {
                        //BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),polyshape.getExtraDebugInfo());

                        IndexedVector3 colour = new IndexedVector3(255, 255, 255);
                        for (int i = 0; i < polyshape.GetNumVertices(); i++)
                        {
                            IndexedVector3 vtx;
                            polyshape.GetVertex(i, out vtx);
                            String buf = " " + i;
                            DrawText(buf, ref vtx, ref colour);
                        }

                        for (int i = 0; i < polyshape.GetNumPlanes(); i++)
                        {
                            IndexedVector3 normal;
                            IndexedVector3 vtx;
                            polyshape.GetPlane(out normal, out vtx, i);
                            float d = IndexedVector3.Dot(vtx, normal);
                            vtx *= d;

                            String buf = " plane " + i;
                            DrawText(buf, ref vtx, ref colour);
                        }
                    }
                }

                if (shape.IsConcave() && !shape.IsInfinite())    //>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape.getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
                //		if (shape.getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
                {
                    ConcaveShape concaveMesh = shape as ConcaveShape;

                    XNADrawcallback drawCallback = new XNADrawcallback(this, ref m);
                    drawCallback.m_wireframe = (debugMode & DebugDrawModes.DBG_DrawWireframe) != 0;

                    concaveMesh.ProcessAllTriangles(drawCallback, ref worldBoundsMin, ref worldBoundsMax);
                }

                //glDisable(GL_DEPTH_TEST);
                //glRasterPos3f(0,0,0);//mvtx.x(),  vtx.y(),  vtx.z());
                if ((debugMode & DebugDrawModes.DBG_DrawText) != 0)
                {
                    IndexedVector3 position = IndexedVector3.Zero;
                    IndexedVector3 colour   = new IndexedVector3(255, 255, 255);
                    DrawText(shape.GetName(), ref position, ref colour);
                }

                if ((debugMode & DebugDrawModes.DBG_DrawFeaturesText) != 0)
                {
                    //drawText(shape.getEx]
                    //BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),shape.getExtraDebugInfo());
                }
                //glEnable(GL_DEPTH_TEST);

                ////	glPopMatrix();
                //if(m_textureenabled) glDisable(GL_TEXTURE_2D);
                //  }
                //    glPopMatrix();
            }
        }
Ejemplo n.º 15
0
        public virtual void     DrawShadow(ref IndexedMatrix m, ref IndexedVector3 extrusion, CollisionShape shape, ref IndexedVector3 worldBoundsMin, ref IndexedVector3 worldBoundsMax)
        {
            if (shape.GetShapeType() == BroadphaseNativeTypes.UNIFORM_SCALING_SHAPE_PROXYTYPE)
            {
                UniformScalingShape scalingShape = (UniformScalingShape)(shape);
                ConvexShape         convexShape  = scalingShape.GetChildShape();
                float         scalingFactor      = (float)scalingShape.GetUniformScalingFactor();
                IndexedMatrix tmpScaling         = IndexedMatrix.CreateScale(scalingFactor);
                tmpScaling *= m;
                DrawShadow(ref tmpScaling, ref extrusion, convexShape, ref worldBoundsMin, ref worldBoundsMax);

                return;
            }
            else if (shape.GetShapeType() == BroadphaseNativeTypes.COMPOUND_SHAPE_PROXYTYPE)
            {
                CompoundShape compoundShape = (CompoundShape)(shape);
                for (int i = compoundShape.GetNumChildShapes() - 1; i >= 0; i--)
                {
                    IndexedMatrix  childTrans = compoundShape.GetChildTransform(i);
                    CollisionShape colShape   = compoundShape.GetChildShape(i);
                    //float childMat[16];
                    //childTrans.getOpenGLMatrix(childMat);
                    IndexedVector3 transformedExtrude = childTrans._basis * extrusion;
                    DrawShadow(ref childTrans, ref transformedExtrude, colShape, ref worldBoundsMin, ref worldBoundsMax);
                }
            }
            else
            {
                bool useWireframeFallback = true;
                if (shape.IsConvex())
                {
                    ShapeCache sc   = Cache(shape as ConvexShape);
                    ShapeHull  hull = sc.m_shapehull;
                    //glBegin(GL_QUADS);
                    for (int i = 0; i < sc.m_edges.Count; ++i)
                    {
                        float d = IndexedVector3.Dot(sc.m_edges[i].n[0], extrusion);
                        if ((d * IndexedVector3.Dot(sc.m_edges[i].n[1], extrusion)) < 0)
                        {
                            int            q   = d < 0?1:0;
                            IndexedVector3 a   = hull.m_vertices[sc.m_edges[i].v[q]];
                            IndexedVector3 b   = hull.m_vertices[sc.m_edges[i].v[1 - q]];
                            IndexedVector3 ae  = a + extrusion;
                            IndexedVector3 be  = b + extrusion;
                            Vector2        tex = new Vector2(0, 0);
                            // fix me.
                            IndexedVector3 normal = new IndexedVector3(0, 1, 0);
                            // gl_quad turned into two triangles.
                            AddVertex(ref a, ref normal, ref tex);
                            AddVertex(ref b, ref normal, ref tex);
                            AddVertex(ref be, ref normal, ref tex);
                            AddVertex(ref be, ref normal, ref tex);
                            AddVertex(ref ae, ref normal, ref tex);
                            AddVertex(ref a, ref normal, ref tex);
                        }
                    }
                    //glEnd();
                }
            }

            if (shape.IsConcave())    //>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape.getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
            //		if (shape.getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
            {
                ConcaveShape concaveMesh = (ConcaveShape)shape;

                XNADrawcallback drawCallback = new XNADrawcallback(this, ref m);
                drawCallback.m_wireframe = false;

                concaveMesh.ProcessAllTriangles(drawCallback, ref worldBoundsMin, ref worldBoundsMax);
            }
            //glPopMatrix();
        }
        protected override void OnInitializePhysics()
        {
            ManifoldPoint.ContactAdded += MyContactCallback;

            SetupEmptyDynamicsWorld();

            CompoundCollisionAlgorithm.CompoundChildShapePairCallback = MyCompoundChildShapeCallback;
            convexDecompositionObjectOffset = new Vector3(10, 0, 0);


            // Load wavefront file
            var wo     = new WavefrontObj();
            int tcount = wo.LoadObj("data/file.obj");

            if (tcount == 0)
            {
                return;
            }

            // Convert file data to TriangleMesh
            var trimesh = new TriangleMesh();

            trimeshes.Add(trimesh);

            Vector3        localScaling = new Vector3(6, 6, 6);
            List <int>     indices      = wo.Indices;
            List <Vector3> vertices     = wo.Vertices;

            int i;

            for (i = 0; i < tcount; i++)
            {
                int index0 = indices[i * 3];
                int index1 = indices[i * 3 + 1];
                int index2 = indices[i * 3 + 2];

                Vector3 vertex0 = vertices[index0] * localScaling;
                Vector3 vertex1 = vertices[index1] * localScaling;
                Vector3 vertex2 = vertices[index2] * localScaling;

                trimesh.AddTriangleRef(ref vertex0, ref vertex1, ref vertex2);
            }

            // Create a hull approximation
            ConvexHullShape convexShape;

            using (var tmpConvexShape = new ConvexTriangleMeshShape(trimesh))
            {
                using (var hull = new ShapeHull(tmpConvexShape))
                {
                    hull.BuildHull(tmpConvexShape.Margin);
                    convexShape = new ConvexHullShape(hull.Vertices);
                }
            }
            if (sEnableSAT)
            {
                convexShape.InitializePolyhedralFeatures();
            }
            CollisionShapes.Add(convexShape);


            // Add non-moving body to world
            float mass = 1.0f;

            LocalCreateRigidBody(mass, Matrix.Translation(0, 2, 14), convexShape);

            const bool useQuantization = true;
            var        concaveShape    = new BvhTriangleMeshShape(trimesh, useQuantization);

            LocalCreateRigidBody(0, Matrix.Translation(convexDecompositionObjectOffset), concaveShape);

            CollisionShapes.Add(concaveShape);


            // HACD
            var hacd = new Hacd();

            hacd.SetPoints(wo.Vertices);
            hacd.SetTriangles(wo.Indices);
            hacd.CompacityWeight = 0.1;
            hacd.VolumeWeight    = 0.0;

            // Recommended HACD parameters: 2 100 false false false
            hacd.NClusters                = 2;       // minimum number of clusters
            hacd.Concavity                = 100;     // maximum concavity
            hacd.AddExtraDistPoints       = false;
            hacd.AddNeighboursDistPoints  = false;
            hacd.AddFacesPoints           = false;
            hacd.NumVerticesPerConvexHull = 100;     // max of 100 vertices per convex-hull

            hacd.Compute();
            hacd.Save("output.wrl", false);


            // Generate convex result
            var outputFile = new FileStream("file_convex.obj", FileMode.Create, FileAccess.Write);
            var writer     = new StreamWriter(outputFile);

            var convexDecomposition = new ConvexDecomposition(writer, this);

            convexDecomposition.LocalScaling = localScaling;

            for (int c = 0; c < hacd.NClusters; c++)
            {
                Vector3[] points;
                int[]     triangles;
                hacd.GetCH(c, out points, out triangles);

                convexDecomposition.ConvexDecompResult(points, triangles);
            }


            // Combine convex shapes into a compound shape
            var compound = new CompoundShape();

            for (i = 0; i < convexDecomposition.convexShapes.Count; i++)
            {
                Vector3 centroid     = convexDecomposition.convexCentroids[i];
                Matrix  trans        = Matrix.Translation(centroid);
                var     convexShape2 = convexDecomposition.convexShapes[i] as ConvexHullShape;
                if (sEnableSAT)
                {
                    convexShape2.InitializePolyhedralFeatures();
                }
                CollisionShapes.Add(convexShape2);
                compound.AddChildShape(trans, convexShape2);

                LocalCreateRigidBody(1.0f, trans, convexShape2);
            }
            CollisionShapes.Add(compound);

            writer.Dispose();
            outputFile.Dispose();

#if true
            mass = 10.0f;
            var body2 = LocalCreateRigidBody(mass, Matrix.Translation(-convexDecompositionObjectOffset), compound);
            body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;

            convexDecompositionObjectOffset.Z = 6;
            body2 = LocalCreateRigidBody(mass, Matrix.Translation(-convexDecompositionObjectOffset), compound);
            body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;

            convexDecompositionObjectOffset.Z = -6;
            body2 = LocalCreateRigidBody(mass, Matrix.Translation(-convexDecompositionObjectOffset), compound);
            body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;
#endif
        }
Ejemplo n.º 17
0
        protected override void OnInitializePhysics()
        {
            ManifoldPoint.ContactAdded += MyContactCallback;

            SetupEmptyDynamicsWorld();

            WavefrontObj wo     = new WavefrontObj();
            int          tcount = wo.LoadObj("data/file.obj");

            if (tcount > 0)
            {
                TriangleMesh trimesh = new TriangleMesh();
                trimeshes.Add(trimesh);

                Vector3        localScaling = new Vector3(6, 6, 6);
                List <int>     indices      = wo.Indices;
                List <Vector3> vertices     = wo.Vertices;

                int i;
                for (i = 0; i < tcount; i++)
                {
                    int index0 = indices[i * 3];
                    int index1 = indices[i * 3 + 1];
                    int index2 = indices[i * 3 + 2];

                    Vector3 vertex0 = vertices[index0] * localScaling;
                    Vector3 vertex1 = vertices[index1] * localScaling;
                    Vector3 vertex2 = vertices[index2] * localScaling;

                    trimesh.AddTriangle(vertex0, vertex1, vertex2);
                }

                ConvexShape tmpConvexShape = new ConvexTriangleMeshShape(trimesh);

                //create a hull approximation
                ShapeHull hull   = new ShapeHull(tmpConvexShape);
                float     margin = tmpConvexShape.Margin;
                hull.BuildHull(margin);
                tmpConvexShape.UserObject = hull;

                ConvexHullShape convexShape = new ConvexHullShape();
                foreach (Vector3 v in hull.Vertices)
                {
                    convexShape.AddPoint(v);
                }

                if (sEnableSAT)
                {
                    convexShape.InitializePolyhedralFeatures();
                }
                tmpConvexShape.Dispose();
                //hull.Dispose();


                CollisionShapes.Add(convexShape);

                float mass = 1.0f;

                LocalCreateRigidBody(mass, Matrix.Translation(0, 2, 14), convexShape);

                const bool     useQuantization = true;
                CollisionShape concaveShape    = new BvhTriangleMeshShape(trimesh, useQuantization);
                LocalCreateRigidBody(0, Matrix.Translation(convexDecompositionObjectOffset), concaveShape);

                CollisionShapes.Add(concaveShape);


                // Bullet Convex Decomposition

                FileStream   outputFile = new FileStream("file_convex.obj", FileMode.Create, FileAccess.Write);
                StreamWriter writer     = new StreamWriter(outputFile);

                DecompDesc desc = new DecompDesc
                {
                    mVertices    = wo.Vertices.ToArray(),
                    mTcount      = tcount,
                    mIndices     = wo.Indices.ToArray(),
                    mDepth       = 5,
                    mCpercent    = 5,
                    mPpercent    = 15,
                    mMaxVertices = 16,
                    mSkinWidth   = 0.0f
                };

                MyConvexDecomposition convexDecomposition = new MyConvexDecomposition(writer, this);
                desc.mCallback = convexDecomposition;


                // HACD

                Hacd myHACD = new Hacd();
                myHACD.SetPoints(wo.Vertices);
                myHACD.SetTriangles(wo.Indices);
                myHACD.CompacityWeight = 0.1;
                myHACD.VolumeWeight    = 0.0;

                // HACD parameters
                // Recommended parameters: 2 100 0 0 0 0
                int          nClusters = 2;
                const double concavity = 100;
                //bool invert = false;
                const bool addExtraDistPoints      = false;
                const bool addNeighboursDistPoints = false;
                const bool addFacesPoints          = false;

                myHACD.NClusters               = nClusters;       // minimum number of clusters
                myHACD.VerticesPerConvexHull   = 100;             // max of 100 vertices per convex-hull
                myHACD.Concavity               = concavity;       // maximum concavity
                myHACD.AddExtraDistPoints      = addExtraDistPoints;
                myHACD.AddNeighboursDistPoints = addNeighboursDistPoints;
                myHACD.AddFacesPoints          = addFacesPoints;

                myHACD.Compute();
                nClusters = myHACD.NClusters;

                myHACD.Save("output.wrl", false);


                if (true)
                {
                    CompoundShape compound = new CompoundShape();
                    CollisionShapes.Add(compound);

                    Matrix trans = Matrix.Identity;

                    for (int c = 0; c < nClusters; c++)
                    {
                        //generate convex result
                        Vector3[] points;
                        int[]     triangles;
                        myHACD.GetCH(c, out points, out triangles);

                        ConvexResult r = new ConvexResult(points, triangles);
                        convexDecomposition.ConvexDecompResult(r);
                    }

                    for (i = 0; i < convexDecomposition.convexShapes.Count; i++)
                    {
                        Vector3 centroid = convexDecomposition.convexCentroids[i];
                        trans = Matrix.Translation(centroid);
                        ConvexHullShape convexShape2 = convexDecomposition.convexShapes[i] as ConvexHullShape;
                        compound.AddChildShape(trans, convexShape2);

                        RigidBody body = LocalCreateRigidBody(1.0f, trans, convexShape2);
                    }

#if true
                    mass  = 10.0f;
                    trans = Matrix.Translation(-convexDecompositionObjectOffset);
                    RigidBody body2 = LocalCreateRigidBody(mass, trans, compound);
                    body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;

                    convexDecompositionObjectOffset.Z = 6;
                    trans = Matrix.Translation(-convexDecompositionObjectOffset);
                    body2 = LocalCreateRigidBody(mass, trans, compound);
                    body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;

                    convexDecompositionObjectOffset.Z = -6;
                    trans = Matrix.Translation(-convexDecompositionObjectOffset);
                    body2 = LocalCreateRigidBody(mass, trans, compound);
                    body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;
#endif
                }

                writer.Dispose();
                outputFile.Dispose();
            }
        }
Ejemplo n.º 18
0
        protected override void OnInitializePhysics()
        {
            ManifoldPoint.ContactAdded += MyContactCallback;

            SetupEmptyDynamicsWorld();

            //CompoundCollisionAlgorithm.CompoundChildShapePairCallback = MyCompoundChildShapeCallback;
            convexDecompositionObjectOffset = new Vector3(10, 0, 0);


            // Load wavefront file
            var wo = new WavefrontObj();

            //string filename = UnityEngine.Application.dataPath + "/BulletUnity/Examples/Scripts/BulletSharpDemos/ConvexDecompositionDemo/data/file.obj";
            UnityEngine.TextAsset bytes      = (UnityEngine.TextAsset)UnityEngine.Resources.Load("file.obj");
            System.IO.Stream      byteStream = new System.IO.MemoryStream(bytes.bytes);

            int tcount = wo.LoadObj(byteStream);

            if (tcount == 0)
            {
                return;
            }

            // Convert file data to TriangleMesh
            var trimesh = new TriangleMesh();

            trimeshes.Add(trimesh);

            Vector3        localScaling = new Vector3(6, 6, 6);
            List <int>     indices      = wo.Indices;
            List <Vector3> vertices     = wo.Vertices;

            int i;

            for (i = 0; i < tcount; i++)
            {
                int index0 = indices[i * 3];
                int index1 = indices[i * 3 + 1];
                int index2 = indices[i * 3 + 2];

                Vector3 vertex0 = vertices[index0] * localScaling;
                Vector3 vertex1 = vertices[index1] * localScaling;
                Vector3 vertex2 = vertices[index2] * localScaling;

                trimesh.AddTriangleRef(ref vertex0, ref vertex1, ref vertex2);
            }

            // Create a hull approximation
            ConvexHullShape convexShape;

            using (var tmpConvexShape = new ConvexTriangleMeshShape(trimesh))
            {
                using (var hull = new ShapeHull(tmpConvexShape))
                {
                    hull.BuildHull(tmpConvexShape.Margin);
                    convexShape = new ConvexHullShape(hull.Vertices);
                }
            }
            if (sEnableSAT)
            {
                convexShape.InitializePolyhedralFeatures();
            }
            CollisionShapes.Add(convexShape);


            // Add non-moving body to world
            float mass = 1.0f;

            LocalCreateRigidBody(mass, Matrix.Translation(0, 2, 14), convexShape);

            const bool useQuantization = true;
            var        concaveShape    = new BvhTriangleMeshShape(trimesh, useQuantization);

            LocalCreateRigidBody(0, Matrix.Translation(convexDecompositionObjectOffset), concaveShape);

            CollisionShapes.Add(concaveShape);


            // HACD
            var hacd = new Hacd();

            hacd.SetPoints(wo.Vertices);
            hacd.SetTriangles(wo.Indices);
            hacd.CompacityWeight = 0.1;
            hacd.VolumeWeight    = 0.0;

            // Recommended HACD parameters: 2 100 false false false
            hacd.NClusters               = 2;        // minimum number of clusters
            hacd.Concavity               = 100;      // maximum concavity
            hacd.AddExtraDistPoints      = false;
            hacd.AddNeighboursDistPoints = false;
            hacd.AddFacesPoints          = false;
            hacd.NVerticesPerCH          = 100; // max of 100 vertices per convex-hull

            hacd.Compute();
            hacd.Save("output.wrl", false);


            // Generate convex result
            var outputFile = new FileStream("file_convex.obj", FileMode.Create, FileAccess.Write);
            var writer     = new StreamWriter(outputFile);

            var convexDecomposition = new ConvexDecomposition(writer, this);

            convexDecomposition.LocalScaling = localScaling;

            for (int c = 0; c < hacd.NClusters; c++)
            {
                int      nVertices    = hacd.GetNPointsCH(c);
                int      trianglesLen = hacd.GetNTrianglesCH(c) * 3;
                double[] points       = new double[nVertices * 3];
                long[]   triangles    = new long[trianglesLen];
                hacd.GetCH(c, points, triangles);

                if (trianglesLen == 0)
                {
                    continue;
                }

                Vector3[] verticesArray = new Vector3[nVertices];
                int       vi3           = 0;
                for (int vi = 0; vi < nVertices; vi++)
                {
                    verticesArray[vi] = new Vector3(
                        (float)points[vi3], (float)points[vi3 + 1], (float)points[vi3 + 2]);
                    vi3 += 3;
                }

                int[] trianglesInt = new int[trianglesLen];
                for (int ti = 0; ti < trianglesLen; ti++)
                {
                    trianglesInt[ti] = (int)triangles[ti];
                }

                convexDecomposition.ConvexDecompResult(verticesArray, trianglesInt);
            }


            // Combine convex shapes into a compound shape
            var compound = new CompoundShape();

            for (i = 0; i < convexDecomposition.convexShapes.Count; i++)
            {
                Vector3 centroid     = convexDecomposition.convexCentroids[i];
                var     convexShape2 = convexDecomposition.convexShapes[i];
                Matrix  trans        = Matrix.Translation(centroid);
                if (sEnableSAT)
                {
                    convexShape2.InitializePolyhedralFeatures();
                }
                CollisionShapes.Add(convexShape2);
                compound.AddChildShape(trans, convexShape2);

                LocalCreateRigidBody(1.0f, trans, convexShape2);
            }
            CollisionShapes.Add(compound);

            writer.Dispose();
            outputFile.Dispose();

#if true
            mass = 10.0f;
            var body2 = LocalCreateRigidBody(mass, Matrix.Translation(-convexDecompositionObjectOffset), compound);
            body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;

            convexDecompositionObjectOffset.Z = 6;
            body2 = LocalCreateRigidBody(mass, Matrix.Translation(-convexDecompositionObjectOffset), compound);
            body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;

            convexDecompositionObjectOffset.Z = -6;
            body2 = LocalCreateRigidBody(mass, Matrix.Translation(-convexDecompositionObjectOffset), compound);
            body2.CollisionFlags |= CollisionFlags.CustomMaterialCallback;
#endif
        }