Beispiel #1
0
        public void Split()
        {
            R3DBox pBox    = CentralPointsBoundingBox;
            float  middleX = (pBox.Min.X + pBox.Max.X) / 2;
            float  middleZ = (pBox.Min.Z + pBox.Max.Z) / 2;
            // Node 1 (bottom-left)
            Vector3 node1Min = new Vector3(pBox.Min.X, pBox.Min.Y, pBox.Min.Z);
            Vector3 node1Max = new Vector3(middleX, pBox.Max.Y, middleZ);
            NVRNode node1    = new NVRNode(new R3DBox(node1Min, node1Max), this);

            // Node 2 (top-left)
            Vector3 node2Min = new Vector3(pBox.Min.X, pBox.Min.Y, middleZ);
            Vector3 node2Max = new Vector3(middleX, pBox.Max.Y, pBox.Max.Z);
            NVRNode node2    = new NVRNode(new R3DBox(node2Min, node2Max), this);

            // Node 3 (top-right)
            Vector3 node3Min = new Vector3(middleX, pBox.Min.Y, middleZ);
            Vector3 node3Max = new Vector3(pBox.Max.X, pBox.Max.Y, pBox.Max.Z);
            NVRNode node3    = new NVRNode(new R3DBox(node3Min, node3Max), this);

            // Node 4 (bottom-right)
            Vector3 node4Min = new Vector3(middleX, pBox.Min.Y, pBox.Min.Z);
            Vector3 node4Max = new Vector3(pBox.Max.X, pBox.Max.Y, middleZ);
            NVRNode node4    = new NVRNode(new R3DBox(node4Min, node4Max), this);

            foreach (NVRNode childNode in Children)
            {
                Vector3 proportions = childNode.CentralPointsBoundingBox.GetProportions();
                if ((childNode.Meshes.Count > 1) && (proportions.X > 100 || proportions.Z > 100))
                {
                    childNode.Split();
                }
            }
        }
Beispiel #2
0
        public Tuple <R3DSphere, R3DBox> CalculateBoundingGeometry()
        {
            R3DBox    box    = CalculateBoundingBox();
            R3DSphere sphere = CalculateSphere(box);

            return(new Tuple <R3DSphere, R3DBox>(sphere, box));
        }
Beispiel #3
0
 public NVRNode(List <NVRMesh> meshes)
 {
     // Used when creating the big parent node.
     this.Meshes.AddRange(meshes);
     this.BoundingBox = this.CalculateBoundingBox();
     this.CentralPointsBoundingBox = this.CalculateCentralPointsBoundingBox();
 }
Beispiel #4
0
        /// <summary>
        /// Calculates a Bounding Sphere of this <see cref="SKNSubmesh"/>
        /// </summary>
        public R3DSphere CalculateBoundingSphere()
        {
            R3DBox  box          = CalculateBoundingBox();
            Vector3 centralPoint = CalculateCentralPoint();

            return(new R3DSphere(centralPoint, Vector3.Distance(centralPoint, box.Max)));
        }
Beispiel #5
0
        /// <summary>
        /// Calculates the Bounding Sphere of this <see cref="WGEOModel"/> from the specified <see cref="R3DBox"/>
        /// </summary>
        /// <param name="box"><see cref="R3DBox"/> to use for calculation</param>
        public R3DSphere CalculateSphere(R3DBox box)
        {
            Vector3 centralPoint = new Vector3(0.5f * (this.BoundingBox.Max.X + this.BoundingBox.Min.X),
                                               0.5f * (this.BoundingBox.Max.Y + this.BoundingBox.Min.Y),
                                               0.5f * (this.BoundingBox.Max.Z + this.BoundingBox.Min.Z));

            return(new R3DSphere(centralPoint, Vector3.Distance(centralPoint, box.Max)));
        }
Beispiel #6
0
        /// <summary>
        /// Calculates the Central Point of this <see cref="SKNSubmesh"/>
        /// </summary>
        public Vector3 CalculateCentralPoint()
        {
            R3DBox box = CalculateBoundingBox();

            return(new Vector3(0.5f * (box.Min.X + box.Max.X),
                               0.5f * (box.Min.Y + box.Max.Y),
                               0.5f * (box.Min.Z + box.Max.Z)));
        }
Beispiel #7
0
 public NVRNode(R3DBox centralPointsBox, NVRNode parentNode)
 {
     // Used if we create it from a parent node.
     this.CentralPointsBoundingBox = centralPointsBox;
     this.Meshes.AddRange(parentNode.Meshes.FindAll(x => this.CentralPointsBoundingBox.ContainsPoint(x.BoundingSphere.Position)));
     parentNode.Children.Add(this);
     this.BoundingBox = this.CalculateBoundingBox();
 }
Beispiel #8
0
        public SimpleSkin(Stream stream)
        {
            using (BinaryReader br = new BinaryReader(stream))
            {
                uint magic = br.ReadUInt32();
                if (magic != 0x00112233)
                {
                    throw new Exception("Not a valid SKN file");
                }

                ushort major = br.ReadUInt16();
                ushort minor = br.ReadUInt16();
                if (major != 2 && major != 4 && minor != 1)
                {
                    throw new Exception("This SKN version is not supported");
                }

                uint submeshCount = br.ReadUInt32();

                for (int i = 0; i < submeshCount; i++)
                {
                    this.Submeshes.Add(new SimpleSkinSubmesh(br));
                }
                if (major == 4)
                {
                    uint unknown = br.ReadUInt32();
                }

                uint indexCount  = br.ReadUInt32();
                uint vertexCount = br.ReadUInt32();

                uint vertexSize = major == 4 ? br.ReadUInt32() : 52;
                SimpleSkinVertexType vertexType = major == 4 ? (SimpleSkinVertexType)br.ReadUInt32() : SimpleSkinVertexType.Basic;
                R3DBox    boundingBox           = major == 4 ? new R3DBox(br) : R3DBox.Infinite;
                R3DSphere boundingSphere        = major == 4 ? new R3DSphere(br) : R3DSphere.Infinite;

                List <ushort>           indices  = new List <ushort>();
                List <SimpleSkinVertex> vertices = new List <SimpleSkinVertex>();
                for (int i = 0; i < indexCount; i++)
                {
                    indices.Add(br.ReadUInt16());
                }
                for (int i = 0; i < vertexCount; i++)
                {
                    vertices.Add(new SimpleSkinVertex(br, vertexType));
                }

                foreach (SimpleSkinSubmesh submesh in this.Submeshes)
                {
                    List <ushort> submeshIndices = indices.GetRange((int)submesh._startIndex, (int)submesh._indexCount);
                    ushort        minIndex       = submeshIndices.Min();

                    submesh.Indices  = submeshIndices.Select(x => x -= minIndex).ToList();
                    submesh.Vertices = vertices.GetRange((int)submesh._startVertex, (int)submesh._vertexCount);
                }
            }
        }
Beispiel #9
0
        public static StaticObject ReadSCB(Stream stream)
        {
            using (BinaryReader br = new BinaryReader(stream))
            {
                string magic = Encoding.ASCII.GetString(br.ReadBytes(8));
                if (magic != "r3d2Mesh")
                {
                    throw new Exception("This is not a valid SCB file");
                }

                ushort major = br.ReadUInt16();
                ushort minor = br.ReadUInt16();
                if (major != 3 && major != 2 && minor != 1) //There are versions [2][1] and [1][1] aswell
                {
                    throw new Exception(string.Format("The Version: {0}.{1} is not supported", major, minor));
                }

                string            name        = Encoding.ASCII.GetString(br.ReadBytes(128)).Replace("\0", "");
                uint              vertexCount = br.ReadUInt32();
                uint              faceCount   = br.ReadUInt32();
                StaticObjectFlags flags       = (StaticObjectFlags)br.ReadUInt32();
                R3DBox            boundingBox = new R3DBox(br);

                bool hasVertexColors = false;
                if (major == 3 && minor == 2)
                {
                    hasVertexColors = br.ReadUInt32() == 1;
                }

                List <Vector3> vertices     = new List <Vector3>((int)vertexCount);
                List <Color>   vertexColors = new List <Color>((int)vertexCount);
                for (int i = 0; i < vertexCount; i++)
                {
                    vertices.Add(new Vector3(br));
                }

                if (hasVertexColors)
                {
                    for (int i = 0; i < vertexCount; i++)
                    {
                        vertexColors.Add(br.ReadColor(ColorFormat.RgbaU8));
                    }
                }

                Vector3 centralPoint = new Vector3(br);

                List <StaticObjectFace> faces = new List <StaticObjectFace>((int)faceCount);
                for (int i = 0; i < faceCount; i++)
                {
                    faces.Add(new StaticObjectFace(br));
                }

                return(new StaticObject(name, CreateSubmeshes(vertices, vertexColors, faces), centralPoint));
            }
        }
 /// <summary>
 /// Initializes a new <see cref="MOBObject"/> from a <see cref="BinaryReader"/>
 /// </summary>
 /// <param name="br">The <see cref="BinaryReader"/> to read from</param>
 public MOBObject(BinaryReader br)
 {
     this.Name = Encoding.ASCII.GetString(br.ReadBytes(62)).Replace("\0", "");
     this.Type = (MOBObjectType)br.ReadByte();
     this.IgnoreCollisionOnPlacement = br.ReadBoolean();
     this.Position    = new Vector3(br);
     this.Rotation    = new Vector3(br);
     this.Scale       = new Vector3(br);
     this.BoundingBox = new R3DBox(br);
     this.SkinID      = br.ReadUInt32();
 }
 /// <summary>
 /// Initializes a new <see cref="MOBObject"/>
 /// </summary>
 /// <param name="name">Name of this <see cref="MOBObject"/></param>
 /// <param name="type">Type of this <see cref="MOBObject"/></param>
 /// <param name="skinID">Skin ID of this <see cref="MOBObject"/></param>
 /// <param name="ignoreCollisionOnPlacement">Collision flag of this <see cref="MOBObject"/></param>
 /// <param name="position">Position of this <see cref="MOBObject"/></param>
 /// <param name="rotation">Scale of this <see cref="MOBObject"/></param>
 /// <param name="scale">Scale of this <see cref="MOBObject"/></param>
 /// <param name="boundingBox">Bounding Box of this <see cref="MOBObject"/></param>
 public MOBObject(string name, MOBObjectType type, uint skinID, bool ignoreCollisionOnPlacement, Vector3 position, Vector3 rotation, Vector3 scale, R3DBox boundingBox)
 {
     this.Name   = name;
     this.Type   = type;
     this.SkinID = skinID;
     this.IgnoreCollisionOnPlacement = ignoreCollisionOnPlacement;
     this.Position    = position;
     this.Rotation    = rotation;
     this.Scale       = scale;
     this.BoundingBox = boundingBox;
 }
Beispiel #12
0
        public R3DSphere CalculateSphere()
        {
            R3DBox  box          = CalculateBoundingBox();
            Vector3 centralPoint = new Vector3
                                   (
                0.5f * (BoundingBox.Max.X + BoundingBox.Min.X),
                0.5f * (BoundingBox.Max.Y + BoundingBox.Min.Y),
                0.5f * (BoundingBox.Max.Z + BoundingBox.Min.Z)
                                   );

            return(new R3DSphere(centralPoint, Vector3.Distance(centralPoint, box.Max)));
        }
Beispiel #13
0
 private R3DBox CalculateBoundingBox()
 {
     if (Meshes.Count > 0)
     {
         Vector3 min = new Vector3(Meshes[0].BoundingBox.Min.X, Meshes[0].BoundingBox.Min.Y, Meshes[0].BoundingBox.Min.Z);
         Vector3 max = new Vector3(Meshes[0].BoundingBox.Max.X, Meshes[0].BoundingBox.Max.Y, Meshes[0].BoundingBox.Max.Z);
         for (int i = 1; i < Meshes.Count; i++)
         {
             R3DBox box = Meshes[i].BoundingBox;
             if (box.Min.X < min.X)
             {
                 min.X = box.Min.X;
             }
             if (box.Min.Y < min.Y)
             {
                 min.Y = box.Min.Y;
             }
             if (box.Min.Z < min.Z)
             {
                 min.Z = box.Min.Z;
             }
             if (box.Max.X > max.X)
             {
                 max.X = box.Max.X;
             }
             if (box.Max.Y > max.Y)
             {
                 max.Y = box.Max.Y;
             }
             if (box.Max.Z > max.Z)
             {
                 max.Z = box.Max.Z;
             }
         }
         return(new R3DBox(min, max));
     }
     else
     {
         // No meshes inside, set bounding box to
         return(new R3DBox(new Vector3(NullCoordinate, NullCoordinate, NullCoordinate), new Vector3(NullCoordinate, NullCoordinate, NullCoordinate)));
     }
 }
Beispiel #14
0
        private static void DumpSimpleSkinInfo(SimpleSkin simpleSkin)
        {
            Console.WriteLine("----------SIMPLE SKIN INFO----------");

            R3DBox boundingBox = simpleSkin.GetBoundingBox();

            Console.WriteLine("Bounding Box:");
            Console.WriteLine("\t Min: " + boundingBox.Min.ToString());
            Console.WriteLine("\t Max: " + boundingBox.Max.ToString());

            Console.WriteLine("Submesh Count: " + simpleSkin.Submeshes.Count);

            foreach (SimpleSkinSubmesh submesh in simpleSkin.Submeshes)
            {
                Console.WriteLine("--- SUBMESH ---");
                Console.WriteLine("Material: " + submesh.Name);
                Console.WriteLine("Vertex Count: " + submesh.Vertices.Count);
                Console.WriteLine("Index Count: " + submesh.Indices.Count);
                Console.WriteLine("Face Count: " + submesh.Indices.Count / 3);
                Console.WriteLine();
            }
        }
Beispiel #15
0
 /// <summary>
 /// Calculates the Central Point of this <see cref="SKNSubmesh"/> from a <see cref="R3DBox"/> of this <see cref="SKNSubmesh"/>
 /// </summary>
 /// <param name="box"><see cref="R3DBox"/> of this <see cref="SKNSubmesh"/></param>
 public Vector3 CalculateCentralPoint(R3DBox box)
 {
     return(new Vector3(0.5f * (box.Min.X + box.Max.X),
                        0.5f * (box.Min.Y + box.Max.Y),
                        0.5f * (box.Min.Z + box.Max.Z)));
 }
        /// <summary>
        /// Writes this <see cref="SKNFile"/> into the specified <see cref="Stream"/>
        /// </summary>
        /// <param name="stream">The <see cref="Stream"/> to write to</param>
        public void Write(Stream stream)
        {
            using (BinaryWriter bw = new BinaryWriter(stream))
            {
                bw.Write(0x00112233);
                bw.Write((ushort)4);
                bw.Write((ushort)1);
                bw.Write(this.Submeshes.Count);

                bool hasTangent  = false;
                uint indexCount  = 0;
                uint vertexCount = 0;
                foreach (SKNSubmesh submesh in this.Submeshes)
                {
                    if (!hasTangent)
                    {
                        foreach (SKNVertex vertex in submesh.Vertices)
                        {
                            if (vertex.Tangent != null)
                            {
                                hasTangent = true;
                            }
                        }
                    }
                    submesh.Write(bw);
                    indexCount  += (uint)submesh.Indices.Count;
                    vertexCount += (uint)submesh.Vertices.Count;
                }
                bw.Write((uint)0);
                bw.Write(indexCount);
                bw.Write(vertexCount);

                if (hasTangent)
                {
                    bw.Write((uint)56);
                    bw.Write((uint)1);
                }
                else
                {
                    bw.Write((uint)52);
                    bw.Write((uint)0);
                }

                R3DBox box = CalculateBoundingBox();
                box.Write(bw);
                CalculateBoundingSphere(box).Write(bw);

                foreach (SKNSubmesh submesh in this.Submeshes)
                {
                    foreach (ushort index in submesh.Indices)
                    {
                        bw.Write(index);
                    }
                }
                foreach (SKNSubmesh submesh in this.Submeshes)
                {
                    foreach (SKNVertex vertex in submesh.Vertices)
                    {
                        if (hasTangent && vertex.Tangent == null)
                        {
                            vertex.Tangent = new Vector4Byte(255, 255, 255, 255);
                        }
                        else if (!hasTangent && vertex.Tangent != null)
                        {
                            vertex.Tangent = null;
                        }

                        vertex.Write(bw);
                    }
                }
                bw.Write(new byte[12]);
            }
        }
        public void Write(Stream stream)
        {
            using (BinaryWriter bw = new BinaryWriter(stream))
            {
                bw.Write(0x00112233);
                bw.Write((ushort)4);
                bw.Write((ushort)1);
                bw.Write(this.Submeshes.Count);

                bool hasVertexColors = false;
                uint indexCount      = 0;
                uint vertexCount     = 0;
                foreach (SimpleSkinSubmesh submesh in this.Submeshes)
                {
                    if (!hasVertexColors)
                    {
                        foreach (SimpleSkinVertex vertex in submesh.Vertices)
                        {
                            if (vertex.Color != null)
                            {
                                hasVertexColors = true;
                                break;
                            }
                        }
                    }

                    submesh.Write(bw, vertexCount, indexCount);

                    indexCount  += (uint)submesh.Indices.Count;
                    vertexCount += (uint)submesh.Vertices.Count;
                }

                bw.Write((uint)0); //Flags
                bw.Write(indexCount);
                bw.Write(vertexCount);
                if (hasVertexColors)
                {
                    bw.Write((uint)56);
                    bw.Write((uint)SimpleSkinVertexType.Color);
                }
                else
                {
                    bw.Write((uint)52);
                    bw.Write((uint)SimpleSkinVertexType.Basic);
                }

                R3DBox box = GetBoundingBox();
                box.Write(bw);
                box.GetBoundingSphere().Write(bw);

                ushort indexOffset = 0;
                foreach (SimpleSkinSubmesh submesh in this.Submeshes)
                {
                    foreach (ushort index in submesh.Indices.Select(x => x += indexOffset))
                    {
                        bw.Write(index);
                    }

                    indexOffset += submesh.Indices.Max();
                }

                foreach (SimpleSkinSubmesh submesh in this.Submeshes)
                {
                    foreach (SimpleSkinVertex vertex in submesh.Vertices)
                    {
                        vertex.Write(bw, hasVertexColors ? SimpleSkinVertexType.Color : SimpleSkinVertexType.Basic);
                    }
                }

                bw.Write(new byte[12]); //End tab
            }
        }
Beispiel #18
0
        public SimpleSkin(Stream stream)
        {
            using (BinaryReader br = new BinaryReader(stream))
            {
                uint magic = br.ReadUInt32();
                if (magic != 0x00112233)
                {
                    throw new InvalidFileSignatureException();
                }

                ushort major = br.ReadUInt16();
                ushort minor = br.ReadUInt16();
                if (major != 0 && major != 2 && major != 4 && minor != 1)
                {
                    throw new UnsupportedFileVersionException();
                }

                uint indexCount  = 0;
                uint vertexCount = 0;
                SimpleSkinVertexType vertexType = SimpleSkinVertexType.Basic;
                if (major == 0)
                {
                    indexCount  = br.ReadUInt32();
                    vertexCount = br.ReadUInt32();
                }
                else
                {
                    uint submeshCount = br.ReadUInt32();

                    for (int i = 0; i < submeshCount; i++)
                    {
                        this.Submeshes.Add(new SimpleSkinSubmesh(br));
                    }
                    if (major == 4)
                    {
                        uint flags = br.ReadUInt32();
                    }

                    indexCount  = br.ReadUInt32();
                    vertexCount = br.ReadUInt32();

                    uint vertexSize = major == 4 ? br.ReadUInt32() : 52;
                    vertexType = major == 4 ? (SimpleSkinVertexType)br.ReadUInt32() : SimpleSkinVertexType.Basic;
                    R3DBox    boundingBox    = major == 4 ? new R3DBox(br) : new R3DBox(Vector3.Zero, Vector3.Zero);
                    R3DSphere boundingSphere = major == 4 ? new R3DSphere(br) : R3DSphere.Infinite;
                }

                List <ushort>           indices  = new List <ushort>();
                List <SimpleSkinVertex> vertices = new List <SimpleSkinVertex>();
                for (int i = 0; i < indexCount; i++)
                {
                    indices.Add(br.ReadUInt16());
                }
                for (int i = 0; i < vertexCount; i++)
                {
                    vertices.Add(new SimpleSkinVertex(br, vertexType));
                }

                if (major == 0)
                {
                    this.Submeshes.Add(new SimpleSkinSubmesh("Base", indices, vertices));
                }
                else
                {
                    foreach (SimpleSkinSubmesh submesh in this.Submeshes)
                    {
                        List <ushort> submeshIndices = indices.GetRange((int)submesh._startIndex, (int)submesh._indexCount);
                        ushort        minIndex       = submeshIndices.Min();

                        submesh.Indices  = submeshIndices.Select(x => x -= minIndex).ToList();
                        submesh.Vertices = vertices.GetRange((int)submesh._startVertex, (int)submesh._vertexCount);
                    }
                }
            }
        }
Beispiel #19
0
 /// <summary>
 /// Calculates a Bounding Sphere from a <see cref="R3DBox"/> and a Central Point of this <see cref="SKNSubmesh"/>
 /// </summary>
 /// <param name="box"><see cref="R3DBox"/> of this <see cref="SKNSubmesh"/></param>
 /// <param name="centralPoint">Position of the <see cref="R3DSphere"/></param>
 public R3DSphere CalculateBoundingSphere(R3DBox box, Vector3 centralPoint)
 {
     return(new R3DSphere(centralPoint, Vector3.Distance(centralPoint, box.Max)));
 }
        /// <summary>
        /// Initializes a new <see cref="SKNFile"/> from a <see cref="Stream"/>
        /// </summary>
        /// <param name="stream">The <see cref="Stream"/> to read from</param>
        public SKNFile(Stream stream)
        {
            using (BinaryReader br = new BinaryReader(stream))
            {
                uint magic = br.ReadUInt32();
                if (magic != 0x00112233)
                {
                    throw new Exception("Not a valid SKN file");
                }

                ushort major = br.ReadUInt16();
                ushort minor = br.ReadUInt16();
                if (major != 2 && major != 4 && minor != 1)
                {
                    throw new Exception("This SKN version is not supported");
                }

                uint submeshCount = br.ReadUInt32();

                for (int i = 0; i < submeshCount; i++)
                {
                    this.Submeshes.Add(new SKNSubmesh(this, br));
                }
                if (major == 4)
                {
                    uint unknown = br.ReadUInt32();
                }

                uint indexCount  = br.ReadUInt32();
                uint vertexCount = br.ReadUInt32();

                uint      vertexSize;
                bool      isTangent = false;
                R3DBox    boundingBox;
                R3DSphere boundingSphere;

                if (major == 4)
                {
                    vertexSize     = br.ReadUInt32();
                    isTangent      = br.ReadUInt32() == 1;
                    boundingBox    = new R3DBox(br);
                    boundingSphere = new R3DSphere(br);
                }

                List <ushort>    indices  = new List <ushort>();
                List <SKNVertex> vertices = new List <SKNVertex>();
                for (int i = 0; i < indexCount; i++)
                {
                    indices.Add(br.ReadUInt16());
                }
                for (int i = 0; i < vertexCount; i++)
                {
                    vertices.Add(new SKNVertex(br, isTangent));
                }

                foreach (SKNSubmesh submesh in this.Submeshes)
                {
                    submesh.Indices  = indices.GetRange((int)submesh._startIndex, (int)submesh._indexCount);
                    submesh.Vertices = vertices.GetRange((int)submesh._startVertex, (int)submesh._vertexCount);
                }
            }
        }