public static PatchedShape CreatePatchedShapeFromMesh(Mesh inputMesh, int minTrianglesPerPatch, int maxTrianglesPerPatch, int seed) { Shape meshShapeCopy = new Shape(); meshShapeCopy.AllocateShape(inputMesh.vertexCount, inputMesh.triangles.Length); meshShapeCopy.vertices_ = inputMesh.vertices; meshShapeCopy.normals_ = inputMesh.normals; if (inputMesh.uv.Length > 0) { meshShapeCopy.uvs_ = inputMesh.uv; } meshShapeCopy.indices_ = inputMesh.triangles; PatchedShape patchedShape = new PatchedShape(); patchedShape.AllocateShape(meshShapeCopy.numIndices_, meshShapeCopy.numIndices_); patchedShape.CreatePatches(meshShapeCopy, minTrianglesPerPatch, maxTrianglesPerPatch, seed); //free copy meshShapeCopy = null; return(patchedShape); }
// 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); }
static public OptimizedPatchedShape CreateOptimizedPatchedShapeFromPatchedShape(PatchedShape patchedShape) { uint idxRemapCapacity = 1024; uint[] idxRemap = new uint[idxRemapCapacity]; OptimizedPatchedShape optimizedShape = new OptimizedPatchedShape(); //allocate optimized shape optimizedShape.AllocateShape(patchedShape.numVertices_, patchedShape.numIndices_); optimizedShape.numIndices_ = 0; //we will be filling it from beginning optimizedShape.patches_ = new Patch_[patchedShape.nPatches_]; optimizedShape.nPatches_ = patchedShape.nPatches_; uint nDstVertices = 0; for (uint ipatch = 0; ipatch < patchedShape.nPatches_; ++ipatch) { Patch_ patch = patchedShape.patches_[ipatch]; //optimizedShape.patches_[ipatch] = new Patch_(); if (patch.nVertices_ > idxRemapCapacity) { idxRemapCapacity = patch.nVertices_; idxRemap = null; idxRemap = new uint[idxRemapCapacity]; } uint dstIndex = nDstVertices; uint srcIndex = patch.startVertex_; // copy first vertex optimizedShape.vertices_[dstIndex] = patchedShape.vertices_[srcIndex]; optimizedShape.normals_[dstIndex] = patchedShape.normals_[srcIndex]; optimizedShape.uvs_[dstIndex] = patchedShape.uvs_[srcIndex]; uint nv = 1; idxRemap[0] = 0; Dictionary <PatchVertex_, uint> vmap = new Dictionary <PatchVertex_, uint>(new PatchVertexComparer_()); PatchVertex_ v0 = new PatchVertex_(patchedShape.vertices_[srcIndex], patchedShape.normals_[srcIndex], patchedShape.uvs_[srcIndex]); vmap[v0] = 0; for (uint ivert = 1; ivert < patch.nVertices_; ++ivert) { PatchVertex_ v = new PatchVertex_(patchedShape.vertices_[srcIndex + ivert], patchedShape.normals_[srcIndex + ivert], patchedShape.uvs_[srcIndex + ivert]); uint val = 0; if (vmap.TryGetValue(v, out val)) { idxRemap[ivert] = val; } else { // not found // optimizedShape.vertices_[dstIndex + nv] = patchedShape.vertices_[srcIndex + ivert]; optimizedShape.normals_[dstIndex + nv] = patchedShape.normals_[srcIndex + ivert]; optimizedShape.uvs_[dstIndex + nv] = patchedShape.uvs_[srcIndex + ivert]; idxRemap[ivert] = nv; vmap[v] = nv; ++nv; } //mesh.vertexToPatchIndex_[ivert] = ipatch; } for (int i = 0; i < patch.nVertices_; ++i) { optimizedShape.indices_[optimizedShape.numIndices_] = (int)(idxRemap[i] + nDstVertices); optimizedShape.numIndices_++; } optimizedShape.patches_[ipatch].startVertex_ = nDstVertices; optimizedShape.patches_[ipatch].nVertices_ = nv; optimizedShape.patches_[ipatch].startIndex_ = patch.startVertex_; optimizedShape.patches_[ipatch].nIndices_ = patch.nVertices_; nDstVertices += nv; } idxRemap = null; optimizedShape.numVertices_ = (int)nDstVertices; return(optimizedShape); }