예제 #1
0
 public void Set(int _index, int _value)
 {
     Map(); FlexUtils.FastCopy(ref _value, 0, m_pointer, _index * m_stride, m_stride);
 }
예제 #2
0
 public void Set(int _start, int _count, int[] _data)
 {
     Map(); FlexUtils.FastCopy(ref _data[0], 0, m_pointer, _start * m_stride, _count * m_stride);
 }
예제 #3
0
 public void Set(int _index, Flex.CollisionGeometry _value)
 {
     Map(); FlexUtils.FastCopy(ref _value, 0, m_pointer, _index * m_stride, m_stride);
 }
예제 #4
0
 public void Get(int _start, int _count, Flex.CollisionGeometry[] _data)
 {
     Map(); FlexUtils.FastCopy(m_pointer, _start * m_stride, ref _data[0], 0, _count * m_stride);
 }
예제 #5
0
 public void Get(int _start, int _count, Quaternion[] _data)
 {
     Map(); FlexUtils.FastCopy(m_pointer, _start * m_stride, ref _data[0], 0, _count * m_stride);
 }
예제 #6
0
 public void Get(int _index, ref Quaternion _value)
 {
     Map(); FlexUtils.FastCopy(m_pointer, _index * m_stride, ref _value, 0, m_stride);
 }
        void Create()
        {
            m_actor = GetComponentInParent <FlexActor>();
            if (m_actor == null)
            {
                Debug.LogError("_auxFlexDrawPartcles should be parented to a FlexActor");
                Debug.Break();
            }

            if (m_actor && m_actor.handle)
            {
                FlexExt.Instance instance = m_actor.handle.instance;

                int[] indices = new int[instance.numParticles];
                if (instance.numParticles > 0)
                {
                    FlexUtils.FastCopy(instance.particleIndices, indices);
                }

                m_mesh          = new Mesh();
                m_mesh.name     = "Flex Particles";
                m_mesh.vertices = new Vector3[1];

                if (m_actor is FlexSoftActor)
                {
                    int shapeCount = m_actor.asset.shapeOffsets.Length;
                    m_indexBuffers      = new ComputeBuffer[shapeCount];
                    m_particleMaterials = new Material[shapeCount];
                    m_mesh.subMeshCount = shapeCount;
                    for (int i = 0; i < shapeCount; ++i)
                    {
                        int start = i == 0 ? 0 : m_actor.asset.shapeOffsets[i - 1];
                        int count = m_actor.asset.shapeOffsets[i] - start;
                        m_mesh.SetIndices(new int[count], MeshTopology.Points, i);
                        m_indexBuffers[i] = new ComputeBuffer(count, 4);
                        int[] shape = new int[count];
                        for (int j = 0; j < count; ++j)
                        {
                            shape[j] = indices[m_actor.asset.shapeIndices[start + j]];
                        }
                        m_indexBuffers[i].SetData(shape);
                        m_particleMaterials[i]           = new Material(Shader.Find(PARTICLES_SHADER));
                        m_particleMaterials[i].hideFlags = HideFlags.HideAndDontSave;
                    }
                }
                else
                {
                    m_mesh.subMeshCount = 1;
                    m_mesh.SetIndices(new int[0], MeshTopology.Points, 0);
                    m_mesh.SetIndices(new int[instance.numParticles], MeshTopology.Points, 0);
                    m_indexBuffers = new ComputeBuffer[1];
                    if (instance.numParticles > 0)
                    {
                        m_indexBuffers[0] = new ComputeBuffer(instance.numParticles, sizeof(int));
                        m_indexBuffers[0].SetData(indices);
                    }
                    m_particleMaterials              = new Material[1];
                    m_particleMaterials[0]           = new Material(Shader.Find(PARTICLES_SHADER));
                    m_particleMaterials[0].hideFlags = HideFlags.HideAndDontSave;
                }

                m_mesh.bounds = m_actor.bounds;

                MeshFilter meshFilter = GetComponent <MeshFilter>();
                meshFilter.mesh = m_mesh;

                MeshRenderer meshRenderer = GetComponent <MeshRenderer>();
                meshRenderer.materials         = m_particleMaterials;
                meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
#if UNITY_EDITOR
                EditorUtility.SetSelectedRenderState(meshRenderer, EditorSelectedRenderState.Hidden);
#endif
                UpdateMesh();
            }
        }
        public void UpdateShapes(FlexContainer.ParticleData _particleData)
        {
            int colliderCount = 0;

            foreach (var item in m_colliders)
            {
                Collider collider = item.Key;

                if (!(collider is SphereCollider) && !(collider is CapsuleCollider) && !(collider is BoxCollider) && !(collider is MeshCollider))
                {
                    continue;
                }

                ++colliderCount;
            }
            if (colliderCount > 0)
            {
                if (m_geometryBuffer == null || colliderCount > m_geometryBuffer.count)
                {
                    if (m_geometryBuffer != null)
                    {
                        m_geometryBuffer.Release();
                        m_shapePositionBuffer.Release();
                        m_shapeRotationBuffer.Release();
                        m_shapePrevPositionBuffer.Release();
                        m_shapePrevRotationBuffer.Release();
                        m_shapeFlagsBuffer.Release();
                    }
                    m_geometryBuffer          = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4);
                    m_shapePositionBuffer     = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4);
                    m_shapeRotationBuffer     = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4);
                    m_shapePrevPositionBuffer = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4);
                    m_shapePrevRotationBuffer = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4);
                    m_shapeFlagsBuffer        = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(int));
                }

                int shapeIndex = 0;

                foreach (var item in m_colliders)
                {
                    Collider  collider  = item.Key;
                    ShapeData shapeData = item.Value;

                    if (!(collider is SphereCollider) && !(collider is CapsuleCollider) && !(collider is BoxCollider) && !(collider is MeshCollider))
                    {
                        continue;
                    }

                    m_geometryBuffer.Set(shapeIndex, shapeData.geometry);
                    m_shapeFlagsBuffer.Set(shapeIndex, shapeData.flags);
                    m_shapePositionBuffer.Set(shapeIndex, (Vector4)(collider.transform.position + collider.transform.rotation * shapeData.shapeCenter));
                    m_shapeRotationBuffer.Set(shapeIndex, collider.transform.rotation * shapeData.shapePreRotation);
                    m_shapePrevPositionBuffer.Set(shapeIndex, (Vector4)shapeData.shapePrevPosition);
                    m_shapePrevRotationBuffer.Set(shapeIndex, shapeData.shapePrevRotation);

                    shapeData.shapePrevPosition = collider.transform.position + collider.transform.rotation * shapeData.shapeCenter;
                    shapeData.shapePrevRotation = collider.transform.rotation * shapeData.shapePreRotation;

                    ++shapeIndex;
                }

                Flex.SetShapes(m_scene.container.solver, m_geometryBuffer.handle,
                               m_shapePositionBuffer.handle, m_shapeRotationBuffer.handle,
                               m_shapePrevPositionBuffer.handle, m_shapePrevRotationBuffer.handle,
                               m_shapeFlagsBuffer.handle, colliderCount);
            }
            else
            {
                Flex.SetShapes(m_scene.container.solver, default(Flex.Buffer),
                               default(Flex.Buffer), default(Flex.Buffer),
                               default(Flex.Buffer), default(Flex.Buffer),
                               default(Flex.Buffer), 0);
            }

            Vector3 lower = Vector3.zero, upper = Vector3.zero;

            FlexUtils.FastCopy(_particleData.particleData.lower, 0, ref lower, 0, sizeof(float) * 3);
            FlexUtils.FastCopy(_particleData.particleData.upper, 0, ref upper, 0, sizeof(float) * 3);

            if (lower.x < upper.x && lower.y < upper.y && lower.z < upper.z)
            {
                m_trigger.transform.position = (upper + lower) * 0.5f;
                m_trigger.size = (upper - lower) + Vector3.one * m_scene.container.radius;
            }
        }
        public ShapeData(Collider collider)
        {
            bool dynamic = false;

            if (collider is SphereCollider)
            {
                SphereCollider sphereCollider = collider as SphereCollider;
                Vector3        scale          = collider.transform.lossyScale;
                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.lossyScale;
                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.lossyScale;
                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.lossyScale;
                    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;
        }