private unsafe void ComputeXZRadius(IntPtr vbStream, out Vector3 centerXz, out float radius, out Vector3 center, out int nbZeroDistance) { centerXz = new Vector3(); radius = float.MinValue; nbZeroDistance = 0; int posOffset = VertexDescriptor.OffsetOf(IASemantic.Position, 0); int size = VertexDescriptor.Size; byte *vbPter = (byte *)vbStream + posOffset; for (int i = 0; i < _vertexCount; i++) { centerXz += *(Vector3 *)(vbPter + size * i); } centerXz *= 1f / (float)_vertexCount; center = centerXz; centerXz.Y = 0; for (int i = 0; i < _vertexCount; i++) { Vector3 point = *(Vector3 *)(vbPter + size * i); point.Y = 0; float distance = Vector3.Distance(point, centerXz); if (distance == 0 || distance.IsZero()) { nbZeroDistance++; } radius = Math.Max(radius, distance); } }
public unsafe bool IsPlane(out Plane plane) { plane = new Plane(); if (_faceCount != 2) { return(false); } var vbStream = _vb.Map(MapType.Read); var ibStream = _ib.Map(MapType.Read); Plane *planes = stackalloc Plane[2]; try { int posOffset = VertexDescriptor.OffsetOf(IASemantic.Position, 0); int size = VertexDescriptor.Size; byte *vbPter = (byte *)vbStream + posOffset; byte *ibPter = (byte *)ibStream; for (int iface = 0; iface < _faceCount; iface++) { Vector3 p0; Vector3 p1; Vector3 p2; if (_is16BitIndices) { p0 = *(Vector3 *)(vbPter + size * ((short *)ibPter)[iface * 3]); p1 = *(Vector3 *)(vbPter + size * ((short *)ibPter)[iface * 3 + 1]); p2 = *(Vector3 *)(vbPter + size * ((short *)ibPter)[iface * 3 + 2]); } else { p0 = *(Vector3 *)(vbPter + size * ((int *)ibPter)[iface * 3]); p1 = *(Vector3 *)(vbPter + size * ((int *)ibPter)[iface * 3 + 1]); p2 = *(Vector3 *)(vbPter + size * ((int *)ibPter)[iface * 3 + 2]); } planes[iface] = new Plane(p0, p1, p2); } } finally { _vb.Unmap(); _ib.Unmap(); } if (Plane.Equals(planes[0], planes[1])) { plane = planes[0]; return(true); } return(false); }
public unsafe bool IsCylindre(out float radius, out float height, out Vector3 center) { radius = 0; height = 0; center = new Vector3(); if (_vertexCount == 0 || _faceCount <= 12) { return(false); } var vbStream = _vb.Map(MapType.Read); int posOffset = VertexDescriptor.OffsetOf(IASemantic.Position, 0); int size = VertexDescriptor.Size; float distance; float maxY = float.MinValue; float minY = float.MaxValue; byte *vbPter = (byte *)vbStream + posOffset; Vector3 xzCenter; float xzRadius; int nb; ComputeXZRadius(vbStream, out xzCenter, out xzRadius, out center, out nb); xzCenter.Y = 0; bool result = true; for (int i = 0; i < _vertexCount; i++) { Vector3 point = *(Vector3 *)(vbPter + size * i); maxY = Math.Max(maxY, point.Y); minY = Math.Min(minY, point.Y); point.Y = 0; distance = Vector3.Distance(point, xzCenter); if (!distance.IsEqual(xzRadius) && !distance.IsZero()) { result = false; break; } } radius = xzRadius; height = maxY - minY; _vb.Unmap(); return(result); }
public unsafe void FindDimensions(IntPtr vbStream, out Vector3 center, out Vector3 dimensions) { int posOffset = VertexDescriptor.OffsetOf(IASemantic.Position, 0); int size = VertexDescriptor.Size; byte *vbPter = (byte *)vbStream + posOffset; center = new Vector3(); Vector3 max = new Vector3(float.MinValue); Vector3 min = new Vector3(float.MaxValue); for (int i = 0; i < _vertexCount; i++) { center += *(Vector3 *)(vbPter + size * i); max = Vector3.Max(max, *(Vector3 *)(vbPter + size * i)); min = Vector3.Min(min, *(Vector3 *)(vbPter + size * i)); } dimensions = 0.5f * (max - min); center *= 1.0f / (float)_vertexCount; }
unsafe private void CreateBoxPlanes(Plane *planes, int planesCount, IntPtr vbStream, IntPtr ibStream) { int posOffset = VertexDescriptor.OffsetOf(IASemantic.Position, 0); int size = VertexDescriptor.Size; byte *vbPter = (byte *)vbStream + posOffset; byte *ibPter = (byte *)ibStream; int k = 0; for (int iface = 0; iface < _faceCount; iface++) { Vector3 p0; Vector3 p1; Vector3 p2; if (_is16BitIndices) { p0 = *(Vector3 *)(vbPter + size * ((short *)ibPter)[iface * 3]); p1 = *(Vector3 *)(vbPter + size * ((short *)ibPter)[iface * 3 + 1]); p2 = *(Vector3 *)(vbPter + size * ((short *)ibPter)[iface * 3 + 2]); } else { p0 = *(Vector3 *)(vbPter + size * ((int *)ibPter)[iface * 3]); p1 = *(Vector3 *)(vbPter + size * ((int *)ibPter)[iface * 3 + 1]); p2 = *(Vector3 *)(vbPter + size * ((int *)ibPter)[iface * 3 + 2]); } var facePlane = new Plane(p0, p1, p2); if (!Contains(planes, planesCount, facePlane)) { if (k >= planesCount) { throw new IndexOutOfRangeException(); } planes[k++] = facePlane; } } }
public unsafe bool IsSphere(out Vector3 center, out float radius) { center = new Vector3(); radius = 0; if (_vertexCount == 0 || _faceCount <= 12) { return(false); } var vbStream = _vb.Map(MapType.Read); int posOffset = VertexDescriptor.OffsetOf(IASemantic.Position, 0); int size = VertexDescriptor.Size; byte *vbPter = (byte *)vbStream + posOffset; if (_sphere.Radius == 0) { _sphere = new Sphere(vbPter, _vertexCount, size); } center = _sphere.Center; radius = _sphere.Radius; bool result = true; for (int i = 0; i < _vertexCount; i++) { float distance = Vector3.Distance(*(Vector3 *)(vbPter + size * i), center); if (distance != radius && !distance.IsEqual(radius)) { result = false; break; } } _vb.Unmap(); return(result); }
public unsafe bool IsCapsule(out float radius, out float height, out Vector3 center) { radius = 0; height = 0; center = new Vector3(); if (_vertexCount == 0 || _faceCount <= 12) { return(false); } var vbStream = _vb.Map(MapType.Read); int posOffset = VertexDescriptor.OffsetOf(IASemantic.Position, 0); int size = VertexDescriptor.Size; float distance; float maxY = float.MinValue; float minY = float.MaxValue; byte *vbPter = (byte *)vbStream + posOffset; Vector3 xzCenter; int nbZeroDistance; float xyRadius = 0; ComputeXZRadius(vbStream, out xzCenter, out xyRadius, out center, out nbZeroDistance); radius = xyRadius; int nbCylindrePoints = 0; xzCenter.Y = 0; //compute height and radius of the cylindre for (int i = 0; i < _vertexCount; i++) { Vector3 point = *(Vector3 *)(vbPter + size * i); float y = point.Y; point.Y = 0; distance = Vector3.Distance(point, xzCenter); if (distance.IsEqual(xyRadius)) { nbCylindrePoints++; maxY = Math.Max(maxY, y); minY = Math.Min(minY, y); } } height = maxY - minY; float halfHeight = height * 0.5f; if (height.IsZero()) { _vb.Unmap(); return(false); } //verify top semispheres int nbSphereSpherePoints = 0; //compute height and radius of the cylindre for (int i = 0; i < _vertexCount; i++) { Vector3 point = *(Vector3 *)(vbPter + size * i); if (point.Y > center.Y) { point.Y -= halfHeight; } else { point.Y += halfHeight; } distance = Vector3.Distance(point, center); if (distance.IsEqual(xyRadius, 0.0005f)) { nbSphereSpherePoints++; } } _vb.Unmap(); return((nbSphereSpherePoints + nbCylindrePoints) >= _vertexCount); }
public TriangleMesh CreateTriangleMesh() { TriangleMesh triangleMesh; TriangleMeshDesc desc = new TriangleMeshDesc(); desc.Name = Name; desc.Flags |= Is16BitIndices ? MeshFlag.BIT_INDICES_16 : 0; desc.Flags |= MeshFlag.HARDWARE_MESH; desc.NumTriangles = FaceCount; desc.NumVertices = VertexCount; desc.TriangleStrideBytes = 3 * (Is16BitIndices ? sizeof(short) : sizeof(int)); desc.PointStrideBytes = VertexDescriptor.SizeOf(IASemantic.Position, 0); int stride = desc.PointStrideBytes; var ibData = _ib.Map(MapType.Read); var vbStream = _vb.Map(MapType.Read); try { int posOffset = VertexDescriptor.OffsetOf(IASemantic.Position, 0); int size = _vd.Size; byte[] positions = new byte[desc.NumVertices * stride]; unsafe { fixed(byte *desPter = positions) { byte *srcPter = (byte *)vbStream + posOffset; byte *pter = desPter; for (int i = 0; i < desc.NumVertices; i++, srcPter += size, pter += stride) { *(Vector3 *)pter = *(Vector3 *)(srcPter); } desc.Points = (IntPtr)desPter; desc.Triangles = ibData; //Cooking.Create(); //Cooking.InitCooking(); //byte[] stream = Cooking.CookTriangleMesh(desc); //Cooking.CloseCooking(); //desc.Dispose(); //triangleMesh = new TriangleMesh(stream) { Name = Name, UserData = this }; triangleMesh = PhysicManager.Sigleton.CreateTriangleMesh(desc); triangleMesh.GraphicMesh = this; } } } finally { _vb.Unmap(); _ib.Unmap(); } return(triangleMesh); }