Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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;
        }
Пример #5
0
        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;
                }
            }
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }