Пример #1
0
        public void BasicMeshSerializationTest()
        {
            const int VERTICES = 499;
            const int INDICES = 1009;

            BasicMesh mesh = new BasicMesh();
            mesh.Volume = 42f;

            mesh.Vertices = new Vector3[VERTICES];
            for (int i = 0; i < VERTICES; i++)
                mesh.Vertices[i] = RandomVector();

            mesh.Indices = new ushort[INDICES];
            for (int i = 0; i < INDICES; i++)
                mesh.Indices[i] = (ushort)m_rng.Next(VERTICES);

            byte[] data = mesh.Serialize();

            BasicMesh mesh2 = BasicMesh.Deserialize(data);

            Assert.AreEqual(mesh.Volume, mesh2.Volume);
            Assert.AreEqual(mesh.Vertices.Length, mesh2.Vertices.Length);
            Assert.AreEqual(mesh.Indices.Length, mesh2.Indices.Length);

            for (int i = 0; i < mesh.Vertices.Length; i++)
                Assert.AreEqual(mesh.Vertices[i], mesh2.Vertices[i]);

            for (int i = 0; i < mesh.Indices.Length; i++)
                Assert.AreEqual(mesh.Indices[i], mesh2.Indices[i]);
        }
Пример #2
0
        public static BasicMesh Deserialize(byte[] data)
        {
            int pos = 0;

            BasicMesh mesh = new BasicMesh();

            mesh.Volume = Utils.BytesToFloat(data, pos);
            pos        += 4;

            ushort vertexCount = Utils.BytesToUInt16(data, pos);

            pos += 2;

            mesh.Vertices = new Vector3[vertexCount];
            for (int j = 0; j < vertexCount; j++)
            {
                Vector3 v = new Vector3(data, pos);
                pos += 12;

                mesh.Vertices[j] = v;
            }

            ushort indexCount = Utils.BytesToUInt16(data, pos);

            pos += 2;

            mesh.Indices = new ushort[indexCount];
            Buffer.BlockCopy(data, pos, mesh.Indices, 0, indexCount * 2);
            pos += indexCount * 2;

            return(mesh);
        }
Пример #3
0
        public void StoreBasicMesh(ulong meshKey, DetailLevel lod, BasicMesh mesh)
        {
            UUID   dataID      = new UUID(meshKey);
            string contentType = BASIC_MESH_BASE_CONTENT_TYPE + "-" + lod.ToString().ToLower();

            byte[] data = mesh.Serialize();

            m_dataStore.AddOrUpdateAsset(dataID, contentType, data, true);
        }
Пример #4
0
        /// <summary>
        /// Calculates the approximate volume of a scaled mesh
        /// </summary>
        /// <param name="mesh">Mesh data</param>
        /// <param name="scale">Object scale</param>
        /// <returns>Approximate volume of the mesh</returns>
        public static float GetMeshVolume(BasicMesh mesh, Vector3 scale)
        {
            const float OO_SIX = 1f / 6f;

            double volume = 0.0f;

            // Formula adapted from Stan Melax's algorithm: <http://www.melax.com/volint.html>
            for (int i = 0; i < mesh.Indices.Length; i += 3)
            {
                Vector3 v0 = mesh.Vertices[mesh.Indices[i + 0]];
                Vector3 v1 = mesh.Vertices[mesh.Indices[i + 1]];
                Vector3 v2 = mesh.Vertices[mesh.Indices[i + 2]];

                volume += Determinant3x3(v0, v1, v2);
            }

            return((float)(volume * OO_SIX) * scale.X * scale.Y * scale.Z);
        }
Пример #5
0
        public static bool CollisionTest(Ray ray, IPhysical obj, BasicMesh mesh, out float dist)
        {
            Vector3 start     = new Vector3(ray.X, ray.Y, ray.Z);
            Vector3 direction = new Vector3(ray.I, ray.J, ray.K);

            dist = Single.MaxValue;

            // Construct a matrix to transform to scene space
            Matrix4 transform = Matrix4.Identity;

            transform *= Matrix4.CreateScale(obj.Scale);
            transform *= Matrix4.CreateFromQuaternion(obj.RelativeRotation);
            transform *= Matrix4.CreateTranslation(obj.RelativePosition);

            ILinkable parent = obj.Parent;

            if (parent != null)
            {
                // Apply parent rotation and translation
                transform *= Matrix4.CreateFromQuaternion(parent.RelativeRotation);
                transform *= Matrix4.CreateTranslation(parent.RelativePosition);
            }

            // Iterate through all of the triangles in the mesh, doing a ray-triangle intersection
            for (int i = 0; i < mesh.Indices.Length; i += 3)
            {
                Vector3 point0 = mesh.Vertices[mesh.Indices[i + 0]] * transform;
                Vector3 point1 = mesh.Vertices[mesh.Indices[i + 1]] * transform;
                Vector3 point2 = mesh.Vertices[mesh.Indices[i + 2]] * transform;

                float thisDist;
                if (RayTriangle.CollisionTestCull(start, direction, point0, point1, point2, out thisDist))
                {
                    if (thisDist < dist)
                    {
                        dist = thisDist;
                    }
                }
            }

            return(dist < Single.MaxValue);
        }
Пример #6
0
        public bool TryGetBasicMesh(ulong meshKey, DetailLevel lod, out BasicMesh mesh)
        {
            UUID   dataID      = new UUID(meshKey);
            string contentType = BASIC_MESH_BASE_CONTENT_TYPE + "-" + LOD_NAMES[(int)lod];

            mesh = null;

            byte[] meshData;
            if (m_dataStore.TryGetAsset(dataID, contentType, out meshData))
            {
                try
                {
                    mesh = BasicMesh.Deserialize(meshData);
                }
                catch (Exception ex)
                {
                    m_log.WarnFormat("Failed to deserialize basic mesh {0} ({1}): {2}", dataID, contentType, ex.Message);
                }
            }

            return(mesh != null);
        }
Пример #7
0
        public static bool CollisionTest(Ray ray, IPhysical obj, BasicMesh mesh, out float dist)
        {
            Vector3 start = new Vector3(ray.X, ray.Y, ray.Z);
            Vector3 direction = new Vector3(ray.I, ray.J, ray.K);
            dist = Single.MaxValue;

            // Construct a matrix to transform to scene space
            Matrix4 transform = Matrix4.Identity;

            transform *= Matrix4.CreateScale(obj.Scale);
            transform *= Matrix4.CreateFromQuaternion(obj.RelativeRotation);
            transform *= Matrix4.CreateTranslation(obj.RelativePosition);

            ILinkable parent = obj.Parent;
            if (parent != null)
            {
                // Apply parent rotation and translation
                transform *= Matrix4.CreateFromQuaternion(parent.RelativeRotation);
                transform *= Matrix4.CreateTranslation(parent.RelativePosition);
            }

            // Iterate through all of the triangles in the mesh, doing a ray-triangle intersection
            for (int i = 0; i < mesh.Indices.Length; i += 3)
            {
                Vector3 point0 = mesh.Vertices[mesh.Indices[i + 0]] * transform;
                Vector3 point1 = mesh.Vertices[mesh.Indices[i + 1]] * transform;
                Vector3 point2 = mesh.Vertices[mesh.Indices[i + 2]] * transform;

                float thisDist;
                if (RayTriangle.CollisionTestCull(start, direction, point0, point1, point2, out thisDist))
                {
                    if (thisDist < dist)
                        dist = thisDist;
                }
            }

            return dist < Single.MaxValue;
        }
Пример #8
0
        /// <summary>
        /// Calculates the approximate volume of a scaled mesh
        /// </summary>
        /// <param name="mesh">Mesh data</param>
        /// <param name="scale">Object scale</param>
        /// <returns>Approximate volume of the mesh</returns>
        public static float GetMeshVolume(BasicMesh mesh, Vector3 scale)
        {
            const float OO_SIX = 1f / 6f;

            double volume = 0.0f;

            // Formula adapted from Stan Melax's algorithm: <http://www.melax.com/volint.html>
            for (int i = 0; i < mesh.Indices.Length; i += 3)
            {
                Vector3 v0 = mesh.Vertices[mesh.Indices[i + 0]];
                Vector3 v1 = mesh.Vertices[mesh.Indices[i + 1]];
                Vector3 v2 = mesh.Vertices[mesh.Indices[i + 2]];

                volume += Determinant3x3(v0, v1, v2);
            }

            return (float)(volume * OO_SIX) * scale.X * scale.Y * scale.Z;
        }
Пример #9
0
        public static BasicMesh Deserialize(byte[] data)
        {
            int pos = 0;

            BasicMesh mesh = new BasicMesh();
            mesh.Volume = Utils.BytesToFloat(data, pos);
            pos += 4;

            ushort vertexCount = Utils.BytesToUInt16(data, pos);
            pos += 2;

            mesh.Vertices = new Vector3[vertexCount];
            for (int j = 0; j < vertexCount; j++)
            {
                Vector3 v = new Vector3(data, pos);
                pos += 12;

                mesh.Vertices[j] = v;
            }

            ushort indexCount = Utils.BytesToUInt16(data, pos);
            pos += 2;

            mesh.Indices = new ushort[indexCount];
            Buffer.BlockCopy(data, pos, mesh.Indices, 0, indexCount * 2);
            pos += indexCount * 2;

            return mesh;
        }
Пример #10
0
        public bool TryGetBasicMesh(ulong meshKey, DetailLevel lod, out BasicMesh mesh)
        {
            UUID dataID = new UUID(meshKey);
            string contentType = BASIC_MESH_BASE_CONTENT_TYPE + "-" + LOD_NAMES[(int)lod];

            mesh = null;

            byte[] meshData;
            if (m_dataStore.TryGetAsset(dataID, contentType, out meshData))
            {
                try
                {
                    mesh = BasicMesh.Deserialize(meshData);
                }
                catch (Exception ex)
                {
                    m_log.WarnFormat("Failed to deserialize basic mesh {0} ({1}): {2}", dataID, contentType, ex.Message);
                }
            }

            return (mesh != null);
        }
Пример #11
0
        public void StoreBasicMesh(ulong meshKey, DetailLevel lod, BasicMesh mesh)
        {
            UUID dataID = new UUID(meshKey);
            string contentType = BASIC_MESH_BASE_CONTENT_TYPE + "-" + lod.ToString().ToLower();
            byte[] data = mesh.Serialize();

            m_dataStore.AddOrUpdateAsset(dataID, contentType, data, true);
        }