public virtual bool EditLoad(LEditTextFile file) { Reset(); file.SkipLine(_Key_ConvexDataHead); mFlags = file.LoadValueLine <uint>(_Key_ConvexFlag); int vertnum = file.LoadValueLine <int>(_Key_VertexNum); for (int i = 0; i < vertnum; i++) { Vector3 vec = file.LoadVector3Line(_Key_Vertex); mLstVertices.Add(vec); } int facenum = file.LoadValueLine <int>(_Key_FaceNum); for (int i = 0; i < facenum; i++) { CovFace face = new CovFace(); face.EditLoad(file); mLstCovFace.Add(face); } //mAABBDirty = true; return(true); }
public CovFace GetNeighborFace(CovFace face, int vID1, int vID2) { for (int i = 0; i < GetFaceNum(); i++) { CovFace cface = GetFace(i); if (cface == face) { continue; } int j; for (j = 0; j < cface.GetVNum() - 1; j++) { if ((cface.GetVID(j) == vID1 && cface.GetVID(j + 1) == vID2) || (cface.GetVID(j) == vID2 && cface.GetVID(j + 1) == vID1)) { return(cface); } } if ((cface.GetVID(j) == vID1 && cface.GetVID(0) == vID2) || (cface.GetVID(j) == vID2 && cface.GetVID(0) == vID1)) { return(cface); } } return(null); }
public Vector3 GetSupportPlaneNormal(int vID1, int vID2) { Vector3 normal = Vector3.zero; float maxY = 0; for (int i = 0; i < GetFaceNum(); i++) { CovFace cface = GetFace(i); int j; for (j = 0; j < cface.GetVNum() - 1; j++) { if ((cface.GetVID(j) == vID1 && cface.GetVID(j + 1) == vID2) || (cface.GetVID(j) == vID2 && cface.GetVID(j + 1) == vID1)) { if (cface.Normal.y > maxY) { maxY = cface.Normal.y; normal = cface.Normal; } break; } } if ((cface.GetVID(j) == vID1 && cface.GetVID(0) == vID2) || (cface.GetVID(j) == vID2 && cface.GetVID(0) == vID1)) { if (cface.Normal.y > maxY) { maxY = cface.Normal.y; normal = cface.Normal; } } } return(normal); }
public void DebugRender(bool debug = true, string Text = "") { if (!debug) { ClearDebugRender(); return; } if (null == _DebugRender) { _DebugRender = new UEDebugMeshRender(); } List <Vector3> vlist = new List <Vector3>(); List <int> ilist = new List <int>(); List <Color> clist = new List <Color>(); int iindex = 0; for (int i = 0; i < GetFaceNum(); ++i) { CovFace cf = GetFace(i); Vector3 v0 = (GetVertex(cf.GetVID(0))); for (int j = 1; j < cf.GetVNum() - 1; ++j) { vlist.Add(v0); ilist.Add(iindex++); Vector3 v1 = GetVertex(cf.GetVID(j + 0)); vlist.Add(v1); ilist.Add(iindex++); Vector3 v2 = GetVertex(cf.GetVID(j + 1)); vlist.Add(v2); ilist.Add(iindex++); Vector3 normal = Vector3.Cross(v0 - v1, v1 - v2); normal.Normalize(); float fdot = Vector3.Dot(normal, (Vector3.left - Vector3.down)); float fweight = Mathf.Max(0, fdot) * .8f; Color facecolor = Color.red * (.2f + fweight); clist.Add(facecolor); clist.Add(facecolor); clist.Add(facecolor); } } int index = 0; foreach (Vector3 v in vlist) { _DebugRender.SetPoint(index++, v); } _DebugRender.CreateLineRender(); //_DebugRender.AABB = GetAABB(); _DebugRender.Create(vlist, ilist, clist); //if(!string.IsNullOrEmpty(Text)) //{ // _DebugRender.CreateText(Text); //} }
public void AddFace(CovFace face) { CovFace covface = new CovFace(face); face.CHData = this; mLstCovFace.Add(covface); }
public bool Import(CYLINDER cylinder, int nbFaceInSide) { if (nbFaceInSide < 3) { return(false); } float fHalfRad = Mathf.PI / nbFaceInSide; float fRad = fHalfRad * 2; float fNewR = cylinder.Radius / Mathf.Cos(fHalfRad); Matrix4x4 mat = Matrix4x4.identity; mat.SetRow(0, cylinder.AxisX); mat.SetRow(1, cylinder.AxisY); mat.SetRow(2, cylinder.AxisZ); mat.SetRow(3, cylinder.Center); Vector3 vHalfHigh = cylinder.AxisY * cylinder.HalfLen; int nAllCount = nbFaceInSide * 2; Vector3[] vertBuf = new Vector3[nAllCount]; Vector3 p = Vector3.zero; int idx = 0; float fTheta = 0; for (int i = 0; i < nbFaceInSide; ++i) { p.Set(0, 0, 0); p.z -= fNewR * Mathf.Cos(fTheta); p.x += fNewR * Mathf.Sin(fTheta); p = mat.MultiplyPoint3x4(p); vertBuf[idx] = p + vHalfHigh; vertBuf[idx + 1] = p - vHalfHigh; idx += 2; fTheta += fRad; } Vector3 vTopCenter = cylinder.Center + vHalfHigh; float fTopD = Vector3.Dot(cylinder.AxisY, vTopCenter); CovFace faceTop = new CovFace(); faceTop.Normal = cylinder.AxisY; faceTop.Dist = fTopD; Vector3 vBtmCenter = cylinder.Center - vHalfHigh; float fBtmD = Vector3.Dot(cylinder.AxisY * -1, vBtmCenter); CovFace faceBottom = new CovFace(); faceBottom.Normal = cylinder.AxisY * -1; faceBottom.Dist = fBtmD; return(CreateConvexHullData(vertBuf, faceTop, faceBottom)); }
public void Set(CovFace face) { Normal = face.Normal; Dist = face.Dist; for (int i = 0; i < face.GetVNum(); i++) { int vid = face.GetVID(i); AddElement(vid); } }
// Generate convex hull from a triangle directly public bool Import(Vector3[] triangle, float fThickness = 0.01f) { if (triangle == null) { return(false); } fThickness = Mathf.Abs(fThickness); if (0.0001 > fThickness) { return(false); } Vector3 e01 = triangle[1] - triangle[0]; //Vector3 e12 = triangle[2] - triangle[1]; Vector3 e20 = triangle[0] - triangle[2]; Vector3 vNTop = Vector3.Cross(e01, e20); float fDNTop = MathUtil.Normalize(ref vNTop); // Collinear test if (fDNTop < 1e-5) { return(false); } Reset(); // Compute all 6 triangle of convex hull; Vector3[] v = new Vector3[6]; float fHalfThickness = 0.5f * fThickness; v[0] = triangle[0] + fHalfThickness * vNTop; v[1] = triangle[0] - fHalfThickness * vNTop; v[2] = triangle[1] + fHalfThickness * vNTop; v[3] = triangle[1] - fHalfThickness * vNTop; v[4] = triangle[2] + fHalfThickness * vNTop; v[5] = triangle[2] - fHalfThickness * vNTop; float fTopD = Vector3.Dot(vNTop, v[0]); CovFace faceTop = new CovFace(); faceTop.Normal = vNTop; faceTop.Dist = fTopD; float fBtmD = Vector3.Dot(vNTop * -1.0f, v[3]); CovFace faceBottom = new CovFace(); faceBottom.Normal = vNTop * -1.0f; faceBottom.Dist = fBtmD; return(CreateConvexHullData(v, faceTop, faceBottom)); }
//导出数据到ConvexData中 public void ExportCHData(ConvexData chData) { List <int> lstMap = new List <int>(); //一个由顶点在本类中id到CConvexHullData中id的一个映射表; //遍历每一个Patch for (int i = 0; i < LstPatches.Count; i++) { Patch pat = LstPatches[i]; Vector3 n = pat.Normal; CovFace face = new CovFace(); face.Normal = n; face.Dist = pat.Dist; for (int j = 0; j < pat.GetVNum(); j++) { int vid = pat.GetVID(j); //构造垂直于该边法向朝外的HalfSpace Vector3 v1 = Vector3.zero; Vector3 v2 = Vector3.zero; pat.GetEdge(j, ref v1, ref v2); int ExistID = FindInArray(vid, lstMap); if (ExistID == -1) { //说明是新的顶点 //插入到CConvexHullData的Vertices中 chData.AddVertex(v1); int newID = chData.GetVertexNum() - 1; //在pCHData中的id face.AddElement(newID); lstMap.Add(vid); } else { //说明是已经存在的顶点 face.AddElement(ExistID); } } //插入该面片 chData.AddFace(face); } }
public virtual bool Load(LBinaryFile fs, uint version) { Reset(); mFlags = fs.Reader.ReadUInt32(); int vertnum = fs.Reader.ReadInt32(); for (int i = 0; i < vertnum; i++) { Vector3 vec = SLBinary.LoadVector3(fs); mLstVertices.Add(vec); } int facenum = fs.Reader.ReadInt32(); for (int i = 0; i < facenum; i++) { CovFace face = new CovFace(); face.Load(fs, version); mLstCovFace.Add(face); } //mAABBDirty = true; return(true); }
public CovFace(CovFace face) { Set(face); }
public bool CreateConvexHullData(Vector3[] vertBuf, CovFace faceTop, CovFace faceBottom) { if (vertBuf == null || vertBuf.Length <= 0) { return(false); } int vertCount = vertBuf.Length; Reset(); for (int i = 0; i < vertCount; ++i) { AddVertex(vertBuf[i]); } Vector3 vNormalTop = faceTop.Normal; Vector3 vNormalBTM = faceBottom.Normal; int idx = 0; int nHalfVert = vertCount / 2; int idxInverse = (nHalfVert - 1) * 2; int p0, p1, p2, p3; int pi0, pi2, pi3; for (int i = 0; i < nHalfVert; ++i) { /* * a side face: * p0 p2 +-------+ | | | | | | +-------+ | p1 p3 */ p0 = idx; p1 = idx + 1; p2 = idx + 2; p3 = idx + 3; if (p2 >= vertCount) { p2 -= vertCount; } if (p3 >= vertCount) { p3 -= vertCount; } CovFace face = new CovFace(); face.Set(vertBuf[p0], vertBuf[p1], vertBuf[p2]); Vector3 vNormal = face.Normal; face.AddElement(p0); face.AddElement(p2); face.AddElement(p3); face.AddElement(p1); AddFace(face); faceBottom.AddElement(p1); pi0 = idxInverse; //pi1 = idxInverse + 1; pi2 = idxInverse + 2; pi3 = idxInverse + 3; if (pi2 >= vertCount) { pi2 -= vertCount; } if (pi3 >= vertCount) { pi3 -= vertCount; } faceTop.AddElement(pi0); idx += 2; idxInverse -= 2; } AddFace(faceTop); AddFace(faceBottom); return(true); }