public void RetrieveInfos(CPNPolygon polygon) { CPNSideEdge[] polylines = polygon.sideEdges; int M1 = polylines[0].GetN(); int M2 = polylines[1].GetN(); int M3 = polylines[2].GetN(); this.M = M3 > M1 ? M3 : M1; this.M = M2 > M ? M2 : M; this.internalsN = (((M - 1) * (M - 2)) >> 1); if (M == 1) { this.trianglesN = 1; } else if (M == 2) { this.trianglesN = (M1 + M2 + M3 - 2); } else { this.trianglesN = (M - 3) * (M - 3) + M1 + M2 + M3 + 3 * (M - 3); } // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.retrieveInfos inputs M1:%d // M2:%d M3:%d evaluated M:%d internalsN:%d trianglesN:%d", // M1,M2,M3,M,internalsN,trianglesN); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR }
public void RetrieveInfos(CPNPolygon buildingPolygonData) { this.M = 0; int missing = 0; for (int i = 0; i < sides; i++) { int N = buildingPolygonData.sideEdges[i].GetN(); if (this.M < N) { this.M = N; } } for (int i = 0; i < sides; i++) { int N = buildingPolygonData.sideEdges[i].GetN(); missing += (M - N); } this.nInternals = 1 + sides * (((M)*(M - 1)) >> 1); //TODO : I think this is wrong. You miss a triangle when N is less then M, you know? this.nTriangles = sides * ((M * M)) - missing; }
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); }
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 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); }
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); }
public void RetrieveInfos(CPNPolygon polygon) { CPNSideEdge[] polylines = polygon.sideEdges; int M1 = polylines[0].GetN(); int M2 = polylines[1].GetN(); int M3 = polylines[2].GetN(); int M4 = polylines[3].GetN(); this.MV = M4 > M2 ? M4 : M2; this.MH = M3 > M1 ? M3 : M1; this.nInternals = (MH - 1) * (MV - 1); if (MV == 1 && MH == 1) { this.nTriangles = 2; } else { this.nTriangles = 2 * (MH - 2) * (MV - 2) + M1 + M2 + M3 + M4 + 2 * (MH - 2) + 2 * (MV - 2); } }
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 RetrieveInfos(CPNPolygon buildingPolygonData) { triangleStructure.RetrieveInfos(buildingPolygonData); }
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 void CreateTriangleTessellation(OutputMesh mesh, int internalsIndex, int facesIndex, CPNPolygon polygon) { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // internalsIndex:%d facesIndex:%d", internalsIndex, facesIndex); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR CPNSideEdge[] polylines = polygon.sideEdges; RetrieveInfos(polygon); int trPosition = facesIndex; if (M == 1) { trPosition = mesh.WriteTriangle(trPosition, polylines[0].GetIndex(0), polylines[1].GetIndex(0), polylines[2].GetIndex(0)); return; } else if (M == 2) { // int[] MS=new int[3]; MS[0] = polylines[0].GetN(); MS[1] = polylines[1].GetN(); MS[2] = polylines[2].GetN(); for (int i = 0; i < 3; i++) { int prev = i == 0 ? 2 : i - 1; if (MS[prev] == 2) { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // M == 2 i:%d trPosition:%d writing CASE 1",i,trPosition); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR trPosition = mesh.WriteTriangle(trPosition, polylines[i].GetIndex(0), polylines[i].GetIndex(1), polylines[prev].GetBackIndex(1)); } else if (MS[i] == 2) { int other = (i == 2 ? 0 : i + 1); if (MS[other] == 2) { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // M == 2 i:%d trPosition:%d writing CASE 2", i, // trPosition); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR trPosition = mesh.WriteTriangle(trPosition, polylines[i].GetIndex(0), polylines[i].GetIndex(1), polylines[other].GetIndex(1)); } else { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // M == 2 i:%d trPosition:%d writing CASE 3", i, // trPosition); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR trPosition = mesh.WriteTriangle(trPosition, polylines[i].GetIndex(0), polylines[i].GetIndex(1), polylines[other].GetIndex(1)); } } } if (MS[0] == 2 && MS[1] == 2 && MS[2] == 2) { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // M == 2 writing CASE 4"); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR trPosition = mesh.WriteTriangle(trPosition, polylines[0].GetIndex(1), polylines[1].GetIndex(1), polylines[2].GetIndex(1)); } // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // if(facesIndex+trianglesN!=trPosition) // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // ERROR on trianglesN facesIndex:%d trianglesN:%d trPosition:%d", // facesIndex, trianglesN, trPosition); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR return; } int innerVerticesPosition = internalsIndex; int rowPosition1 = innerVerticesPosition; int rowPosition2 = innerVerticesPosition + M - 2; // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // writing Internals innerVerticesPosition:%d rowPosition1:%d // rowPosition2:%d", innerVerticesPosition, rowPosition1, rowPosition2); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR for (int i = 0; i < M - 3; i++) { for (int j_ = 0; j_ < M - 4 - i; j_++) { trPosition = mesh.WriteTriangle(trPosition, rowPosition1 + j_, rowPosition1 + j_ + 1, rowPosition2 + j_); trPosition = mesh.WriteTriangle(trPosition, rowPosition2 + j_, rowPosition1 + j_ + 1, rowPosition2 + j_ + 1); } int j = M - 4 - i; trPosition = mesh.WriteTriangle(trPosition, rowPosition1 + j, rowPosition1 + j + 1, rowPosition2 + j); rowPosition1 = rowPosition2; rowPosition2 = rowPosition2 + (M - 3 - i); // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // writing Internals rowPosition1:%d rowPosition2:%d", rowPosition1, // rowPosition2); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR } first[0] = innerVerticesPosition; first[1] = innerVerticesPosition + M - 3; first[2] = innerVerticesPosition + (((M - 1) * (M - 2)) >> 1) - 1; move[0] = 1; move[1] = M - 2; move[2] = -1; deltaMove[0] = 0; deltaMove[1] = -1; deltaMove[2] = -1; int count = M - 2; // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // preparing Sides count:%d first:[%d,%d,%d] move:[%d,%d,%d] // deltaMove:[%d,%d,%d]", // count, first[0], first[1], first[2], move[0], move[1], move[2], // deltaMove[0], deltaMove[1], deltaMove[2]); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR for (int i = 0; i < 3; i++) { int N = polylines[i].GetN(); if (N >= 2) { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // side Triangle case A trPosition:%d", trPosition); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR meshIndicesArray.Setup(first[i], move[i], deltaMove[i], count, mesh, TriangleMeshStructure.DEFAULT_VERTICES_LAYER); NetPolylineInternalIndicesArray npi = new NetPolylineInternalIndicesArray(polylines[i], mesh); trPosition = MeshStructures.CreateSideTriangles(mesh, meshIndicesArray, npi, trPosition); } else if (N == 1) { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // side Triangle case B trPosition:%d (Begin)", trPosition); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR meshIndicesArray.Setup(first[i], move[i], deltaMove[i], count, mesh, DEFAULT_VERTICES_LAYER); NetPolylineIndicesArray npi = new NetPolylineIndicesArray(polylines[i], mesh); trPosition = MeshStructures.CreateSideTriangles(mesh, meshIndicesArray, npi, trPosition); // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // side Triangle case B trPosition:%d (End)", trPosition); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR } int prev = i == 0 ? 2 : i - 1; int prevN = polylines[prev].GetN(); if (N > 1 && prevN > 1) { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // writing corner Index as Quad a:%d b:%d c:%d d:%d", // polylines[i].getIndex(1),first[i], // polylines[prev].getBackIndex(1), polylines[i].getIndex(0)); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR if (prevN + N < 1.5f * M) { trPosition = mesh.WriteQuad(trPosition, polylines[i].GetIndex(0), polylines[i].GetIndex(1), first[i], polylines[prev].GetBackIndex(1)); } else { trPosition = mesh.WriteQuad(trPosition, polylines[i].GetIndex(1), first[i], polylines[prev].GetBackIndex(1), polylines[i].GetIndex(0)); } } else if (polylines[i].GetN() > 1) { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // writing corner Index as Triangle a:%d b:%d c:%d ", // polylines[i].getIndex(0), polylines[i].getIndex(1), // first[i]); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR trPosition = mesh.WriteTriangle(trPosition, polylines[i].GetIndex(0), polylines[i].GetIndex(1), first[i]); } else if (polylines[prev].GetN() > 1) { // #ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // writing corner Index as Triangle a:%d b:%d c:%d ", // polylines[i].getIndex(0), // first[i],polylines[i].getBackIndex(1)); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR trPosition = mesh.WriteTriangle(trPosition, polylines[i].GetIndex(0), first[i], polylines[prev].GetBackIndex(1)); } } // # // ifdef SF_RAW_DEBUG_TRIANGLE_TESSELLATOR // if(facesIndex+trianglesN!=trPosition) // // printf("\nSFCPNTrianglesMeshStructure.createTriangleTessellation // ERROR on trianglesN facesIndex:%d trianglesN:%d trPosition:%d", // facesIndex, trianglesN, trPosition); // #endif //SF_RAW_DEBUG_TRIANGLE_TESSELLATOR }
public void UdpdateContent(OutputMesh mesh, CPNPolygon polygon, int internalsIndex, int facesIndex, bool doUpdateStructure = true) { quadStructure.RetrieveInfos(polygon); int MV = quadStructure.GetMV(); int MH = quadStructure.GetMH(); float stepV = 1.0f / MV; float stepH = 1.0f / MH; CPNSideEdge[] polylines = polygon.sideEdges; buffer0.writeWithGuide(polylines[0], MH, mesh, evaluator); buffer1.writeWithGuide(polylines[1], MV, mesh, evaluator); buffer2.writeWithGuide(polylines[2], MH, mesh, evaluator); buffer3.writeWithGuide(polylines[3], MV, mesh, evaluator); edgeSurface0.Set(buffer0, buffer3, buffer1); edgeSurface1.Set(buffer1, buffer0, buffer2); edgeSurface2.Set(buffer2, buffer1, buffer3); edgeSurface3.Set(buffer3, buffer2, 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[3] * ks[2] * ks[3]; float l4 = ks[3] * ks[0] * ks[3] * ks[0]; prepareMemory(MH, MV); for (int i = 1; i < MV; i++) { for (int j = 1; j < MH; j++) { float U = (j) * stepH; float V = (i) * stepV; Vector3 V1 = edgeSurface0.evalVertex(j, i); Vector3 V2 = edgeSurface1.evalVertex(i, MH - j); Vector3 V3 = edgeSurface2.evalVertex(MH - j, MV - i); Vector3 V4 = edgeSurface3.evalVertex(MV - i, j); Vector3 V1uv = edgeSurface0.evalUV(j, i); Vector3 V2uv = edgeSurface1.evalUV(i, MH - j); Vector3 V3uv = edgeSurface2.evalUV(MH - j, MV - i); Vector3 V4uv = edgeSurface3.evalUV(MV - i, j); float UM = 1 - U; float VM = 1 - V; float a1 = U * U * VM * VM * UM * UM * l1 /** buffer0.thickness*/; float a2 = VM * VM * U * U * V * V * l2 /** buffer1.thickness*/; float a3 = UM * UM * V * V * U * U * l3 /** buffer2.thickness*/; float a4 = V * V * UM * UM * VM * VM * l4 /** buffer3.thickness*/; #if DEBUG if (TriangleInterpolator4.interpolationCorner != 0) { switch (TriangleInterpolator4.interpolationCorner) { case 1: a1 = 1; a2 = 0; a3 = 0; a4 = 0; break; case 2: a1 = 0; a2 = 1; a3 = 0; a4 = 0; break; case 3: a1 = 0; a2 = 0; a3 = 1; a4 = 0; break; case 4: a1 = 0; a2 = 0; a3 = 0; a4 = 1; break; } } #endif float rec = 1.0f / (a1 + a2 + a3 + a4); a1 *= rec; a2 *= rec; a3 *= rec; a4 *= rec; Vector3 vertex = a1 * V1 + a2 * V2 + a3 * V3 + a4 * V4; //Vector3 vertex = V3; Vector3 uv = a1 * V1uv + a2 * V2uv + a3 * V3uv + a4 * V4uv; //Vector3 uv = V3uv; int memoryIndex = j + i * (MH + 1); memory.vertices[memoryIndex] = vertex; memory.uv[memoryIndex] = uv; } } int index = internalsIndex; for (int i = 1; i < MV; i++) { for (int j = 1; j < MH; j++) { int rowIndex = i * (MH + 1); int rowIndexPrev = (i - 1) * (MH + 1); int rowIndexNext = (i + 1) * (MH + 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]; dSdu = dSdu.normalized; dSdv = dSdv.normalized; Vector3 normal = Vector3.Cross(dSdu, dSdv).normalized; //Debug.Log("dSdu: (" + dSdu.x + "," + dSdu.y + "," + dSdu.z + ") dSdv:" // + dSdv.x + "," + dSdv.y + "," + dSdv.z + ") Vector3.Cross(dSdu, dSdv).magnitude:" + Vector3.Cross(dSdu, dSdv).magnitude); //Debug.Log("Normal (" + normal.x + "," + normal.y + "," + normal.z + ")"); //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(index, vertex, normal, uv, tangent); index++; } } if (doUpdateStructure) { quadStructure.CreateQuadTessellation(mesh, internalsIndex, facesIndex, polygon); } }
public void UdpdateContent(OutputMesh mesh, CPNPolygon buildingPolygonData, int internalsIndex, int facesIndex, bool doUpdateStructure = true) { RetrieveInfos(buildingPolygonData); this.step = 1.0f / M; totalInterpolationStep = M / relativeTriangleFactorX; interpolationSteps = (int)(totalInterpolationStep); if (interpolationSteps * relativeTriangleFactorX < M) { interpolationSteps++; } Vector3 vertex = Vector3.zero; Vector3 uv = Vector3.zero; int centerPiecePosition = 0; int verticesLayer = 0;// mesh.FindLayer(BufferType.VERTICES); //int normalsLayer = mesh.FindLayer(BufferType.NORMALS); //cornerSurfacesSet.SetNormalsLayer(normalsLayer); CPNSideEdge[] polylines = buildingPolygonData.sideEdges; for (int i = 0; i < sides; i++) { buffers[i].writeWithGuide(polylines[i], interpolationSteps, step * relativeTriangleFactorX, mesh, evaluator); backBuffers[i].writeWithGuideBack(polylines[i], interpolationSteps, step * relativeTriangleFactorX, mesh, evaluator); } prepareMemory(M, polylines, mesh); //int position = internalsIndex; int triangleSize = ((M)*(M + 1)) >> 1; for (int corner = 0; corner < sides; corner++) { int next = corner == sides - 1 ? 0 : corner + 1; float p1x = cos_[corner]; float p2x = cos_[next]; float p1y = sin_[corner]; float p2y = sin_[next]; int relativeMemoryIndex = triangleSize * corner + M; for (int i = 1; i <= M - 1; i++) { for (int j = 0; j <= M - 1 - i; j++) { float innerU = step * j; float innerV = step * i; float innerW = 1 - innerU - innerV; float innerX_ = innerW * p1x + innerU * p2x; float innerY_ = innerW * p1y + innerU * p2y; vertex = EvalVertex(mesh, buildingPolygonData, innerX_, innerY_, out uv); memory.vertices[relativeMemoryIndex] = vertex; memory.uv[relativeMemoryIndex] = uv; relativeMemoryIndex++; //position++; } } } vertex = EvalVertex(mesh, buildingPolygonData, 0, 0, out uv); //mesh.SetValue(0, position, vertex); memory.vertices[triangleSize * sides] = vertex; memory.uv[triangleSize * sides] = uv; //position++; //Phase 2 Normals and Tangents Evaluation int position = internalsIndex; for (int corner = 0; corner < sides; corner++) { int prev = corner == 0 ? sides - 1 : corner - 1; int next = corner == sides - 1 ? 0 : corner + 1; int relativeMemoryIndex = triangleSize * corner; int nextPatchRelativeMemoryIndex = triangleSize * next; int prevPatchRelativeMemoryIndex = triangleSize * prev; slicePosition[corner] = position; for (int i = 1; i <= M - 1; i++) { for (int j = 0; j <= M - 1 - i; j++) { int rowIndex = relativeMemoryIndex + M * i - (((i) * (i - 1)) >> 1); int prevRowIndex = relativeMemoryIndex + M * (i - 1) - (((i - 1) * (i - 2)) >> 1); int nextRowIndex = relativeMemoryIndex + M * (i + 1) - (((i + 1) * (i)) >> 1); int index = rowIndex + j; vertex = memory.vertices[index]; uv = memory.uv[index]; int duIndexA = 0, duIndexB = 0, dvIndexA = 0, dvIndexB = 0; if (j > 0 && j < M - 1 - i) { duIndexA = prevRowIndex + j; duIndexB = nextRowIndex + j; dvIndexA = nextRowIndex + j - 1; dvIndexB = prevRowIndex + j + 1; } else if (i < M - 1) { if (j == M - 1 - i) { int nextPatchnextRowIndex = nextPatchRelativeMemoryIndex + M * (i + 1) - (((i + 1) * (i)) >> 1); duIndexA = prevRowIndex + j; duIndexB = nextPatchnextRowIndex; dvIndexA = nextRowIndex + j - 1; dvIndexB = prevRowIndex + j + 1; } else if (j == 0) { int prevPatchprevRowIndex = prevPatchRelativeMemoryIndex + M * (i - 1) - (((i - 1) * (i - 2)) >> 1); duIndexA = prevRowIndex + j; duIndexB = nextRowIndex + j; dvIndexA = prevPatchprevRowIndex + M - i; dvIndexB = prevRowIndex + j + 1; } } else { int prevPatchprevRowIndex = prevPatchRelativeMemoryIndex + M * (i - 1) - (((i - 1) * (i - 2)) >> 1); duIndexA = prevRowIndex + j; duIndexB = triangleSize * sides; dvIndexA = prevPatchprevRowIndex + M - i; dvIndexB = prevRowIndex + j + 1; } Vector3 dSdu = memory.vertices[duIndexB] - memory.vertices[duIndexA]; Vector3 dSdv = memory.vertices[dvIndexB] - memory.vertices[dvIndexA]; Vector3 normal = Vector3.Cross(dSdu, dSdv).normalized; //Tangent Vector3 dTxdu = memory.uv[duIndexB] - memory.uv[duIndexA]; Vector3 dTxdv = memory.uv[dvIndexB] - memory.uv[dvIndexA]; Vector3 tangent = getTangent(dSdu, dSdv, dTxdu, dTxdv); mesh.SetPNUV(position, vertex, normal, uv, tangent); //relativeMemoryIndex++; position++; } } } { int duIndexA = 2 * triangleSize - 1; int duIndexB = 4 * triangleSize - 1; int dvIndexA = triangleSize - 1; int dvIndexB = 3 * triangleSize - 1; vertex = memory.vertices[triangleSize * sides]; uv = memory.uv[triangleSize * sides]; Vector3 dSdu = memory.vertices[duIndexB] - memory.vertices[duIndexA]; Vector3 dSdv = memory.vertices[dvIndexB] - memory.vertices[dvIndexA]; Vector3 normal = Vector3.Cross(dSdu, dSdv).normalized; //Tangent Vector3 dTxdu = memory.uv[duIndexB] - memory.uv[duIndexA]; Vector3 dTxdv = memory.uv[dvIndexB] - memory.uv[dvIndexA]; Vector3 tangent = getTangent(dSdu, dSdv, dTxdu, dTxdv); mesh.SetPNUV(position, vertex, normal, uv, tangent); } centerPiecePosition = position; position++; int trPosition = facesIndex; for (int corner = 0; corner < sides; corner++) { int next = corner == sides - 1 ? 0 : corner + 1; if (M > 1) { int rowPosition1 = slicePosition[corner]; int rowPosition2 = slicePosition[corner] + M - 1; int rowPosition1Next = slicePosition[next]; int rowPosition2Next = slicePosition[next] + M - 1; for (int i = 0; i < M - 2; i++) { for (int j_ = 0; j_ < M - 3 - i; j_++) { trPosition = mesh.WriteTriangle(trPosition, rowPosition1 + j_, rowPosition2 + j_, rowPosition1 + j_ + 1); trPosition = mesh.WriteTriangle(trPosition, rowPosition1 + j_ + 1, rowPosition2 + j_, rowPosition2 + j_ + 1); } int j = M - 3 - i; trPosition = mesh.WriteTriangle(trPosition, rowPosition1 + j, rowPosition2 + j, rowPosition1 + j + 1); trPosition = mesh.WriteTriangle(trPosition, rowPosition2 + j, rowPosition2Next, rowPosition1 + j + 1); trPosition = mesh.WriteTriangle(trPosition, rowPosition1 + j + 1, rowPosition2Next, rowPosition1Next); rowPosition1 = rowPosition2; rowPosition2 = rowPosition2 + M - 2 - i; rowPosition1Next = rowPosition2Next; rowPosition2Next = rowPosition2Next + M - 2 - i; } trPosition = mesh.WriteTriangle(trPosition, rowPosition1, centerPiecePosition, rowPosition1Next); meshIndicesArray.Setup(slicePosition[corner], 1, M, slicePosition[next], mesh, verticesLayer); int polylineIndex = sides - 1 - corner; NetPolylineIndicesArray npi = new NetPolylineIndicesArray(polylines[polylineIndex], mesh, true); trPosition = MeshStructures.CreateSideTriangles(mesh, npi, meshIndicesArray, trPosition); } else { trPosition = mesh.WriteTriangle(trPosition, polylines[corner].GetIndex(0), centerPiecePosition, polylines[corner].GetBackIndex(0)); } } }
public void UdpdateContent(OutputMesh mesh, CPNPolygon polygon, int internalsIndex, int facesIndex, bool doUpdateStructure = true) { quadStructure.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); buffer3.requestProperties(countProperties); int MV = quadStructure.GetMV(); int MH = quadStructure.GetMH(); float stepV = 1.0f / MV; float stepH = 1.0f / MH; CPNSideEdge[] polylines = polygon.sideEdges; buffer0.writeWithGuide(polylines[0], MH, mesh, evaluator); buffer1.writeWithGuide(polylines[1], MV, mesh, evaluator); buffer2.writeWithGuide(polylines[2], MH, mesh, evaluator); buffer3.writeWithGuide(polylines[3], MV, mesh, evaluator); edgeSurface0.Set(buffer0, buffer3, buffer1); edgeSurface1.Set(buffer1, buffer0, buffer2); edgeSurface2.Set(buffer2, buffer1, buffer3); edgeSurface3.Set(buffer3, buffer2, buffer0); //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[3] * ks[2] * ks[3]; //float l4 = ks[3] * ks[0] * ks[3] * ks[0]; float l1 = GetBufferLength(buffer0); float l2 = GetBufferLength(buffer1); float l3 = GetBufferLength(buffer2); float l4 = GetBufferLength(buffer3); prepareMemory(MH, MV); int index = internalsIndex; for (int i = 1; i < MV; i++) { for (int j = 1; j < MH; j++) { float U = (j) * stepH; float V = (i) * stepV; float UM = 1 - U; float VM = 1 - V; float a1 = U * U * VM * VM * UM * UM * l1 /** buffer0.thickness*/; float a2 = VM * VM * U * U * V * V * l2 /** buffer1.thickness*/; float a3 = UM * UM * V * V * U * U * l3 /** buffer2.thickness*/; float a4 = V * V * UM * UM * VM * VM * l4 /** buffer3.thickness*/; #if DEBUG if (TriangleInterpolator4.interpolationCorner != 0) { switch (TriangleInterpolator4.interpolationCorner) { case 1: a1 = 1; a2 = 0; a3 = 0; a4 = 0; break; case 2: a1 = 0; a2 = 1; a3 = 0; a4 = 0; break; case 3: a1 = 0; a2 = 0; a3 = 1; a4 = 0; break; case 4: a1 = 0; a2 = 0; a3 = 0; a4 = 1; break; } } #endif float rec = 1.0f / (a1 + a2 + a3 + a4); a1 *= rec; a2 *= rec; a3 *= rec; a4 *= rec; Vector3 V1 = edgeSurface0.evalVertex(j, i); Vector3 V2 = edgeSurface1.evalVertex(i, MH - j); Vector3 V3 = edgeSurface2.evalVertex(MH - j, MV - i); Vector3 V4 = edgeSurface3.evalVertex(MV - i, j); Vector3 vertex = a1 * V1 + a2 * V2 + a3 * V3 + a4 * V4; int memoryIndex = j + i * (MH + 1); memory.vertices[memoryIndex] = vertex; if (useUV) { Vector3 V1uv = edgeSurface0.evalUV(j, i); Vector3 V2uv = edgeSurface1.evalUV(i, MH - j); Vector3 V3uv = edgeSurface2.evalUV(MH - j, MV - i); Vector3 V4uv = edgeSurface3.evalUV(MV - i, j); //Vector3 vertex = V3; Vector3 uv = a1 * V1uv + a2 * V2uv + a3 * V3uv + a4 * V4uv; //Vector3 uv = V3uv; memory.uv[memoryIndex] = uv; } for (int k = 0; k < countProperties; k++) { Vector3 V1propK = edgeSurface0.evalProperty(k, j, i); Vector3 V2propK = edgeSurface1.evalProperty(k, i, MH - j); Vector3 V3propK = edgeSurface2.evalProperty(k, MH - j, MV - i); Vector3 V4propK = edgeSurface3.evalProperty(k, MV - i, j); Vector3 propK = a1 * V1propK + a2 * V2propK + a3 * V3propK + a4 * V4propK; mesh.SetProperty3(index, k, propK); } index++; } } index = internalsIndex; for (int i = 1; i < MV; i++) { for (int j = 1; j < MH; j++) { int rowIndex = i * (MH + 1); int rowIndexPrev = (i - 1) * (MH + 1); int rowIndexNext = (i + 1) * (MH + 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) { Vector3 dSdu = memory.vertices[memoryIndex + 1] - memory.vertices[memoryIndex - 1]; Vector3 dSdv = memory.vertices[rowIndexNext + j] - memory.vertices[rowIndexPrev + j]; dSdu = dSdu.normalized; dSdv = dSdv.normalized; 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(index, vertex, normal, uv, tangent); index++; } } if (doUpdateStructure) { quadStructure.CreateQuadTessellation(mesh, internalsIndex, facesIndex, polygon); } }