private bool DealWithSpecialCases(OutputMesh builder, int facesIndex, CPNPolygon polygon) { CPNSideEdge[] polylines = polygon.sideEdges; /*---- SPECIAL CASES ----*/ if (MV == 1 && MH != 1) { NetPolylineIndicesArray array1 = new NetPolylineIndicesArray(polylines[0], builder); NetPolylineIndicesArray array2 = new NetPolylineIndicesArray(polylines[2], builder, true); MeshStructures.CreateSideTriangles(builder, array2, array1, facesIndex); return(true); } if (MV != 1 && MH == 1) { NetPolylineIndicesArray array1 = new NetPolylineIndicesArray(polylines[1], builder); NetPolylineIndicesArray array2 = new NetPolylineIndicesArray(polylines[3], builder, true); MeshStructures.CreateSideTriangles(builder, array2, array1, facesIndex); return(true); } if (MV == 1 && MH == 1) { builder.WriteQuad(facesIndex, polylines[0].GetFirstVertex(), polylines[1].GetFirstVertex(), polylines[2].GetFirstVertex(), polylines[3].GetFirstVertex()); return(true); } return(false); }
public void EvaluatePolyline(CurvedPolygonsNet net, OutputMesh mesh, CPNGuide guide) { bool uvAvailable = net.GetUv() != null && net.GetUv().Length != 0 && mesh.DoUseUVs(); int countP = mesh.CountProperties(); //bool tgAvailable = net.GetTangents() != null && net.GetTangents().Length != 0; short[] tessellationDegrees = CPNGuide_loqs; guide.vBuffer = CreateBufferWithIndices(guide.vBuffer, net.GetVertices(), guide.GetIndices()); guide.nBuffer = CreateBufferWithIndices(guide.vBuffer, net.GetNormals(), guide.GetIndices()); if (uvAvailable) { guide.uvsBuffer = CreateBufferWithIndices(guide.uvsBuffer, net.GetUv(), guide.GetIndices()); } if (countP > 0) { guide.PreparePropertiesBuffers(countP); for (int k = 0; k < countP; k++) { guide.propertiesBuffer[k] = CreateBufferWithIndices(guide.propertiesBuffer[k], net.GetProperties3()[k], guide.GetIndices()); } } }
public void CreateQuadTessellation(OutputMesh builder, int internalsIndex, int facesIndex, CPNPolygon polygon) { /*---- SPECIAL CASES ----*/ if (DealWithSpecialCases(builder, facesIndex, polygon)) { return; } CPNSideEdge[] polylines = polygon.sideEdges; int trPosition = facesIndex; int innerVerticesPosition = internalsIndex; //Internal Quads -- Pretty Straightforward for (int i = 0; i < MV - 2; i++) { int rowPosition1 = innerVerticesPosition + (i) * (MH - 1); int rowPosition2 = innerVerticesPosition + (i + 1) * (MH - 1); for (int j = 0; j < MH - 2; j++) { trPosition = builder.WriteQuad(trPosition, rowPosition1 + j, rowPosition1 + j + 1, rowPosition2 + j + 1, rowPosition2 + j); } } UpdateSides(builder, polygon, trPosition, innerVerticesPosition); }
public void BuildModel(GameObject gameObject) { CurvedPolygonsNet cpnet = GetPolylinesCPNet(asset.GetCPN()); short[] loqs = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; CPNTessellationProcess tessellationProcess = ProcessesKeeper.GetTessellationProcess(); TessellationOutput output = tessellationProcess.InitProcess(cpnet, loqs, this); //Debug.Log("cpnet.GetGeometriesCount() " + cpnet.GetGeometriesCount()); tessellationProcess.BuildProfile(); int[] builtTrianglesCount = output.GetBuiltTrianglesSize(); int builtVerticesCount = output.GetBuiltVerticesSize(); Vector2[] uvs_ = new Vector2[builtVerticesCount]; Vector3[] vertices_ = new Vector3[builtVerticesCount]; Vector3[] normals_ = new Vector3[builtVerticesCount]; int[][] indices_ = new int[builtTrianglesCount.Length][]; //Debug.Log("indices_ " + indices_.Length); for (int i = 0; i < builtTrianglesCount.Length; i++) { indices_[i] = new int[builtTrianglesCount[i] * 3]; //Debug.Log("indices_[" + i + "] " + indices_[i].Length); } OutputMesh mesh = null; mesh = new OutputMesh(vertices_, uvs_, normals_, indices_); tessellationProcess.WriteMesh(mesh); MeshAssigner.AssignMesh(gameObject, vertices_, normals_, uvs_, indices_); }
public NetPolylineIndicesArray(CPNSideEdge guide, OutputMesh builder) { this.guide = guide; this.builder = builder; this.position = 0; this.back = false; }
// Retrieves meshes from last generate result and creates according Unity meshes void GetMeshes(Material[] materials, Transform loc2WorldTrafo, out OutputMesh[] meshes) { int numMeshes = Prt4Unity.GetMeshCount(ctx); meshes = new OutputMesh[numMeshes]; for (int i = 0; i < numMeshes; i++) { IntPtr name, pVertices, pNormals, pTexcoords; int numVertices; Prt4Unity.GetMesh(ctx, i, out name, out numVertices, out pVertices, out pNormals, out pTexcoords); OutputMesh outputMesh = new OutputMesh(); meshes[i] = outputMesh; outputMesh.mesh = new Mesh(); outputMesh.mesh.name = Marshal.PtrToStringUni(name); float[] floats = new float[numVertices * 3]; Marshal.Copy(pVertices, floats, 0, numVertices * 3); Vector3[] vertices = new Vector3[numVertices]; Vector3 preScale = loc2WorldTrafo.localScale; for (int v = 0; v < numVertices; v++) { vertices[v] = new Vector3(floats[3 * v + 0], floats[3 * v + 1], floats[3 * v + 2]); vertices[v] = loc2WorldTrafo.InverseTransformPoint(vertices[v]); vertices[v].x *= preScale.x; vertices[v].y *= preScale.y; vertices[v].z *= preScale.z; } outputMesh.mesh.vertices = vertices; Marshal.Copy(pNormals, floats, 0, numVertices * 3); Vector3[] normals = new Vector3[numVertices]; for (int v = 0; v < numVertices; v++) { normals[v] = new Vector3(floats[3 * v + 0], floats[3 * v + 1], floats[3 * v + 2]); } outputMesh.mesh.normals = normals; if (pTexcoords != IntPtr.Zero) { Marshal.Copy(pTexcoords, floats, 0, numVertices * 2); Vector2[] texcoords = new Vector2[numVertices]; for (int v = 0; v < numVertices; v++) { texcoords[v] = new Vector2(floats[2 * v + 0], floats[2 * v + 1]); } outputMesh.mesh.uv = texcoords; } int numSubMeshes = Prt4Unity.GetSubMeshCount(ctx, i); outputMesh.mesh.subMeshCount = (int)numSubMeshes; outputMesh.materials = new Material[numSubMeshes]; for (int s = 0; s < numSubMeshes; s++) { IntPtr pIndices; int numIndices, materialIndex; Prt4Unity.GetSubMesh(ctx, i, s, out pIndices, out numIndices, out materialIndex); int[] indices = new int[numIndices]; Marshal.Copy(pIndices, indices, 0, numIndices); outputMesh.mesh.SetTriangles(indices, (int)s); outputMesh.materials[s] = materials[materialIndex]; } } }
public void writeWithGuideBack(CPNSideEdge guide, int N, float step, OutputMesh mesh, CPNGuideEvaluator evaluator) { this.step = step; requestSize(N + 1); //We should have only one thickness on multisided edge, you know? this.thickness = 1; for (int i = 0; i <= N; i++) { //This is the eval-back evaluator.EvalAt(1.0f - i * step, guide); Vector3 dev = evaluator.EvalDev(guide); vertices[i] = evaluator.EvalVertex(guide); if (i == 0) { devFirst = dev; } if (i == N) { devLast = dev; } evaluator.EvalAt(i * step + DELTA, guide); verticesDplus[i] = evaluator.EvalVertex(guide); evaluator.EvalAt(i * step - DELTA, guide); verticesDminus[i] = evaluator.EvalVertex(guide); normals[i] = evaluator.EvalNormal(guide, dev).normalized; uvs[i] = evaluator.EvalUV(guide); for (int k = 0; k < countP; k++) { properties[k][i] = evaluator.EvalProperty(guide, k); } } }
private void WriteMesh(Mesh storedMesh, OutputMesh output /*,bool useUnityNormals*/) { if (output.GetVertices().Length > CPNTessellationProcess.MAX_VERTICES_SIZE) { return; } storedMesh.Clear(); storedMesh.vertices = output.GetVertices(); storedMesh.uv = output.GetUVs(); storedMesh.normals = output.GetNormals(); int[][] triangles = output.GetTriangles(); if (triangles.Length == 0) { storedMesh.SetTriangles(new int[0], 0); } else { storedMesh.subMeshCount = triangles.Length; for (int i = 0; i < triangles.Length; i++) { storedMesh.SetTriangles(triangles[i], i); } } }
public void Execute() { CurvedPolygonsNet cpnet = asset.GetCPN(); short[] loqs = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; CPNTessellationProcess tessellationProcess = ProcessesKeeper.GetTessellationProcess(); TessellationOutput output = tessellationProcess.InitProcess(cpnet, loqs); tessellationProcess.BuildProfile(); int[] builtTrianglesCount = output.GetBuiltTrianglesSize(); int builtVerticesCount = output.GetBuiltVerticesSize(); uvs_ = new Vector2[builtVerticesCount]; vertices_ = new Vector3[builtVerticesCount]; normals_ = new Vector3[builtVerticesCount]; indices_ = new int[builtTrianglesCount.Length][]; for (int i = 0; i < builtTrianglesCount.Length; i++) { indices_[i] = new int[builtTrianglesCount[i] * 3]; } OutputMesh mesh = null; mesh = new OutputMesh(vertices_, uvs_, normals_, indices_); tessellationProcess.WriteMesh(mesh); }
public LinearMeshIndicesArray(int first, int move, int count, OutputMesh builder) { this.first = first; this.move_ = move; this.count_ = count; this.source = builder; this.position = 0; }
public int UpdateSides(OutputMesh builder, CPNPolygon polygon, int trPosition, int innerVerticesPosition) { CPNSideEdge[] polylines = polygon.sideEdges; first[0] = innerVerticesPosition; first[1] = innerVerticesPosition + (MH - 2); first[2] = innerVerticesPosition + (MV - 1) * (MH - 1) - 1; first[3] = innerVerticesPosition + (MV - 2) * (MH - 1); move[0] = 1; move[1] = (MH - 1); move[2] = -1; move[3] = -(MH - 1); count[0] = MH - 1; count[1] = MV - 1; count[2] = MH - 1; count[3] = MV - 1; for (int i = 0; i < 4; i++) { if (polylines[i].GetN() > 1) { LinearMeshIndicesArray lmi = new LinearMeshIndicesArray(first[i], move[i], count[i], builder); NetPolylineInternalIndicesArray npi = new NetPolylineInternalIndicesArray(polylines[i], builder); trPosition = MeshStructures.CreateSideTriangles(builder, lmi, npi, trPosition); } else { LinearMeshIndicesArray lmi = new LinearMeshIndicesArray(first[i], move[i], count[i], builder); NetPolylineIndicesArray npi = new NetPolylineIndicesArray(polylines[i], builder); trPosition = MeshStructures.CreateSideTriangles(builder, lmi, npi, trPosition); } int prev = i == 0 ? 3 : i - 1; if (polylines[i].GetN() > 1 && polylines[prev].GetN() > 1) { trPosition = builder.WriteQuad(trPosition, polylines[i].GetIndex(0), polylines[i].GetIndex(1), first[i], polylines[prev].GetBackIndex(1)); } else if (polylines[i].GetN() > 1) { trPosition = builder.WriteTriangle(trPosition, polylines[i].GetIndex(0), polylines[i].GetIndex(1), first[i]); } else if (polylines[prev].GetN() > 1) { trPosition = builder.WriteTriangle(trPosition, polylines[i].GetIndex(0), first[i], polylines[prev].GetBackIndex(1)); } // System.err.println("trPosition on sides " + trPosition); } return(trPosition); }
public void Setup(int first, int move, int count, int last, OutputMesh builder, int layer) { this.first = first; this.move_ = move; this.count_ = count; this.last = last; this.source = builder; this.layer = layer; position = 0; }
public void WriteMesh(OutputMesh mesh) { int position = WriteVertices(mesh); position = WriteEdges(mesh, position); WriteEdgesNormals(mesh); position = WritePolygons(mesh, position); }
public NGonsMeshIndicesArray(int first, int move, int count, int last, OutputMesh builder, int layer) { this.first = first; this.move_ = move; this.count_ = count; this.last = last; this.source = builder; this.layer = layer; position = 0; }
public void Setup(int first, int move, int deltaMove, int count, OutputMesh builder, int layer) { this.deltaMove = deltaMove; this.basemove = move; this.move_ = move + deltaMove; this.count_ = count; this.builder = builder; this.layer = layer; index = first; next = first + this.move_; this.first = first; }
int WritePolygons(OutputMesh mesh, int position) { int geometriesCount = this.curvedPolygonsNet.GetGeometriesCount(); CPNPolygon[][] polygons = tessellationOutput.GetPolygons(); int[][] polygonsProfile = tessellationOutput.GetPolygonsProfile(); int[][] polygonsVerticesProfile = tessellationOutput.GetPolygonsVerticesProfile(); for (int k = 0; k < geometriesCount; k++) { mesh.SetGeometry(k); CPNGeometry geometry = this.curvedPolygonsNet.GetGeometries()[k]; int geomPolygonsCount = subSet == null?geometry.GetPolygonsCount() : subSet.polygons[k].Length; for (int i = 0; i < geomPolygonsCount; i++) { int index = subSet == null ? i : subSet.polygons[k][i]; int countEffectiveSize = polygons[k][index].sideEdges.Length; CPNPolygon polygonData = polygons[k][index]; if (countEffectiveSize > 2 && countEffectiveSize < TESSELLATION_PROCESS_NET_INTERPOLATORS && !polygonData.skip) { polygonData.computeSideEdgesSizes(); ICPNetInterpolator netInterpolator = manager.GetSchema(polygonData.schemaIndex). interpolators[countEffectiveSize]; netInterpolator.UdpdateContent(mesh, polygonData, polygonsVerticesProfile[k][index], polygonsProfile[k][index]); } } position += polygonsVerticesProfile[k][geometry.GetPolygonsCount()]; int triangleIndex = polygonsProfile[k][geometry.GetPolygonsCount()]; int trianglesCount = geometry.GetTrianglesCount(); short[] triangles = geometry.GetTriangles(); for (int i = 0; i < trianglesCount; i++) { mesh.WriteTriangle(triangleIndex, triangles[3 * i], triangles[3 * i + 1], triangles[3 * i + 2]); triangleIndex++; } int quadsCount = geometry.GetQuadsCount(); short[] quads = geometry.GetQuads(); for (int i = 0; i < quadsCount; i++) { mesh.WriteQuad(triangleIndex, quads[3 * i], quads[3 * i + 1], quads[3 * i + 2], quads[3 * i + 3]); triangleIndex += 2; } } return(position); }
public void Execute() { CurvedPolygonsNet cpnet = asset.GetCPN(); CurvedPolyVariants cpnVariants = new CurvedPolyVariants(); cpnVariants.SetCPN(cpnet); short[] loqs = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; CPNTessellationProcess tessellationProcess = ProcessesKeeper.GetTessellationProcess(); TessellationOutput output = tessellationProcess.InitProcess(cpnet, loqs); //Debug.Log("cpnet.GetGeometriesCount() " + cpnet.GetGeometriesCount()); tessellationProcess.BuildProfile(); int[] builtTrianglesCount = output.GetBuiltTrianglesSize(); int builtVerticesCount = output.GetBuiltVerticesSize(); uvs_ = new Vector2[builtVerticesCount]; vertices_ = new Vector3[builtVerticesCount]; normals_ = new Vector3[builtVerticesCount]; indices_ = new int[builtTrianglesCount.Length][]; for (int i = 0; i < builtTrianglesCount.Length; i++) { indices_[i] = new int[builtTrianglesCount[i] * 3]; } OutputMesh mesh = null; mesh = new OutputMesh(vertices_, uvs_, normals_, indices_); tessellationProcess.WriteMesh(mesh); //here int id = cpnVariants.GetFreeTessellationRecordId(); cpnVariants.SetRecord(id, new OutputMesh(vertices_, uvs_, normals_, indices_), output); //this.outMesh = cpnVariants.GetMeshOutput(id).GetNewCloneVariant(); CPNSubset subsSet = new CPNSubset(); TessellationOutput output2 = tessellationProcess.InitProcess(cpnet, loqs, subsSet); this.mesh2 = new OutputMesh(outMesh.GetVertices(), outMesh.GetUVs(), outMesh.GetNormals(), outMesh.GetTriangles()); tessellationProcess.WriteMesh(mesh2); }
void WriteEdgesNormals(OutputMesh mesh) { IGuideModel guideEvaluator = GetGuideModel(); CPNGuide[] guides = this.tessellationOutput.GetGuides(); int edgesSize = subSet == null?curvedPolygonsNet.GetEdgesCount() : subSet.edges.Length; for (int i = 0; i < edgesSize; i++) { int index = subSet == null ? i : subSet.edges[i]; if (guides[index].GetN() > 0) { guideEvaluator.EvaluateNormals(mesh, guides[index]); } } }
Vector3 EvalVertex(OutputMesh builder, CPNPolygon polylines, float innerX, float innerY, out Vector3 uv) { updateVals(innerX, innerY); for (int k = 0; k < sides; k++) { int kprev = k == 0 ? sides - 1 : k - 1; float dx = (innerX * cos_[k] - innerY * sin_[k]) - 1; float dy = (innerX * sin_[k] + innerY * cos_[k]); float U = cornerCoordsMatrix[0] * dx + cornerCoordsMatrix[2] * dy; float V = cornerCoordsMatrix[1] * dx + cornerCoordsMatrix[3] * dy; int indexU = (int)((U + 0.0001f) * totalInterpolationStep); int indexV = (int)((V + 0.0001f) * totalInterpolationStep); if (indexU > interpolationSteps) { indexU = interpolationSteps; } if (indexV > interpolationSteps) { indexV = interpolationSteps; } tmpInterpolations[k] = evalVertex(polylines.sideEdges[k], polylines.sideEdges[kprev], U, V); tmpInterpolationsUV[k] = evalUV(polylines.sideEdges[k], polylines.sideEdges[kprev], U, V); } Vector3 vertex = val[0] * tmpInterpolations[0]; uv = val[0] * tmpInterpolationsUV[0]; for (int k = 1; k < sides; k++) { vertex = vertex + tmpInterpolations[k] * val[k]; uv = uv + tmpInterpolationsUV[k] * val[k]; } return(vertex); }
int WriteEdges(OutputMesh mesh, int position) { IGuideModel guideEvaluator = GetGuideModel(); int edgesSize = subSet == null?curvedPolygonsNet.GetEdgesCount() : subSet.edges.Length; CPNGuide[] guides = this.tessellationOutput.GetGuides(); int[] edgesProfile = this.tessellationOutput.GetEdgesProfile(); for (int i = 0; i < edgesSize; i++) { int index = subSet == null ? i : subSet.edges[i]; CPNGuide polyline = guides[index]; if (polyline.GetN() > 0) { short[] edge = curvedPolygonsNet.GetEdges(/* i */); int edgeLength = curvedPolygonsNet.GetEdgeLength(index); float[] edgeWeights = curvedPolygonsNet.GetEdgeWeights(/* i */); short[] edgeHints = curvedPolygonsNet.GetEdgeHints(/* i */); int edgePosition = curvedPolygonsNet.GetEdgePosition(index); guideEvaluator.EvaluateEdge(curvedPolygonsNet, mesh, polyline, (short)edgeLength, edge, edgePosition, edgeHints, edgeWeights, edgesProfile, index); position += polyline.GetN() - 1; } } edgesSize = curvedPolygonsNet.GetEdgesCount(); int polylinesSize = subSet == null?curvedPolygonsNet.GetPolylinesCount() : subSet.polylines.Length; //No need to compute polylines for (int i = 0; i < polylinesSize; i++) { int index = subSet == null ? i : subSet.edges[i]; index += edgesSize; CPNGuide polyline = guides[index]; guideEvaluator.EvaluatePolyline(curvedPolygonsNet, mesh, polyline); } return(position); }
private void prepareMemory(int M, CPNSideEdge[] guides, OutputMesh mesh) { int triangleSize = ((M)*(M + 1)) >> 1; int totalSize = (triangleSize) * sides + 1; memory.requestSize(totalSize); for (int i = 0; i < sides; i++) { int relativePosition = triangleSize * (sides - 1 - i); bufferTemp.requestSize(M + 1); bufferTemp.writeWithGuideBack(guides[i], M, mesh, evaluator); for (int j = 0; j < M; j++) { memory.vertices[relativePosition + j] = bufferTemp.vertices[j]; memory.uv[relativePosition + j] = bufferTemp.uvs[j]; } } }
public void EvaluateNormals(OutputMesh mesh, CPNGuide guide) { int N = guide.GetN(); if (N <= 0) { return; } bool doTangents = mesh.DoUseTangents(); bool doNormals = mesh.DoNormals(); if (doNormals) { float step = 1.0f / N; for (int j = 1; j < N; j++) { EvalAt(j * step, guide); Vector3 dev; Vector3 normal = EvalNormal(guide, out dev); int index = guide.GetIndex(j); mesh.SetNormal(index, normal.normalized); if (doTangents) { mesh.SetTangent(index, GetTangent(guide, dev, normal).normalized); } } if (doTangents) { for (int j = 0; j <= N; j += N) { EvalAt(j * step, guide); Vector3 dev = EvalDev(guide); int index = guide.GetIndex(j); Vector3 normal = mesh.GetNormal(index); mesh.SetTangent(index, GetTangent(guide, dev, normal).normalized); } } } }
public void writeWithGuide(CPNSideEdge guide, int N, float step, OutputMesh mesh, CPNGuideEvaluator evaluator) { this.step = step; requestSize(N + 1); //We should have only one thickness on multisided edge, you know? this.thickness = 1; for (int i = 0; i <= N; i++) { ts[i] = evaluator.EvalAt(i * step, guide); Vector3 dev = evaluator.EvalDev(guide); vertices[i] = evaluator.EvalVertex(guide); uvs[i] = evaluator.EvalUV(guide); normals[i] = evaluator.EvalNormal(guide, dev).normalized; for (int k = 0; k < countP; k++) { properties[k][i] = evaluator.EvalProperty(guide, k); } } }
int WriteVertices(OutputMesh mesh) { int numberOfVertices = subSet == null?curvedPolygonsNet.GetNumberOfVertices() : subSet.vertices.Length; Vector3[] vertices = curvedPolygonsNet.GetVertices(); Vector3[] normals = curvedPolygonsNet.GetNormals(); Vector3[] uvs = curvedPolygonsNet.GetUv(); Vector3[][] properties = curvedPolygonsNet.GetProperties3(); int countProperties = mesh.CountProperties(); //Vector3[] tangents = curvedPolygonsNet.GetTangents(); //bool doTangents = tangents != null; bool doUvs = uvs != null && mesh.DoUseUVs(); bool doNormals = normals != null && mesh.DoNormals(); for (int i = 0; i < numberOfVertices; i++) { int index = subSet == null ? i : subSet.vertices[i]; mesh.SetVertex(index, vertices[index]); if (doUvs) { mesh.SetUV(index, uvs[index]); } if (doNormals) { mesh.SetNormal(index, normals[index]); } for (int k = 0; k < countProperties; k++) { mesh.SetProperty3(index, k, properties[k][index]); } } return(numberOfVertices); }
public void UdpdateContent(OutputMesh mesh, CPNPolygon polygon, int internalsIndex, int facesIndex, bool doUpdateStructure = true) { triangleStructure.RetrieveInfos(polygon); int M = triangleStructure.GetM(); float step = 1.0f / M; CPNSideEdge[] polylines = polygon.sideEdges; buffer0.writeWithGuide(polylines[0], M, mesh, evaluator); buffer1.writeWithGuide(polylines[1], M, mesh, evaluator); buffer2.writeWithGuide(polylines[2], M, mesh, evaluator); corner0.Set(buffer0, buffer2); corner1.Set(buffer1, buffer0); corner2.Set(buffer2, buffer1); prepareMemory(M); for (int i = 1; i < M - 1; i++) { for (int j = 1; j < M - 1 - (i - 1); j++) { int wIndex = M - i - j; Vector3 V1 = corner0.evalVertex(j, i); Vector3 V1uv = corner0.evalUV(j, i); Vector3 V2 = corner1.evalVertex(i, wIndex); Vector3 V2uv = corner1.evalUV(i, wIndex); Vector3 V3 = corner2.evalVertex(wIndex, j); Vector3 V3uv = corner2.evalUV(wIndex, j); float U = j * step; float V = i * step; float W = 1 - U - V; float a1 = W * W; float a2 = U * U; float a3 = V * V; #if DEBUG if (interpolationCorner != 0) { switch (interpolationCorner) { case 1: a1 = 1; a2 = 0; a3 = 0; break; case 2: a1 = 0; a2 = 1; a3 = 0; break; case 3: a1 = 0; a2 = 0; a3 = 1; break; } } #endif float rec = 1.0f / (a1 + a2 + a3); a1 *= rec; a2 *= rec; a3 *= rec; Vector3 vertex = V1 * a1 + V2 * a2 + V3 * a3; Vector3 uv = V1uv * a1 + V2uv * a2 + V3uv * a3; int memoryIndex = j + i * (M + 1) - (((i) * (i - 1)) >> 1); memory.vertices[memoryIndex] = vertex; memory.uv[memoryIndex] = uv; } } int position = internalsIndex; for (int i = 1; i < M - 1; i++) { for (int j = 1; j < M - 1 - (i - 1); j++) { int rowIndex = i * (M + 1) - (((i) * (i - 1)) >> 1); int rowIndexPrev = (i - 1) * (M + 1) - (((i - 1) * (i - 2)) >> 1); int rowIndexNext = (i + 1) * (M + 1) - (((i + 1) * (i)) >> 1); int memoryIndex = j + rowIndex; Vector3 vertex = memory.vertices[memoryIndex]; Vector3 uv = memory.uv[memoryIndex]; //Normal (S is the vertices, the surface) Vector3 dSdu = memory.vertices[memoryIndex + 1] - memory.vertices[memoryIndex - 1]; Vector3 dSdv = memory.vertices[rowIndexNext + j] - memory.vertices[rowIndexPrev + j]; Vector3 normal = Vector3.Cross(dSdu, dSdv).normalized; //Tangent Vector3 dTxdu = memory.uv[memoryIndex + 1] - memory.uv[memoryIndex - 1]; Vector3 dTxdv = memory.uv[rowIndexNext + j] - memory.uv[rowIndexPrev + j]; Vector3 tangent = getTangent(dSdu, dSdv, dTxdu, dTxdv); mesh.SetPNUV(position, vertex, normal, uv, tangent); position++; } } if (doUpdateStructure) { triangleStructure.CreateTriangleTessellation(mesh, internalsIndex, facesIndex, polygon); } }
public void UdpdateContent(OutputMesh mesh, CPNPolygon polygon, int internalsIndex, int facesIndex, bool doUpdateStructure = true) { triangleStructure.RetrieveInfos(polygon); bool useUV = mesh.DoUseUVs(); bool useNormals = mesh.DoNormals(); bool useTangents = mesh.DoUseUVs(); int countProperties = mesh.CountProperties(); buffer0.requestProperties(countProperties); buffer1.requestProperties(countProperties); buffer2.requestProperties(countProperties); int M = triangleStructure.GetM(); float step = 1.0f / M; CPNSideEdge[] polylines = polygon.sideEdges; buffer0.writeWithGuide(polylines[0], M, mesh, evaluator); buffer1.writeWithGuide(polylines[1], M, mesh, evaluator); buffer2.writeWithGuide(polylines[2], M, mesh, evaluator); edgeSurface0.Set(buffer0, buffer2, buffer1); edgeSurface1.Set(buffer1, buffer0, buffer2); edgeSurface2.Set(buffer2, buffer1, buffer0); computeCorners(); float l1 = ks[0] * ks[1] * ks[0] * ks[1]; float l2 = ks[1] * ks[2] * ks[1] * ks[2]; float l3 = ks[2] * ks[0] * ks[2] * ks[0]; prepareMemory(M, countProperties); int position = internalsIndex; for (int i = 1; i < M - 1; i++) { for (int j = 1; j < M - 1 - (i - 1); j++) { int k = M - i - j; float U = j * step; float V = i * step; float W = 1 - U - V; float a1 = U * U * W * W * l1 /** buffer0.thickness*/; float a2 = V * V * U * U * l2 /** buffer1.thickness*/; float a3 = W * W * V * V * l3 /** buffer2.thickness*/; //float a1 = W * W; //float a2 = U * U; //float a3 = V * V; if (TriangleInterpolator4.interpolationCorner != 0) { switch (TriangleInterpolator4.interpolationCorner) { case 1: a1 = 1; a2 = 0; a3 = 0; break; case 2: a1 = 0; a2 = 1; a3 = 0; break; case 3: a1 = 0; a2 = 0; a3 = 1; break; } } float rec = 1.0f / (a1 + a2 + a3); a1 *= rec; a2 *= rec; a3 *= rec; Vector3 V1 = edgeSurface0.evalVertex(/*j,*/ i, polylines[0], U / (1 - V)); Vector3 V2 = edgeSurface1.evalVertex(/*i,*/ k, polylines[1], V / (1 - W)); Vector3 V3 = edgeSurface2.evalVertex(/*k,*/ j, polylines[2], W / (1 - U)); Vector3 vertex = V1 * a1 + V2 * a2 + V3 * a3; int memoryIndex = j + i * (M + 1) - (((i) * (i - 1)) >> 1); memory.vertices[memoryIndex] = vertex; if (useUV) { Vector3 V1uv = edgeSurface0.evalUV(/*j,*/ i, polylines[0], U / (1 - V)); Vector3 V2uv = edgeSurface1.evalUV(/*i,*/ k, polylines[1], V / (1 - W)); Vector3 V3uv = edgeSurface2.evalUV(/*k,*/ j, polylines[2], W / (1 - U)); Vector3 uv = V1uv * a1 + V2uv * a2 + V3uv * a3; //Vector3 vertex = V3; //Vector3 uv = V3uv; memory.uv[memoryIndex] = uv; } for (int pIndex = 0; pIndex < countProperties; pIndex++) { Vector3 V1prop = edgeSurface0.evalProperty(pIndex, i, polylines[0], U / (1 - V)); Vector3 V2prop = edgeSurface1.evalProperty(pIndex, k, polylines[1], V / (1 - W)); Vector3 V3prop = edgeSurface2.evalProperty(pIndex, j, polylines[2], W / (1 - U)); Vector3 prop = V1prop * a1 + V2prop * a2 + V3prop * a3; mesh.SetProperty3(position, pIndex, prop); } position++; } } position = internalsIndex; for (int i = 1; i < M - 1; i++) { for (int j = 1; j < M - 1 - (i - 1); j++) { int rowIndex = i * (M + 1) - (((i) * (i - 1)) >> 1); int rowIndexPrev = (i - 1) * (M + 1) - (((i - 1) * (i - 2)) >> 1); int rowIndexNext = (i + 1) * (M + 1) - (((i + 1) * (i)) >> 1); int memoryIndex = j + rowIndex; Vector3 vertex = memory.vertices[memoryIndex]; Vector3 uv = memory.uv[memoryIndex]; Vector3 normal = Vector3.zero; Vector3 tangent = Vector3.zero; if (useNormals) { //Normal (S is the vertices, the surface) Vector3 dSdu = memory.vertices[memoryIndex + 1] - memory.vertices[memoryIndex - 1]; Vector3 dSdv = memory.vertices[rowIndexNext + j] - memory.vertices[rowIndexPrev + j]; normal = Vector3.Cross(dSdu, dSdv).normalized; if (useTangents) { //Tangent Vector3 dTxdu = memory.uv[memoryIndex + 1] - memory.uv[memoryIndex - 1]; Vector3 dTxdv = memory.uv[rowIndexNext + j] - memory.uv[rowIndexPrev + j]; tangent = getTangent(dSdu, dSdv, dTxdu, dTxdv); } } mesh.SetPNUV(position, vertex, normal, uv, tangent); position++; } } if (doUpdateStructure) { triangleStructure.CreateTriangleTessellation(mesh, internalsIndex, facesIndex, polygon); } }
public static int CreateSideTriangles2(OutputMesh builder, IMeshIndicesArray inside, IMeshIndicesArray outside, int intTrIndex) { Vector3[] vs = builder.GetVertices(); int outerEdgeLength = outside.Count(); int innerEdgeLength = inside.Count(); int outerIndex = 0; int innerIndex = 0; float dtInner = innerEdgeLength > 1 ? 1.0f / (innerEdgeLength - 1) : 1; float dtOuter = outerEdgeLength > 1 ? 1.0f / (outerEdgeLength - 1) : 1; float kIn = 0; float kOut = 1; if (outerEdgeLength > 1 && innerEdgeLength > 1) { Vector3 A = vs[outside.GetIndex()]; Vector3 B = vs[outside.GetNext()]; Vector3 C = vs[inside.GetIndex()]; Vector3 D = vs[outside.GetAtIndex(outerEdgeLength - 2)]; Vector3 E = vs[outside.GetAtIndex(outerEdgeLength - 1)]; Vector3 F = vs[inside.GetAtIndex(innerEdgeLength - 1)]; kIn = Vector3.Dot(C - A, B - A) / Vector3.Dot(B - A, B - A); kOut = Vector3.Dot(F - D, E - D) / Vector3.Dot(E - D, E - D); float rect = 1.0f / (outerEdgeLength - 1); kIn = kIn * rect; kOut = 1 - (1 - kOut) * rect; } while (innerIndex < innerEdgeLength - 1 || outerIndex < outerEdgeLength - 1) { if (innerIndex < innerEdgeLength - 1) { if (outerIndex < outerEdgeLength - 1) { int id1 = outside.GetIndex(); int id2 = inside.GetIndex(); int id3 = outside.GetNext(); int id4 = inside.GetNext(); float tOuter = dtOuter * (outerIndex); float tInner = dtInner * (innerIndex) * (kOut - kIn) + kIn; if (tInner <= tOuter) { intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2); innerIndex++; inside.Move(); } else { intTrIndex = builder.WriteTriangle(intTrIndex, id1, id3, id2); outerIndex++; outside.Move(); } } else { int id1 = outside.GetIndex(); int id2 = inside.GetIndex(); int id4 = inside.GetNext(); intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2); innerIndex++; inside.Move(); } } else { int id1 = outside.GetIndex(); int id2 = inside.GetIndex(); int id3 = outside.GetNext(); intTrIndex = builder.WriteTriangle( intTrIndex, id1, id3, id2); outerIndex++; outside.Move(); } } return(intTrIndex); }
public static int CreateSideTriangles(OutputMesh builder, IMeshIndicesArray inside, IMeshIndicesArray outside, int intTrIndex) { /*Vector3[] vs = builder.GetVertices(); * int outerEdgeLength = outside.Count(); * int innerEdgeLength = inside.Count(); * int outerIndex = 0; * int innerIndex = 0; * * while (innerIndex < innerEdgeLength - 1 || outerIndex < outerEdgeLength - 1) * { * if (innerIndex < innerEdgeLength - 1) * { * if (outerIndex < outerEdgeLength - 1) * { * int id1 = outerIndex; * int id2 = innerIndex; * int id3 = outside.GetNext(); * int id4 = inside.GetNext(); * * Vector3 P1 = vs[id1]; * Vector3 P2 = vs[id2]; * Vector3 P3 = vs[id3]; * Vector3 P4 = vs[id4]; * * float dInner = (P4 - P1).sqrMagnitude; * float dOuter = (P3 - P2).sqrMagnitude; * * if (dInner < dOuter) { * intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2); * innerIndex++; * inside.Move(); * } else { * intTrIndex = builder.WriteTriangle(intTrIndex, id1, id3, id2); * outerIndex++; * outside.Move(); * * } * } * else * { * * int id1 = outerIndex; * int id2 = innerIndex; * int id4 = inside.GetNext(); * * intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2); * innerIndex++; * inside.Move(); * } * } * else * { * int id1 = outerIndex; * int id2 = innerIndex; * int id3 = outside.GetNext(); * intTrIndex = builder.WriteTriangle( * intTrIndex, id1, id3, id2); * outerIndex++; * outside.Move(); * } * } * * return intTrIndex;*/ Vector3[] vs = builder.GetVertices(); int outerEdgeLength = outside.Count(); int innerEdgeLength = inside.Count(); int outerIndex = 0; int innerIndex = 0; while (innerIndex < innerEdgeLength - 1 || outerIndex < outerEdgeLength - 1) { if (innerIndex < innerEdgeLength - 1) { if (outerIndex < outerEdgeLength - 1) { int id1 = outside.GetIndex(); int id2 = inside.GetIndex(); int id3 = outside.GetNext(); int id4 = inside.GetNext(); Vector3 P1 = vs[id1]; Vector3 P2 = vs[id2]; Vector3 P3 = vs[id3]; Vector3 P4 = vs[id4]; float dInner = (P4 - P1).sqrMagnitude; float dOuter = (P3 - P2).sqrMagnitude; if (dInner <= dOuter) { intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2); innerIndex++; inside.Move(); } else { intTrIndex = builder.WriteTriangle(intTrIndex, id1, id3, id2); outerIndex++; outside.Move(); } } else { int id1 = outside.GetIndex(); int id2 = inside.GetIndex(); int id4 = inside.GetNext(); intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2); innerIndex++; inside.Move(); } } else { int id1 = outside.GetIndex(); int id2 = inside.GetIndex(); int id3 = outside.GetNext(); intTrIndex = builder.WriteTriangle( intTrIndex, id1, id3, id2); outerIndex++; outside.Move(); } } return(intTrIndex); }
public bool Generate(Mesh startShape, Transform loc2WorldTrafo, Shader shader, out OutputMesh[] meshes, string specialMaterial) { Vector3[] vertices = new Vector3[startShape.vertices.Length]; for (int i = 0; i < vertices.Length; i++) vertices[i] = loc2WorldTrafo.TransformPoint(startShape.vertices[i]); if(!Prt4Unity.Generate(ctx, vertices, vertices.Length, startShape.triangles, startShape.triangles.Length, specialMaterial)) { meshes = null; return false; } Material[] materials = GetMaterials(shader); GetMeshes(materials, loc2WorldTrafo, out meshes); Prt4Unity.ReleaseMeshesAndMaterials(ctx); return true; }
public void Free() { used = false; tessellationOutput = null; outputMesh = null; }
public NetPolylineInternalIndicesArray(CPNSideEdge sideEdge, OutputMesh builder) { this.sideEdge = sideEdge; this.builder = builder; this.position = 0; }
// Retrieves meshes from last generate result and creates according Unity meshes void GetMeshes(Material[] materials, Transform loc2WorldTrafo, out OutputMesh[] meshes) { int numMeshes = Prt4Unity.GetMeshCount(ctx); meshes = new OutputMesh[numMeshes]; for(int i = 0; i < numMeshes; i++) { IntPtr name, pVertices, pNormals, pTexcoords; int numVertices; Prt4Unity.GetMesh(ctx, i, out name, out numVertices, out pVertices, out pNormals, out pTexcoords); OutputMesh outputMesh = new OutputMesh(); meshes[i] = outputMesh; outputMesh.mesh = new Mesh(); outputMesh.mesh.name = Marshal.PtrToStringUni(name); float[] floats = new float[numVertices * 3]; Marshal.Copy(pVertices, floats, 0, numVertices * 3); Vector3[] vertices = new Vector3[numVertices]; Vector3 preScale = loc2WorldTrafo.localScale; for (int v = 0; v < numVertices; v++) { vertices[v] = new Vector3(floats[3 * v + 0], floats[3 * v + 1], floats[3 * v + 2]); vertices[v] = loc2WorldTrafo.InverseTransformPoint(vertices[v]); vertices[v].x *= preScale.x; vertices[v].y *= preScale.y; vertices[v].z *= preScale.z; } outputMesh.mesh.vertices = vertices; Marshal.Copy(pNormals, floats, 0, numVertices * 3); Vector3[] normals = new Vector3[numVertices]; for(int v = 0; v < numVertices; v++) normals[v] = new Vector3(floats[3 * v + 0], floats[3 * v + 1], floats[3 * v + 2]); outputMesh.mesh.normals = normals; if(pTexcoords != IntPtr.Zero) { Marshal.Copy(pTexcoords, floats, 0, numVertices * 2); Vector2[] texcoords = new Vector2[numVertices]; for(int v = 0; v < numVertices; v++) texcoords[v] = new Vector2(floats[2 * v + 0], floats[2 * v + 1]); outputMesh.mesh.uv = texcoords; } int numSubMeshes = Prt4Unity.GetSubMeshCount(ctx, i); outputMesh.mesh.subMeshCount = (int)numSubMeshes; outputMesh.materials = new Material[numSubMeshes]; for(int s = 0; s < numSubMeshes; s++) { IntPtr pIndices; int numIndices, materialIndex; Prt4Unity.GetSubMesh(ctx, i, s, out pIndices, out numIndices, out materialIndex); int[] indices = new int[numIndices]; Marshal.Copy(pIndices, indices, 0, numIndices); outputMesh.mesh.SetTriangles(indices, (int)s); outputMesh.materials[s] = materials[materialIndex]; } } }
public bool Generate(Mesh startShape, Transform loc2WorldTrafo, Shader shader, out OutputMesh[] meshes) { ctx.SetAttributes(attributes); return ctx.Generate(startShape, loc2WorldTrafo, shader, out meshes, collisionMaterial); }