public Vector3 EvalAxis(CPNGuide guide) { if (guide.GetN() == -1) { int N = guide.GetIndices().Length; if (N > 0) { Vector3 pDev1 = (guide.vBuffer[1] - guide.vBuffer[0]).normalized; Vector3 pPerp1 = Vector3.Cross(pDev1, guide.nBuffer[0]).normalized; Vector3 pDev2 = (guide.vBuffer[N - 1] - guide.vBuffer[N - 2]).normalized; Vector3 pPerp2 = Vector3.Cross(pDev2, guide.nBuffer[N - 1]).normalized; Vector3 pPerp = ((T1 + T2) * pPerp1 + (T3 + T4) * pPerp2); return(pPerp.normalized); } else { return(Vector3.zero); } } Vector3 Dev1 = (guide.vBuffer[1] - guide.vBuffer[0]).normalized; Vector3 Perp1 = Vector3.Cross(Dev1, guide.firstNormal).normalized; Vector3 Dev2 = (guide.vBuffer[3] - guide.vBuffer[2]).normalized; Vector3 Perp2 = Vector3.Cross(Dev2, guide.lastNormal).normalized; Vector3 Perp = ((T1 + T2) * Perp1 + (T3 + T4) * Perp2); return(Perp.normalized); }
public float EvalAt(float t, CPNSideEdge sideEdge) { int N = sideEdge.guide.Length; float index = t * N; this.sideEdgeIndex = (int)index; if (sideEdgeIndex < 0) { sideEdgeIndex = 0; } if (sideEdgeIndex >= N) { sideEdgeIndex = N - 1; } t = index - this.sideEdgeIndex; /*if(sideEdgeIndex<0 || sideEdgeIndex>=sideEdge.direct.Length) * Debug.Log("N " + N + " sideEdgeIndex:" + sideEdgeIndex + " sideEdge.guide.Length:" + sideEdge.guide.Length + " this.sideEdgeIndex:"+ this.sideEdgeIndex+" t:"+t);*/ bool direct = sideEdge.direct[sideEdgeIndex]; CPNGuide guide = sideEdge.guide[sideEdgeIndex]; if (!direct) { t = 1 - t; } this.direction = direct ? 1 : -1; float updatedT = EvalAt(t, guide); updatedT = direct ? updatedT : 1 - updatedT; float sideEdgeT = sideEdge.position[sideEdgeIndex] + updatedT * sideEdge.size[sideEdgeIndex]; return(sideEdgeT); }
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 Vector3 EvalDev(CPNGuide guide) { if (guide.GetN() == -1) { return((guide.vBuffer[this.polylineIndex + 1] - guide.vBuffer[this.polylineIndex]) * (guide.GetIndices().Length - 1)); } float tp = t + 0.001f; float tmp = 1 - tp; float T1p = tmp * tmp * tmp; float T2p = 3 * tp * tmp * tmp; float T3p = 3 * tp * tp * tmp; float T4p = tp * tp * tp; float w2 = guide.w2; float w3 = guide.w3; Vector3[] vBuffer = guide.vBuffer; Vector3 F1 = (vBuffer[0] * T1 + vBuffer[1] * T2 * w2 + vBuffer[2] * T3 * w3 + vBuffer[3] * T4) / (T1 + T2 * w2 + T3 * w3 + T4); Vector3 F2 = (vBuffer[0] * T1p + vBuffer[1] * T2p * w2 + vBuffer[2] * T3p * w3 + vBuffer[3] * T4p) / (T1p + T2p * w2 + T3p * w3 + T4p); return((F2 - F1) * (1000f)); }
public Vector3 EvalUV(CPNGuide guide) { if (guide.GetN() == -1) { return(guide.uvsBuffer[this.polylineIndex] * T1 + guide.uvsBuffer[this.polylineIndex + 1] * T2); } Vector3[] uvsBuffer = guide.uvsBuffer; return(uvsBuffer[0] * T1 + uvsBuffer[1] * T2 + uvsBuffer[2] * T3 + uvsBuffer[3] * T4); }
public Vector3 EvalNormal(CPNGuide guide) { if (guide.GetN() == -1) { return(guide.vBuffer[this.polylineIndex] * T1 + guide.vBuffer[this.polylineIndex + 1] * T2); } Vector3 Dev = EvalDev(guide); return(EvalNormal(guide, Dev)); }
private Vector3 GetTangent(CPNGuide guide, Vector3 dev, Vector3 normal) { Vector3 DCTdt = EvalUVDev(guide); Vector3 DCTds = Vector3.Cross(DCTdt, Vector3.forward); Vector3 DCds = Vector3.Cross(dev, normal); float det = DCTdt.x * DCTds.y - DCTdt.y * DCTds.x; Vector3 tangent = (dev * DCTds.y - DCds * DCTdt.y).normalized; return(det > 0 ? tangent : -tangent); }
public Vector3 EvalProperty(CPNGuide guide, int index) { if (guide.GetN() == -1) { return(guide.propertiesBuffer[index][this.polylineIndex] * T1 + guide.propertiesBuffer[index][this.polylineIndex + 1] * T2); } Vector3[] b = guide.propertiesBuffer[index]; return(b[0] * T1 + b[1] * T2 + b[2] * T3 + b[3] * T4); }
public void Set(CPNGuide guide, bool direct) { this.guide = new CPNGuide[] { guide }; this.direct = new bool[] { direct }; this.position = new float[] { 0 }; this.size = new float[] { 1 }; int n = guide.GetN(); this.skip = n == 0; n = (n == -1) ? guide.GetIndices().Length - 1 : n; this.N = n; }
public Vector3 EvalVertex(CPNGuide guide) { if (guide.GetN() == -1) { return(guide.vBuffer[this.polylineIndex] * T1 + guide.vBuffer[this.polylineIndex + 1] * T2); } Vector3[] vBuffer = guide.vBuffer; float w2 = guide.w2; float w3 = guide.w3; Vector3 F = (vBuffer[0] * T1 + vBuffer[1] * T2 * w2 + vBuffer[2] * T3 * w3 + vBuffer[3] * T4); return(F * this.recG); }
/* * public int WriteRotationAt(int position, float[] rots, int direction) * { * int rotLength = this.rotations.Length; * if (direction > 0) * { * for (int i = 0; i < rotLength; i++) * { * rots[position + i] = this.rotations[i]; * } * } * else * { * for (int i = 0; i < rotLength; i++) * { * rots[position + i] = this.rotations[rotLength - 1 - i]; * } * } * return position + rotLength; * }*/ public static CPNGuide Build(int[] indices /*, float[] rots*/, Vector3 suggestedStartDev, Vector3 suggestedEndDev, float tessellationStepA, float tessellationStepB) { CPNGuide built = new CPNGuide { indices = indices, N = indices.Length - 1, //rotations = rots, //suggestedStartDev = suggestedStartDev, //suggestedEndDev = suggestedEndDev, tessellationStepA = tessellationStepA, tessellationStepB = tessellationStepB }; return(built); }
public void SwitchDirection() { int half = this.guide.Length >> 1; for (int i = 0; i < half; i++) { CPNGuide tmp = guide[i]; guide[i] = guide[guide.Length - i - 1]; guide[guide.Length - i - 1] = tmp; bool tmpD = direct[i]; direct[i] = direct[guide.Length - i - 1]; direct[guide.Length - i - 1] = tmpD; } for (int i = 0; i < direct.Length; i++) { direct[i] = !direct[i]; } }
/* * if (linear) { //forgot linear evaluation.. uff. * mesh.SetVertex(index, vBuffer[0] * t + vBuffer[1] * tm); * if (uvAvailable) * mesh.SetUV(index, uvsBuffer[0] * t + uvsBuffer[1] * tm); * if (nsAvailable) * { * * Vector3 Dev = vBuffer[1] - vBuffer[0]; * Vector3 Perp = ((1 - t) * perpA + t * perpB).normalized; * * Vector3 normal = Vector3.Normalize(Vector3.Cross(Dev, Perp)).normalized; * * mesh.SetNormal(index, normal); * } * }*/ public float EvalAt(float t, CPNGuide guide) { if (guide.GetN() == -1) //Polylines { int N = guide.GetIndices().Length - 1; if (N > 1) { float T = t * N; int pI = (int)T; pI = (pI == N) ? pI - 1 : pI; this.polylineIndex = pI; this.T2 = T - pI; this.T1 = 1 - this.T2; } else { this.polylineIndex = 0; } return(t); } float j = t * guide.GetN(); t = j * (guide.tessellationStepA + j * guide.tessellationStepB); this.t = t; this.tm = 1 - this.t; this.T1 = tm * tm * tm; this.T2 = 3 * t * tm * tm; this.T3 = 3 * t * t * tm; this.T4 = t * t * t; float w2 = guide.w2; float w3 = guide.w3; this.G = (T1 + T2 * w2 + T3 * w3 + T4); this.recG = 1.0f / G; return(t); }
private float approximateGuideSize(CPNGuide guide) { CPNGuideEvaluator evaluator = new CPNGuideEvaluator(); int STEPS = 8; float step = 1.0f / STEPS; Vector3 preV = guide.vBuffer[0]; float distance = 0; for (int i = 1; i <= STEPS; i++) { evaluator.EvalAt(i * step, guide); Vector3 V = evaluator.EvalVertex(guide); distance += Vector3.Distance(V, preV); preV = V; } if (distance == 0) { distance = 0.001f; } return(distance); }
public Vector3 EvalUVDev(CPNGuide guide) { if (guide.GetN() == -1) { return(guide.uvsBuffer[this.polylineIndex + 1] - guide.uvsBuffer[this.polylineIndex]); } float tp = t + 0.001f; float tmp = 1 - tp; float T1p = tmp * tmp * tmp; float T2p = 3 * tp * tmp * tmp; float T3p = 3 * tp * tp * tmp; float T4p = tp * tp * tp; Vector3[] uvsBuffer = guide.uvsBuffer; Vector3 F1 = (uvsBuffer[0] * T1 + uvsBuffer[1] * T2 + uvsBuffer[2] * T3 + uvsBuffer[3] * T4); Vector3 F2 = (uvsBuffer[0] * T1p + uvsBuffer[1] * T2p + uvsBuffer[2] * T3p + uvsBuffer[3] * T4p); return((F2 - F1) * 1000); }
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 Vector3 EvalNormal(CPNGuide guide, Vector3 Dev) { if (guide.GetN() == -1) { Vector3 n = guide.nBuffer[this.polylineIndex] * T1 + guide.nBuffer[this.polylineIndex + 1] * T2; n = n - Vector3.Dot(Dev, n) * Dev; n = n.normalized; return(n); } Dev = Dev.normalized; Vector3 AN = guide.firstNormal; Vector3 ABN = guide.edgeNormal; Vector3 BN = guide.lastNormal; Vector3 normal = tm * tm * AN + 2 * t * tm * (2 * ABN - 0.5f * AN - 0.5f * BN) + t * t * BN; normal = normal - Vector3.Dot(Dev, normal) * Dev; normal = normal.normalized; /*Vector3 Dev1 = (guide.vBuffer[1] - guide.vBuffer[0]).normalized; * Vector3 Perp1 = Vector3.Cross(Dev1, guide.firstNormal).normalized; * Perp1 = Perp1 * guide.rotCosF + Dev1 * guide.rotSinF; * * Vector3 Dev2 = (guide.vBuffer[3] - guide.vBuffer[2]).normalized; * Vector3 Perp2 = Vector3.Cross(Dev2, guide.lastNormal).normalized; * Perp2 = Perp2 * guide.rotCosL + Dev2 * guide.rotSinL; * * Vector3 Perp = ((T1 + T2) * Perp1 + (T3 + T4) * Perp2); * * Vector3 normal = Vector3.Cross(Perp, Dev).normalized;*/ return(normal); }
public void EvaluateEdge(CurvedPolygonsNet net, OutputMesh mesh, CPNGuide guide, short edgeLength, short[] edge, int edgeIndex, short[] edgeHints, float[] edgeWeights, int[] edgeProfile, int realEdgeIndex) { bool isLinear = edgeLength == 2; bool uvAvailable = net.GetUv() != null && net.GetUv().Length != 0 && mesh.DoUseUVs(); int countP = mesh.CountProperties(); short[] tessellationDegrees = CPNGuide_loqs; if (isLinear) { FillBufferWithLine(guide.vBuffer, net.GetVertices(), edge, edgeIndex); if (uvAvailable) { FillBufferWithLine(guide.uvsBuffer, net.GetUv(), edge, edgeIndex); } guide.PreparePropertiesBuffers(countP); for (int k = 0; k < countP; k++) { FillBufferWithLine(guide.propertiesBuffer[k], net.GetProperties3()[k], edge, edgeIndex); } } else { FillBuffer(guide.vBuffer, net.GetVertices(), edge, edgeIndex); if (uvAvailable) { FillBuffer(guide.uvsBuffer, net.GetUv(), edge, edgeIndex); } guide.PreparePropertiesBuffers(countP); for (int k = 0; k < countP; k++) { FillBuffer(guide.propertiesBuffer[k], net.GetProperties3()[k], edge, edgeIndex); } } //if (tgAvailable) //Avoid tangents for now // FillBuffer(linear, polyline.tgsBuffer, net.GetTangents(), edge, edgeIndex); int handleIndex = (realEdgeIndex) << 1; guide.w2 = edgeWeights[handleIndex + 0]; guide.w3 = edgeWeights[handleIndex + 1]; guide.edgeNormal = net.GetNormals()[net.GetNumberOfVertices() + realEdgeIndex]; guide.firstNormal = net.GetNormals()[edge[edgeIndex + 0]]; guide.lastNormal = net.GetNormals()[edge[edgeIndex + (isLinear? 1 : 3)]]; //float r = edgeRots == null ? 0 : edgeRots[edgeProfileIndex]; //float r3 = edgeRots == null ? 0 : edgeRots[handleIndex + 1]; int N1 = 1; int N2 = 1; if (!isLinear) { N1 = tessellationDegrees[edgeHints[handleIndex + 0]]; N2 = tessellationDegrees[edgeHints[handleIndex + 1]]; } int N = guide.GetN(); float c = (2.0f * N1 * N2) / (N * (N1 + N2)); guide.tessellationStepA = c / N1; guide.tessellationStepB = c * 0.5f * (N1 - N2) / (N1 * N2 * N * 1.0f); int edgeInternal = edgeProfile[((realEdgeIndex) << 2) + 2]; float step = 1.0f / N; for (int j = 1; j < N; j++) { int index = edgeInternal + j - 1; EvalAt(j * step, guide); mesh.SetVertex(index, EvalVertex(guide)); if (uvAvailable) { mesh.SetUV(index, EvalUV(guide)); } for (int k = 0; k < countP; k++) { mesh.SetProperty3(index, k, EvalProperty(guide, k)); } } }