Example #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;
        }