예제 #1
0
        public TerrainRenderer(int id, IEnumerable <FileInfo> files, ZoneType type, ClientDataWrapper wrapper)
            : base(id, files, type, wrapper)
        {
            // Init Terrain Height Calculator
            TerrainHeightCache = TerrainHeightCalculator;

            AddNifCache(TerrainNifs);
            AddNifInstancesYZSwapped(TerrainFixtures);

            // Store Terrain
            var terrain  = TerrainHeightMap;
            var vertices = new List <Vector3>();
            var indices  = new List <TriangleIndex>();

            for (int x = 0; x < terrain.Length; x++)
            {
                var yLength = terrain[x].Length;
                for (int y = 0; y < yLength; y++)
                {
                    var height = terrain[x][y];
                    vertices.Add(new Vector3(x, height, y));
                }
            }

            var width = terrain.Length;

            for (int x = 0; x < terrain.Length - 1; x++)
            {
                var yLength = terrain[x].Length;
                for (int y = 0; y < yLength - 1; y++)
                {
                    var tri1 = new TriangleIndex
                    {
                        A = (uint)((x + 1) * width + (y + 1)),
                        B = (uint)((x + 1) * width + y),
                        C = (uint)(x * width + y),
                    };
                    var tri2 = new TriangleIndex
                    {
                        A = (uint)((x + 1) * width + (y + 1)),
                        B = (uint)(x * width + y),
                        C = (uint)(x * width + (y + 1)),
                    };

                    indices.Add(tri1);
                    indices.Add(tri2);
                }
            }

            // Build Terrain object as a Primitive Nif
            var Terrain = new TriangleCollection
            {
                Vertices = vertices.ToArray(),
                Indices  = indices.ToArray(),
            };

            // Add Terrain like a Nif
            var insertid = 0;

            if (NifCache.Count > 0)
            {
                insertid = NifCache.Max(kv => kv.Key) + 1;
            }

            NifCache.Add(insertid, new ClientMesh("terrain", Terrain, Terrain, Terrain));
            InstancesMatrix = InstancesMatrix.Concat(new [] { new KeyValuePair <int, Matrix>(insertid, Matrix.Identity) }).ToArray();
        }
예제 #2
0
        /// <summary>
        /// Get World Matrix For NifGeometry
        /// </summary>
        /// <param name="nifGeom"></param>
        /// <param name="UnitFactor"></param>
        /// <param name="heightCalculator"></param>
        /// <returns></returns>
        protected static Matrix ComputeWorldMatrix(NifGeometry nifGeom, float UnitFactor, TerrainHeightCalculator heightCalculator)
        {
            if (nifGeom == null)
                throw new ArgumentNullException("nifGeom");

            // Find Ground
            float nifHeight = nifGeom.Z * UnitFactor;
            if (nifGeom.OnGround)
            {
                nifHeight = heightCalculator[nifGeom.X, nifGeom.Y] * UnitFactor;
            }

            // Get Translation (XY Inverted), Scale, Rotation
            Matrix translation;
            ZoneDrawingExtensions.CreateTranslation(nifGeom.X * UnitFactor, nifHeight, nifGeom.Y * UnitFactor, out translation);
            Matrix scale;
            ZoneDrawingExtensions.CreateScale(nifGeom.Scale * UnitFactor, out scale);
            Matrix rotation;
            ZoneDrawingExtensions.CreateRotation(new Vector3(nifGeom.RotationX, nifGeom.RotationY, nifGeom.RotationZ), nifGeom.Angle , out rotation);

            Matrix result = Matrix.Identity;
            // Flip if needed
            if (nifGeom.Flip)
            {
                Matrix flip;
                ZoneDrawingExtensions.CreateScale(-1f, 1f, 1f, out flip);
                result = flip;
            }

            Matrix intermediateResult;
            // Combine Scale, Rotation, Invertion Rotation, Translation
            ZoneDrawingExtensions.Mult(ref result, ref scale, out intermediateResult);
            result = intermediateResult;
            ZoneDrawingExtensions.Mult(ref result, ref rotation, out intermediateResult);
            result = intermediateResult;
            ZoneDrawingExtensions.Mult(ref result, ref RotationMatrix, out intermediateResult);
            result = intermediateResult;
            ZoneDrawingExtensions.Mult(ref result, ref translation, out intermediateResult);
            result = intermediateResult;

            // Combine Matrix with Parent Matrix
            if (nifGeom.RelativeTo != null)
            {
                Matrix relativeMatrix = ComputeWorldMatrix(nifGeom.RelativeTo, UnitFactor, heightCalculator);
                ZoneDrawingExtensions.Mult(ref result, ref relativeMatrix, out intermediateResult);
                result = intermediateResult;
            }

            return result;
        }
예제 #3
0
        /// <summary>
        /// Get World Matrix For NifGeometry
        /// </summary>
        /// <param name="nifGeom"></param>
        /// <param name="UnitFactor"></param>
        /// <param name="heightCalculator"></param>
        /// <returns></returns>
        protected static Matrix ComputeWorldMatrix(NifGeometry nifGeom, float UnitFactor, TerrainHeightCalculator heightCalculator)
        {
            if (nifGeom == null)
            {
                throw new ArgumentNullException("nifGeom");
            }

            // Find Ground
            float nifHeight = nifGeom.Z * UnitFactor;

            if (nifGeom.OnGround)
            {
                nifHeight = heightCalculator[nifGeom.X, nifGeom.Y] * UnitFactor;
            }

            // Get Translation (XY Inverted), Scale, Rotation
            Matrix translation;

            ZoneDrawingExtensions.CreateTranslation(nifGeom.X * UnitFactor, nifHeight, nifGeom.Y * UnitFactor, out translation);
            Matrix scale;

            ZoneDrawingExtensions.CreateScale(nifGeom.Scale * UnitFactor, out scale);
            Matrix rotation;

            ZoneDrawingExtensions.CreateRotation(new Vector3(nifGeom.RotationX, nifGeom.RotationY, nifGeom.RotationZ), nifGeom.Angle, out rotation);

            Matrix result = Matrix.Identity;

            // Flip if needed
            if (nifGeom.Flip)
            {
                Matrix flip;
                ZoneDrawingExtensions.CreateScale(-1f, 1f, 1f, out flip);
                result = flip;
            }

            Matrix intermediateResult;

            // Combine Scale, Rotation, Invertion Rotation, Translation
            ZoneDrawingExtensions.Mult(ref result, ref scale, out intermediateResult);
            result = intermediateResult;
            ZoneDrawingExtensions.Mult(ref result, ref rotation, out intermediateResult);
            result = intermediateResult;
            ZoneDrawingExtensions.Mult(ref result, ref RotationMatrix, out intermediateResult);
            result = intermediateResult;
            ZoneDrawingExtensions.Mult(ref result, ref translation, out intermediateResult);
            result = intermediateResult;

            // Combine Matrix with Parent Matrix
            if (nifGeom.RelativeTo != null)
            {
                Matrix relativeMatrix = ComputeWorldMatrix(nifGeom.RelativeTo, UnitFactor, heightCalculator);
                ZoneDrawingExtensions.Mult(ref result, ref relativeMatrix, out intermediateResult);
                result = intermediateResult;
            }

            return(result);
        }