Exemplo n.º 1
0
        public ShapeData(Collider collider)
        {
            bool dynamic = false;

            if (collider is SphereCollider)
            {
                SphereCollider sphereCollider = collider as SphereCollider;
                Vector3        scale          = collider.transform.localScale;
                geometry.sphere.radius = sphereCollider.radius * Mathf.Max(scale.x, scale.y, scale.z);
                flags          = Flex.MakeShapeFlags(Flex.CollisionShapeType.Sphere, dynamic);
                shapeMin       = Vector3.one * -geometry.sphere.radius;
                shapeMax       = Vector3.one * geometry.sphere.radius;
                shapeCenter    = sphereCollider.center;
                shapeCenter.x *= scale.x; shapeCenter.y *= scale.y; shapeCenter.z *= scale.z;
            }
            else if (collider is CapsuleCollider)
            {
                CapsuleCollider capsuleCollider = collider as CapsuleCollider;
                Vector3         scale           = collider.transform.localScale;
                if (capsuleCollider.direction == 1)
                {
                    scale = new Vector3(scale.y, scale.z, scale.x);
                }
                if (capsuleCollider.direction == 2)
                {
                    scale = new Vector3(scale.z, scale.x, scale.y);
                }
                geometry.capsule.radius     = capsuleCollider.radius * Mathf.Max(scale.y, scale.z);
                geometry.capsule.halfHeight = capsuleCollider.height * scale.x * 0.5f - geometry.capsule.radius;
                flags          = Flex.MakeShapeFlags(Flex.CollisionShapeType.Capsule, dynamic);
                shapeMin       = new Vector3(-geometry.capsule.halfHeight - geometry.capsule.radius, -geometry.capsule.radius, -geometry.capsule.radius);
                shapeMax       = new Vector3(geometry.capsule.halfHeight + geometry.capsule.radius, geometry.capsule.radius, geometry.capsule.radius);
                shapeCenter    = capsuleCollider.center;
                shapeCenter.x *= scale.x; shapeCenter.y *= scale.y; shapeCenter.z *= scale.z;
                if (capsuleCollider.direction == 1)
                {
                    shapePreRotation = Quaternion.Euler(0.0f, 0.0f, 90.0f);
                }
                if (capsuleCollider.direction == 2)
                {
                    shapePreRotation = Quaternion.Euler(0.0f, 90.0f, 0.0f);
                }
            }
            else if (collider is BoxCollider)
            {
                BoxCollider boxCollider = collider as BoxCollider;
                Vector3     scale       = collider.transform.localScale;
                Vector3     halfSize    = new Vector3(boxCollider.size.x * scale.x * 0.5f, boxCollider.size.y * scale.y * 0.5f, boxCollider.size.z * scale.z * 0.5f);
                geometry.box.halfExtents = halfSize;
                flags          = Flex.MakeShapeFlags(Flex.CollisionShapeType.Box, dynamic);
                shapeMin       = -halfSize;
                shapeMax       = halfSize;
                shapeCenter    = boxCollider.center;
                shapeCenter.x *= scale.x; shapeCenter.y *= scale.y; shapeCenter.z *= scale.z;
            }
            else if (collider is MeshCollider)
            {
                MeshCollider meshCollider = collider as MeshCollider;
                Mesh         mesh         = meshCollider.sharedMesh;
                if (mesh)
                {
                    Vector3   scale     = collider.transform.localScale;
                    Vector3   boundsMin = new Vector3(mesh.bounds.min.x * scale.x, mesh.bounds.min.y * scale.y, mesh.bounds.min.z * scale.z);
                    Vector3   boundsMax = new Vector3(mesh.bounds.max.x * scale.x, mesh.bounds.max.y * scale.y, mesh.bounds.max.z * scale.z);
                    Vector3[] vertices  = mesh.vertices;
                    int[]     triangles = mesh.triangles;
                    if (vertices.Length > 0 && triangles.Length > 0)
                    {
                        bool useConvex = meshCollider.convex;
                        if (useConvex)
                        {
                            Vector4[] planes     = new Vector4[triangles.Length / 3];
                            Vector3[] bounds     = new Vector3[2];
                            int       planeCount = FlexUtils.ConvexPlanes(ref vertices[0], ref scale, ref triangles[0], triangles.Length / 3, ref planes[0], ref bounds[0]);
                            // Convex meshes in Flex can't have more than 64 faces
                            if (planeCount <= 64)
                            {
                                m_flexConvex = Flex.CreateConvexMesh(FlexContainer.library);
                                Flex.Buffer planeBuffer = Flex.AllocBuffer(FlexContainer.library, planeCount, sizeof(float) * 4, Flex.BufferType.Host);
                                FlexUtils.FastCopy(planes, Flex.Map(planeBuffer)); Flex.Unmap(planeBuffer);
                                Flex.UpdateConvexMesh(FlexContainer.library, m_flexConvex, planeBuffer, planeCount, ref bounds[0], ref bounds[1]);
                                geometry.convexMesh.scale = Vector3.one;
                                geometry.convexMesh.mesh  = m_flexConvex;
                                Flex.FreeBuffer(planeBuffer);
                                flags    = Flex.MakeShapeFlags(Flex.CollisionShapeType.ConvexMesh, dynamic);
                                shapeMin = bounds[0];
                                shapeMax = bounds[1];
                            }
                            else
                            {
                                useConvex = false;
                            }
                        }
                        if (!useConvex)
                        {
                            int[]     uniqueInds          = new int[vertices.Length];
                            int[]     originalToUniqueMap = new int[vertices.Length];
                            int       uniqueVertCount     = FlexExt.CreateWeldedMeshIndices(ref vertices[0], vertices.Length, ref uniqueInds[0], ref originalToUniqueMap[0], 0.0001f); // @@@
                            Vector4[] uniqueVerts         = new Vector4[uniqueVertCount];
                            for (int i = 0; i < uniqueVertCount; ++i)
                            {
                                uniqueVerts[i] = new Vector3(vertices[uniqueInds[i]].x * scale.x, vertices[uniqueInds[i]].y * scale.y, vertices[uniqueInds[i]].z * scale.z);
                            }
                            Flex.Buffer vertexBuffer = Flex.AllocBuffer(FlexContainer.library, uniqueVerts.Length, sizeof(float) * 4, Flex.BufferType.Host);
                            FlexUtils.FastCopy(uniqueVerts, Flex.Map(vertexBuffer)); Flex.Unmap(vertexBuffer);
                            int[] indices = new int[triangles.Length];
                            for (int i = 0; i < triangles.Length; ++i)
                            {
                                indices[i] = originalToUniqueMap[triangles[i]];
                            }
                            Flex.Buffer indexBuffer = Flex.AllocBuffer(FlexContainer.library, indices.Length, sizeof(int), Flex.BufferType.Host);
                            FlexUtils.FastCopy(indices, Flex.Map(indexBuffer)); Flex.Unmap(indexBuffer);
                            m_flexMesh = Flex.CreateTriangleMesh(FlexContainer.library);
                            Flex.UpdateTriangleMesh(FlexContainer.library, m_flexMesh, vertexBuffer, indexBuffer, uniqueVertCount, indices.Length / 3, ref boundsMin, ref boundsMax);
                            geometry.triMesh.scale = Vector3.one;
                            geometry.triMesh.mesh  = m_flexMesh;
                            Flex.FreeBuffer(vertexBuffer);
                            Flex.FreeBuffer(indexBuffer);
                            flags = Flex.MakeShapeFlags(Flex.CollisionShapeType.TriangleMesh, dynamic);
                            Flex.GetTriangleMeshBounds(FlexContainer.library, m_flexMesh, ref shapeMin, ref shapeMax);
                        }
                    }
                }
            }
            shapePrevPosition = collider.transform.position + collider.transform.rotation * shapeCenter;
            shapePrevRotation = collider.transform.rotation * shapePreRotation;
        }
Exemplo n.º 2
0
        public void ProcessColliders(IntPtr solverPtr, Flex.Memory memory)
        {
            m_meshColliders  = FindObjectsOfType <MeshCollider>();
            m_collidersCount = m_meshColliders.Length;

            m_collidersGeometry = new Flex.CollisionTriangleMesh[m_collidersCount];

            m_collidersPositions     = new Vector4[m_collidersCount];
            m_collidersPrevPositions = new Vector4[m_collidersCount];

            m_collidersRotations     = new Quaternion[m_collidersCount];
            m_collidersPrevRotations = new Quaternion[m_collidersCount];

            m_collidersAabbMin = new Vector4[m_collidersCount];
            m_collidersAabbMax = new Vector4[m_collidersCount];

            m_collidersStarts = new int[m_collidersCount];
            m_collidersFlags  = new int[m_collidersCount];

            for (int i = 0; i < m_collidersCount; i++)
            {
                Mesh         mesh         = m_meshColliders[i].GetComponent <MeshFilter>().mesh;
                MeshCollider meshCollider = m_meshColliders[i];
                Transform    tr           = m_meshColliders[i].transform;

                Vector3[] vertices  = mesh.vertices;
                int[]     triangles = mesh.triangles;

                Vector3 localLowerBound = mesh.bounds.min;
                Vector3 localUpperBound = mesh.bounds.max;
                // FlexUtils.GetBounds(vertices, out localLowerBound, out localUpperBound);

                IntPtr meshPtr = Flex.CreateTriangleMesh();
                Flex.UpdateTriangleMesh(meshPtr, vertices, triangles, mesh.vertexCount, mesh.triangles.Length / 3, ref localLowerBound, ref localUpperBound, memory);

                //TODO
                //FlexAPI.FlexCollisionGeometry geo = new FlexAPI.FlexCollisionGeometry();
                //geo.mTriMesh.mMesh = meshPtr;
                //geo.mTriMesh.mScale = tr.lossyScale.x;

                //FlexAPI.FlexCollisionGeometry[] shapeGeometry = new FlexAPI.FlexCollisionGeometry[] { geo };

                Flex.CollisionTriangleMesh triCol = new Flex.CollisionTriangleMesh();
                triCol.mMesh  = meshPtr;
                triCol.mScale = tr.lossyScale.x;

                m_collidersGeometry[i] = triCol;

                m_collidersPositions[i]     = tr.position;
                m_collidersPrevPositions[i] = tr.position;

                m_collidersRotations[i]     = tr.rotation;
                m_collidersPrevRotations[i] = tr.rotation;

                m_collidersAabbMin[i] = meshCollider.bounds.min;
                m_collidersAabbMax[i] = meshCollider.bounds.max;

                m_collidersStarts[i] = i;
                m_collidersFlags[i]  = Flex.MakeShapeFlags(Flex.CollisionShapeType.eFlexShapeTriangleMesh, !m_meshColliders[i].gameObject.isStatic);
            }

            UpdateColliders(solverPtr, memory);
        }