Ejemplo n.º 1
0
    // Use this for initialization
    void Start()
    {
        //create a copy of mesh for processing
        PatchedShape patchedShape = PatchedShape.CreatePatchedShapeFromMesh(GetComponent <MeshFilter>().sharedMesh,
                                                                            Mathf.Max((int)minTrainglesPerpatch, (int)maxTrainglesPerpatch), (int)maxTrainglesPerpatch, randomSeed);
        OptimizedPatchedShape optimizedShape = OptimizedPatchedShape.CreateOptimizedPatchedShapeFromPatchedShape(patchedShape);

        finalShape = ExtrudedPatchedShape.CreateExtrudedPatchedShapeFromOptimizedPatchedShape(optimizedShape, extrudeAmount);

        patchedShapeCopy = new Shape();
        patchedShapeCopy.AllocateShape(finalShape.numVertices_, finalShape.numIndices_);

        finalShape.indices_.CopyTo(patchedShapeCopy.indices_, 0);

        Mesh mesh = GetComponent <MeshFilter>().mesh;

        mesh.vertices = finalShape.vertices_;
        mesh.normals  = finalShape.normals_;
        mesh.uv       = finalShape.uvs_;

        mesh.triangles = finalShape.indices_;

        //substituting material of the mesh renderer at startup
        shardsMaterial = new Material(Shader.Find("ArtSpaces/MemoryShardsShader"));
        MeshRenderer renderer        = GetComponent <MeshRenderer>();
        Material     previewMaterial = null;

        if (renderer.materials.Length == 1)
        {
            previewMaterial   = renderer.material;
            renderer.material = shardsMaterial;
        }
        else
        {
            Debug.LogError("MemoryShardsEffect only supports meshes with one material!");
        }

        //copy basic attributes if they are present in preview material
        //shardsMaterial.SetColor("_Color", Color.blue);

        _vertexToPatch   = new ComputeBuffer(finalShape.numVertices_, 4);                    // 4 = sizeOf(uint)
        _patchTransforms = new ComputeBuffer(finalShape.nPatches_, (3 + 4) * sizeof(float)); // Vector3, Quaternion

        _vertexToPatch.SetData(finalShape.vertexToPatchIndex_);
        shardsMaterial.SetBuffer("_vertexToPatch", _vertexToPatch);

        _patchTransforms.SetData(finalShape.patchTransforms_);
        shardsMaterial.SetBuffer("_patchTransforms", _patchTransforms);

        //setup compute buffers for compute shader
        _patchStates = new ComputeBuffer(finalShape.nPatches_, (3 + 3) * sizeof(float));         // Vector3, Vector3
        _patchInfos  = new ComputeBuffer(finalShape.nPatches_, (3 + 3 + 1 + 1) * sizeof(float)); // Vector3, Vector3, float, float

        shardsMotionCSKernel = shardsMotionCS.FindKernel("cs_updatePatch");

        PatchInfo_[]  patchInfos  = new PatchInfo_[finalShape.nPatches_];
        PatchState_[] patchStates = new PatchState_[finalShape.nPatches_];

        Random.InitState(GetHashCode());

        for (int i = 0; i < finalShape.nPatches_; i++)
        {
            patchInfos[i].patchAcceleration        = Random.onUnitSphere * 0.01f;
            patchInfos[i].patchAngularAcceleration = Random.onUnitSphere * 0.05f;
            patchInfos[i].patchDrag        = Random.Range(0.0f, 1.0f);
            patchInfos[i].patchRandomValue = Random.Range(0.0f, 1.0f);

            patchStates[i].patchVelocity        = Vector3.zero;
            patchStates[i].patchAngularVelocity = Vector3.zero;
        }

        _patchInfos.SetData(patchInfos);
        _patchStates.SetData(patchStates);
    }
Ejemplo n.º 2
0
    static public ExtrudedPatchedShape CreateExtrudedPatchedShapeFromOptimizedPatchedShape(OptimizedPatchedShape optimizedShape, float extrudeAmount)
    {
        //uint idxRemapCapacity = 1024;
        //uint[] idxRemap = new uint[idxRemapCapacity];

        ExtrudedPatchedShape extrudedShape = new ExtrudedPatchedShape();

        //allocate optimized shape
        extrudedShape.AllocateShape(optimizedShape.numVertices_ * 8, optimizedShape.numIndices_ * 12);
        extrudedShape.numIndices_ = 0; //we will be filling it from beginning

        extrudedShape.patches_  = new Patch_[optimizedShape.nPatches_];
        extrudedShape.nPatches_ = optimizedShape.nPatches_;

        uint nDstVertices        = 0;
        uint nDstIndices         = 0;
        int  numberOfNewVertices = 0;

        for (uint ipatch = 0; ipatch < optimizedShape.nPatches_; ++ipatch)
        {
            Patch_ patch = optimizedShape.patches_[ipatch];

            extrudedShape.patches_[ipatch].startVertex_ = nDstVertices;
            extrudedShape.patches_[ipatch].startIndex_  = nDstIndices;

            int lastNumberOfNewVertices = numberOfNewVertices;

            //copy all vertices original vertices
            for (uint ivert = patch.startVertex_; ivert < patch.startVertex_ + patch.nVertices_; ++ivert)
            {
                extrudedShape.vertices_[nDstVertices] = optimizedShape.vertices_[ivert];
                extrudedShape.normals_[nDstVertices]  = optimizedShape.normals_[ivert];
                extrudedShape.uvs_[nDstVertices]      = optimizedShape.uvs_[ivert];

                nDstVertices++;
            }
            //taking care of indices
            for (uint iidx = patch.startIndex_; iidx < patch.startIndex_ + patch.nIndices_; ++iidx)
            {
                extrudedShape.indices_[nDstIndices] = optimizedShape.indices_[iidx] + numberOfNewVertices;

                nDstIndices++;
            }

            //adding extruded vertices
            for (uint ivert = patch.startVertex_; ivert < patch.startVertex_ + patch.nVertices_; ++ivert)
            {
                extrudedShape.vertices_[nDstVertices] = optimizedShape.vertices_[ivert] - extrudeAmount * optimizedShape.normals_[ivert];
                extrudedShape.normals_[nDstVertices]  = -optimizedShape.normals_[ivert];
                extrudedShape.uvs_[nDstVertices]      = optimizedShape.uvs_[ivert];

                nDstVertices++;
                numberOfNewVertices++;
            }

            //adding indices in reverse order
            for (int iidx = (int)(patch.startIndex_ + patch.nIndices_) - 1; iidx >= patch.startIndex_; --iidx)
            {
                extrudedShape.indices_[nDstIndices] = optimizedShape.indices_[iidx] + numberOfNewVertices;

                nDstIndices++;
            }

            //taking care of edge vertices
            //first find all edges of a patch within just one triangle
            Dictionary <Edge_, uint> edges = new Dictionary <Edge_, uint>(new EdgeComparer_());

            for (uint tidx = patch.startIndex_; tidx < patch.startIndex_ + patch.nIndices_; tidx += 3)
            {
                Edge_ e1 = new Edge_(optimizedShape.indices_[tidx + 0], optimizedShape.indices_[tidx + 1]);
                Edge_ e2 = new Edge_(optimizedShape.indices_[tidx + 1], optimizedShape.indices_[tidx + 2]);
                Edge_ e3 = new Edge_(optimizedShape.indices_[tidx + 2], optimizedShape.indices_[tidx + 0]);

                uint val = 0;
                if (edges.TryGetValue(e1, out val))
                {
                    edges[e1] = val + 1;
                }
                else
                {
                    edges[e1] = 1;
                }

                if (edges.TryGetValue(e2, out val))
                {
                    edges[e2] = val + 1;
                }
                else
                {
                    edges[e2] = 1;
                }

                if (edges.TryGetValue(e3, out val))
                {
                    edges[e3] = val + 1;
                }
                else
                {
                    edges[e3] = 1;
                }
            }

            foreach (KeyValuePair <Edge_, uint> entry in edges)
            {
                if (entry.Value == 1)
                {
                    //add this edge to extruded geometry

                    //we need to duplicate 4 vertices because of new normals
                    //these are:
                    int v1 = entry.Key.v1_ + lastNumberOfNewVertices;
                    int v2 = entry.Key.v2_ + lastNumberOfNewVertices;
                    int v3 = entry.Key.v1_ + (int)patch.nVertices_ + lastNumberOfNewVertices;
                    int v4 = entry.Key.v2_ + (int)patch.nVertices_ + lastNumberOfNewVertices;

                    Vector3 p1 = extrudedShape.vertices_[v1];
                    Vector3 p2 = extrudedShape.vertices_[v2];
                    Vector3 p3 = extrudedShape.vertices_[v3];
                    Vector3 p4 = extrudedShape.vertices_[v4];

                    //v1
                    extrudedShape.vertices_[nDstVertices] = extrudedShape.vertices_[v1];
                    extrudedShape.normals_[nDstVertices]  = Vector3.Cross(p1 - p3, p1 - p2);
                    extrudedShape.uvs_[nDstVertices]      = extrudedShape.uvs_[v1];
                    int newV1index = (int)nDstVertices;
                    nDstVertices++;
                    numberOfNewVertices++;

                    //v2
                    extrudedShape.vertices_[nDstVertices] = extrudedShape.vertices_[v2];
                    extrudedShape.normals_[nDstVertices]  = Vector3.Cross(p2 - p1, p2 - p4);
                    extrudedShape.uvs_[nDstVertices]      = extrudedShape.uvs_[v2];
                    int newV2index = (int)nDstVertices;
                    nDstVertices++;
                    numberOfNewVertices++;

                    //v3
                    extrudedShape.vertices_[nDstVertices] = extrudedShape.vertices_[v3];
                    extrudedShape.normals_[nDstVertices]  = Vector3.Cross(p3 - p4, p3 - p1);
                    extrudedShape.uvs_[nDstVertices]      = extrudedShape.uvs_[v3];
                    int newV3index = (int)nDstVertices;
                    nDstVertices++;
                    numberOfNewVertices++;

                    //v4
                    extrudedShape.vertices_[nDstVertices] = extrudedShape.vertices_[v4];
                    extrudedShape.normals_[nDstVertices]  = Vector3.Cross(p4 - p2, p4 - p3);
                    extrudedShape.uvs_[nDstVertices]      = extrudedShape.uvs_[v3];
                    int newV4index = (int)nDstVertices;
                    nDstVertices++;
                    numberOfNewVertices++;

                    extrudedShape.indices_[nDstIndices++] = newV1index;
                    extrudedShape.indices_[nDstIndices++] = newV3index;
                    extrudedShape.indices_[nDstIndices++] = newV2index;

                    extrudedShape.indices_[nDstIndices++] = newV2index;
                    extrudedShape.indices_[nDstIndices++] = newV3index;
                    extrudedShape.indices_[nDstIndices++] = newV4index;
                }
            }

            extrudedShape.patches_[ipatch].nVertices_ = nDstVertices - extrudedShape.patches_[ipatch].startVertex_;
            extrudedShape.patches_[ipatch].nIndices_  = nDstIndices - extrudedShape.patches_[ipatch].startIndex_;
        }

        extrudedShape.numVertices_ = (int)nDstVertices;
        extrudedShape.numIndices_  = (int)nDstIndices;

        //resize final array
        Array.Resize <Vector3>(ref extrudedShape.vertices_, extrudedShape.numVertices_);
        Array.Resize <Vector3>(ref extrudedShape.normals_, extrudedShape.numVertices_);
        Array.Resize <Vector2>(ref extrudedShape.uvs_, extrudedShape.numVertices_);

        Array.Resize <int>(ref extrudedShape.indices_, extrudedShape.numIndices_);

        extrudedShape.finalizePatches();

        return(extrudedShape);
    }