Beispiel #1
0
 internal static void WritePointlightConstants(LightId lid, ref MyPointlightConstants data)
 {
     data.VsPosition = Vector3.Transform(Lights.Data[lid.Index].Position - MyEnvironment.CameraPosition, ref MyEnvironment.ViewAt0);
     data.Range      = Pointlights[lid.Index].Range;
     data.Color      = Pointlights[lid.Index].Color;
     data.Falloff    = Pointlights[lid.Index].Falloff;
 }
Beispiel #2
0
        internal static Matrix CubeFaceViewMatrix(Vector3 pos, int faceId)
        {
            Matrix viewMatrix = Matrix.Identity;

            switch (faceId)
            {
            case 0:
                viewMatrix = Matrix.CreateLookAt(pos, pos + Vector3.Left, Vector3.Up);
                break;

            case 1:
                viewMatrix = Matrix.CreateLookAt(pos, pos + Vector3.Right, Vector3.Up);
                break;

            case 2:
                viewMatrix = Matrix.CreateLookAt(pos, pos + Vector3.Up, -Vector3.Backward);
                break;

            case 3:
                viewMatrix = Matrix.CreateLookAt(pos, pos + Vector3.Down, -Vector3.Forward);
                break;

            case 4:
                viewMatrix = Matrix.CreateLookAt(pos, pos + Vector3.Backward, Vector3.Up);
                break;

            case 5:
                viewMatrix = Matrix.CreateLookAt(pos, pos + Vector3.Forward, Vector3.Up);
                break;
            }



            return(viewMatrix);
        }
Beispiel #3
0
        public void Rescale(float scaleFactor)
        {
            if (m_scaleFactor != scaleFactor)
            {
                float scaleChange = scaleFactor / m_scaleFactor;
                m_scaleFactor = scaleFactor;

                for (int i = 0; i < m_verticesCount; i++)
                {
                    Vector3 p = GetVertex(i) * scaleChange;
                    SetVertexPosition(i, ref p);
                }

                if (Dummies != null)
                {
                    foreach (var dummy in Dummies)
                    {
                        var localMatrix = dummy.Value.Matrix;
                        localMatrix.Translation *= scaleChange;
                        dummy.Value.Matrix       = localMatrix;
                    }
                }

                BoundingBox.Min *= scaleChange;
                BoundingBox.Max *= scaleChange;

                BoundingBoxSize     = BoundingBox.Max - BoundingBox.Min;
                BoundingBoxSizeHalf = BoundingBoxSize / 2.0f;

                BoundingSphere.Radius *= scaleChange;
            }
        }
        internal static unsafe void UpdateGeneric(InstancingId id, List <MyInstanceData> instanceData, int capacity)
        {
            Debug.Assert(id.Info.Type == MyRenderInstanceBufferType.Generic);

            capacity = instanceData.Count;

            if (capacity != Instancings.Data[id.Index].TotalCapacity)
            {
                bool[]    mask      = new bool[capacity];
                Vector3[] positions = new Vector3[capacity];
                for (int i = 0; i < capacity; i++)
                {
                    mask[i]      = true;
                    positions[i] = new Vector3(instanceData[i].m_row0.ToVector4().W, instanceData[i].m_row1.ToVector4().W, instanceData[i].m_row2.ToVector4().W);
                }

                Instancings.Data[id.Index].VisibilityMask = mask;
                Instancings.Data[id.Index].Positions      = positions;
            }

            Instancings.Data[id.Index].TotalCapacity = capacity;
            Instancings.Data[id.Index].InstanceData  = instanceData.ToArray();

            RebuildGeneric(id);
        }
        internal static void AddBillboardOriented(string material,
                                                  Color color, Vector3D origin, Vector3 leftVector, Vector3 upVector, float radius, int priority = 0, int customViewProjection = -1)
        {
            Debug.Assert(material != null);

            origin.AssertIsValid();
            leftVector.AssertIsValid();
            upVector.AssertIsValid();
            radius.AssertIsValid();
            MyDebug.AssertDebug(radius > 0);

            MyBillboard billboard = SpawnBillboard();

            if (billboard == null)
            {
                return;
            }

            billboard.Priority             = priority;
            billboard.CustomViewProjection = customViewProjection;

            MyQuadD quad;

            MyUtils.GetBillboardQuadOriented(out quad, ref origin, radius, ref leftVector, ref upVector);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin);
        }
Beispiel #6
0
        public void Update(float updateStepTime)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyCamera-Update");
            Zoom.Update(updateStepTime);
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            Vector3 newCameraPosOffset = Vector3.Zero;

            // spring
            if (CameraSpring.Enabled)
            {
                CameraSpring.Update(updateStepTime, out newCameraPosOffset);
            }
            // shake
            if (CameraShake.ShakeEnabled)
            {
                Vector3 shakePos, shakeDir;
                CameraShake.UpdateShake(updateStepTime, out shakePos, out shakeDir);
                newCameraPosOffset += shakePos;
            }
            // apply
            if (newCameraPosOffset != Vector3.Zero)
            {
                Vector3D newCameraPosOffsetD = newCameraPosOffset;
                Vector3D newCameraPosOffsetRotatedD;
                Vector3D.Rotate(ref newCameraPosOffsetD, ref ViewMatrix, out newCameraPosOffsetRotatedD);
                ViewMatrix.Translation += newCameraPosOffsetRotatedD;
            }

            UpdatePropertiesInternal(ViewMatrix);
        }
Beispiel #7
0
        //Game and editor shares this method
        public void MoveAndRotatePlayerOrCamera()
        {
            MyCameraControllerEnum cce  = MySession.GetCameraControllerEnum();
            bool movementAllowedInPause = cce == MyCameraControllerEnum.Spectator;
            bool rotationAllowedInPause = movementAllowedInPause ||
                                          (cce == MyCameraControllerEnum.ThirdPersonSpectator && MyInput.Static.IsAnyAltKeyPressed());

            bool    allowRoll         = !MySessionComponentVoxelHand.Static.BuildMode;
            bool    allowMove         = !MySessionComponentVoxelHand.Static.BuildMode && !MyCubeBuilder.Static.IsBuildMode;
            float   rollIndicator     = allowRoll ? MyInput.Static.GetRoll() : 0;
            Vector2 rotationIndicator = MyInput.Static.GetRotation();

            VRageMath.Vector3 moveIndicator = allowMove ? MyInput.Static.GetPositionDelta() : Vector3.Zero;

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////
            ////  Decide who is moving
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //First move control objects
            if (MySession.ControlledEntity != null)// && MySession.ControlledObject != MySession.Static.CameraController)
            {
                if (MySandboxGame.IsPaused)
                {
                    if (!movementAllowedInPause && !rotationAllowedInPause)
                    {
                        return;
                    }

                    if (!rotationAllowedInPause)
                    {
                        rotationIndicator = Vector2.Zero;
                    }
                    rollIndicator = 0.0f;
                }
                if (MySession.Static.CameraController is MySpectatorCameraController && MySpectatorCameraController.Static.SpectatorCameraMovement == MySpectatorCameraMovementEnum.UserControlled)
                {
                    MySpectatorCameraController.Static.MoveAndRotate(moveIndicator, rotationIndicator, rollIndicator);
                }
                else
                {
                    if (!MySession.Static.CameraController.IsInFirstPersonView)
                    {
                        MyThirdPersonSpectator.Static.UpdateZoom();
                    }

                    if (!MyInput.Static.IsGameControlPressed(MyControlsSpace.LOOKAROUND))
                    {
                        MySession.ControlledEntity.MoveAndRotate(moveIndicator, rotationIndicator, rollIndicator);
                    }
                    else
                    {
                        MySession.ControlledEntity.MoveAndRotate(moveIndicator, Vector2.Zero, rollIndicator);
                        if (!MySession.Static.CameraController.IsInFirstPersonView)
                        {
                            MyThirdPersonSpectator.Static.SaveSettings();
                        }
                    }
                }
            }
        }
Beispiel #8
0
        static Matrix PrepareLocalRenderMatrix(Vector3 pos, int faceId)
        {
            var    projection = GetProjectionMatrixInfinite();
            Matrix viewMatrix = CubeFaceViewMatrix(pos, faceId);

            return(viewMatrix * projection);
        }
Beispiel #9
0
        internal static Matrix PrepareLocalEnvironmentMatrix(Vector3 pos, Vector2I resolution, int faceId, float farPlane)
        {
            var    projection = Matrix.CreatePerspectiveFieldOfView((float)Math.PI * 0.5f, 1, 0.5f, farPlane);
            Matrix viewMatrix = CubeFaceViewMatrix(pos, faceId);

            return(viewMatrix * projection);
        }
Beispiel #10
0
        static Matrix PrepareLocalCullingMatrix(Vector3 pos, int faceId, float farPlane)
        {
            var    projection = GetProjectionMatrix(farPlane);
            Matrix viewMatrix = CubeFaceViewMatrix(pos, faceId);

            return(viewMatrix * projection);
        }
 internal MyVertexFormatTexcoordNormalTangent(Vector2 texcoord, Vector3 normal, Vector3 tangent)
 {
     Texcoord = new HalfVector2(texcoord.X, texcoord.Y);
     Normal = VF_Packer.PackNormalB4(ref normal);
     Vector4 T = new Vector4(tangent, 1);
     Tangent = VF_Packer.PackTangentSignB4(ref T);
 }
Beispiel #12
0
        internal static void WritePointlightConstants(LightId lid, ref MyPointlightConstants data)
        {
            if (lid == LightId.NULL)
            {
                data = default(MyPointlightConstants);
                return;
            }

            data.VsPosition = Vector3.Transform(Lights.Data[lid.Index].PointPosition - MyRender11.Environment.CameraPosition, ref MyRender11.Environment.ViewAt0);
            if (MyStereoRender.Enable)
            {
                if (MyStereoRender.RenderRegion == MyStereoRegion.LEFT)
                {
                    data.VsPosition = Vector3.Transform(Lights.Data[lid.Index].PointPosition - MyStereoRender.EnvMatricesLeftEye.CameraPosition, ref MyStereoRender.EnvMatricesLeftEye.ViewAt0);
                }
                else if (MyStereoRender.RenderRegion == MyStereoRegion.RIGHT)
                {
                    data.VsPosition = Vector3.Transform(Lights.Data[lid.Index].PointPosition - MyStereoRender.EnvMatricesRightEye.CameraPosition, ref MyStereoRender.EnvMatricesRightEye.ViewAt0);
                }
            }
            data.Range       = Pointlights[lid.Index].Range;
            data.Color       = Pointlights[lid.Index].Color;
            data.Falloff     = Pointlights[lid.Index].Falloff;
            data.GlossFactor = Pointlights[lid.Index].GlossFactor;
        }
Beispiel #13
0
        internal static void AddBillboardOriented(string material,
                                                  Color color, Vector3D origin, Vector3 leftVector, Vector3 upVector, float radius, int priority = 0, float softParticleDistanceScale = 1.0f,
                                                  int customViewProjection = -1)
        {
            if (!MyRender11.DebugOverrides.BillboardsDynamic)
            {
                return;
            }

            Debug.Assert(material != null);

            origin.AssertIsValid();
            leftVector.AssertIsValid();
            upVector.AssertIsValid();
            radius.AssertIsValid();
            MyDebug.AssertDebug(radius > 0);

            MyBillboard billboard = MyBillboardRenderer.AddBillboardOnce();

            if (billboard == null)
            {
                return;
            }

            billboard.Priority             = priority;
            billboard.CustomViewProjection = customViewProjection;

            MyQuadD quad;

            MyUtils.GetBillboardQuadOriented(out quad, ref origin, radius, ref leftVector, ref upVector);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin, softParticleDistanceScale);
        }
Beispiel #14
0
        public void SetViewMatrix(MatrixD value)
        {
            ViewMatrix = value;

            MatrixD.Invert(ref ViewMatrix, out WorldMatrix);
            Position = WorldMatrix.Translation;
            InversePositionTranslationMatrix = MatrixD.CreateTranslation(-Position);

            PreviousPosition = Position;

            ForwardVector = (Vector3)WorldMatrix.Forward;
            UpVector      = (Vector3)WorldMatrix.Up;
            LeftVector    = (Vector3)WorldMatrix.Left;

            //  Projection matrix according to zoom level
            ProjectionMatrix = MatrixD.CreatePerspectiveFieldOfView(FovWithZoom, ForwardAspectRatio,
                                                                    GetSafeNear(),
                                                                    FarPlaneDistance);

            ProjectionMatrixFar = MatrixD.CreatePerspectiveFieldOfView(FovWithZoom, ForwardAspectRatio,
                                                                       GetSafeNear(),
                                                                       1000000);

            ViewProjectionMatrix    = ViewMatrix * ProjectionMatrix;
            ViewProjectionMatrixFar = ViewMatrix * ProjectionMatrixFar;

            //  Projection matrix according to zoom level
            float near = System.Math.Min(NearPlaneDistance, NearForNearObjects); //minimum cockpit distance

            ProjectionMatrixForNearObjects = MatrixD.CreatePerspectiveFieldOfView(FovWithZoomForNearObjects, ForwardAspectRatio,
                                                                                  near,
                                                                                  FarForNearObjects);

            float safenear = System.Math.Min(4, NearPlaneDistance); //minimum cockpit distance

            ViewMatrixAtZero     = value;
            ViewMatrixAtZero.M14 = 0;
            ViewMatrixAtZero.M24 = 0;
            ViewMatrixAtZero.M34 = 0;
            ViewMatrixAtZero.M41 = 0;
            ViewMatrixAtZero.M42 = 0;
            ViewMatrixAtZero.M43 = 0;
            ViewMatrixAtZero.M44 = 1;

            UpdateBoundingFrustum();

            VRageRender.MyRenderProxy.SetCameraViewMatrix(
                value,
                ProjectionMatrix,
                ProjectionMatrixForNearObjects,
                safenear,
                Zoom.GetFOVForNearObjects(),
                Zoom.GetFOV(),
                NearPlaneDistance,
                FarPlaneDistance,
                NearForNearObjects,
                FarForNearObjects,
                Position);
        }
        internal static void DrawTriangle(Vector3 v0, Vector3 v1, Vector3 v2, Color color)
        {
            var distance = ((v0 + v1 + v2) / 3f - MyEnvironment.CameraPosition).LengthSquared();
            m_triangleSortDistance.Add(distance);

            m_vertexList.Add(new MyVertexFormatPositionColor(v0, color));
            m_vertexList.Add(new MyVertexFormatPositionColor(v1, color));
            m_vertexList.Add(new MyVertexFormatPositionColor(v2, color));
        }
        static void UpdateVectors()
        {
            MatrixD invertedViewMatrix;

            MatrixD.Invert(ref ViewMatrix, out invertedViewMatrix);
            ForwardVector = (Vector3)invertedViewMatrix.Forward;
            LeftVector    = (Vector3)invertedViewMatrix.Left;
            UpVector      = (Vector3)invertedViewMatrix.Up;
        }
        public bool UpdatePhysicalMovement()
        {
            if (!Running)
            {
                return(false);
            }

            var characterPhysics = Character.Physics;

            var characterProxy = characterPhysics.CharacterProxy;

            if (characterProxy != null)
            {
                if (characterProxy.LinearVelocity.Length() < MyCharacter.MINIMAL_SPEED)
                {
                    characterProxy.LinearVelocity = Vector3.Zero;
                }
            }

            var rigidBody = characterPhysics.RigidBody;

            if (rigidBody != null)
            {
                rigidBody.Gravity = Vector3.Zero;

                if (MySession.Static.SurvivalMode || MyFakes.ENABLE_PLANETS_JETPACK_LIMIT_IN_CREATIVE)
                {
                    Vector3 planetGravity = MyGravityProviderSystem.CalculateNaturalGravityInPoint(Character.PositionComp.WorldAABB.Center);

                    if (planetGravity != Vector3.Zero)
                    {
                        rigidBody.Gravity = planetGravity * MyPerGameSettings.CharacterGravityMultiplier;
                    }
                }

                return(true);
            }
            else if (characterProxy != null)
            {
                characterProxy.Gravity = Vector3.Zero;

                if (MySession.Static.SurvivalMode || MyFakes.ENABLE_PLANETS_JETPACK_LIMIT_IN_CREATIVE)
                {
                    Vector3 planetGravity = MyGravityProviderSystem.CalculateNaturalGravityInPoint(Character.PositionComp.WorldAABB.Center);

                    if (planetGravity != Vector3.Zero)
                    {
                        characterProxy.Gravity = planetGravity * MyPerGameSettings.CharacterGravityMultiplier;
                    }
                }

                return(true);
            }

            return(false);
        }
Beispiel #18
0
        /// <summary>
        /// Returns a list of players near a grid.  Used to send messages
        /// </summary>
        /// <param name="grid"></param>
        /// <returns></returns>
        public static List <IMyPlayer> getPlayersWithinPlacementRadius(this IMyCubeGrid self)
        {
            log("Getting players near grid " + self.DisplayName);

            VRageMath.Vector3 gridSize        = self.LocalAABB.Size;
            float             gridMaxLength   = Math.Max(gridSize.X, Math.Max(gridSize.Y, gridSize.Z));
            float             maxDistFromGrid = gridMaxLength + INGAME_PLACEMENT_MAX_DISTANCE;

            return(self.getPlayersWithin(maxDistFromGrid));
        }
 void IMyEntity.SetColorMaskForSubparts(VRageMath.Vector3 colorMaskHsv)
 {
     if (Subparts != null)
     {
         foreach (var subPart in Subparts)
         {
             subPart.Value.Render.ColorMaskHsv = colorMaskHsv;
         }
     }
 }
        private static Ray ComputeIntersectionLine(ref Plane p1, ref Plane p2)
        {
            Ray ray = new Ray();

            ray.Direction = Vector3.Cross(p1.Normal, p2.Normal);
            float num = ray.Direction.LengthSquared();

            ray.Position = Vector3.Cross(-p1.D * p2.Normal + p2.D * p1.Normal, ray.Direction) / num;
            return(ray);
        }
Beispiel #21
0
        internal static void DrawTriangle(Vector3 v0, Vector3 v1, Vector3 v2, Color color)
        {
            var distance = ((v0 + v1 + v2) / 3f - (Vector3)MyEnvironment.CameraPosition).LengthSquared();

            m_triangleSortDistance.Add(distance);

            m_vertexList.Add(new MyVertexFormatPositionColor(v0, color));
            m_vertexList.Add(new MyVertexFormatPositionColor(v1, color));
            m_vertexList.Add(new MyVertexFormatPositionColor(v2, color));
        }
        public MyCsgShapeExcludedSphere(VRageMath.Vector3 translation, float radius, float exclusionRadius, float halfDeviation = 0, float deviationFrequency = 0, float detailFrequency = 0)
        {
            m_translation        = translation;
            m_radius             = radius;
            m_halfDeviation      = halfDeviation;
            m_deviationFrequency = deviationFrequency;
            m_detailFrequency    = detailFrequency;


            m_sphere          = new MyCsgSphere(translation, radius, halfDeviation, deviationFrequency, detailFrequency);
            m_exclusionSphere = new MyCsgSphere(translation, exclusionRadius, halfDeviation, deviationFrequency, detailFrequency);
        }
Beispiel #23
0
        internal static void GenerateVertexData(ref Vector3D worldPointA, ref Vector3D worldPointB,
                                                out MyVertexFormatPositionH4[] stream0, out MyVertexFormatTexcoordNormalTangentTexindices[] stream1)
        {
            var worldPosition = (worldPointA + worldPointB) * 0.5f;
            var pointA        = (Vector3)(worldPointA - worldPosition);
            var pointB        = (Vector3)(worldPointB - worldPosition);

            var length = (pointA - pointB).Length() * 10.0f;

            Vector3 lineTangent, normal, binormal;

            lineTangent = pointB - pointA;
            VRageMath.Vector3.Normalize(ref lineTangent, out lineTangent);
            lineTangent.CalculatePerpendicularVector(out normal);
            Vector3.Cross(ref lineTangent, ref normal, out binormal);

            var offsetX = normal * 0.025f;
            var offsetY = binormal * 0.025f;

            List <MyVertexFormatPositionH4> vertexPositionList = new List <MyVertexFormatPositionH4>();
            List <MyVertexFormatTexcoordNormalTangentTexindices> vertexList = new List <MyVertexFormatTexcoordNormalTangentTexindices>();

            Byte4 defaultArrayTexIndex = new Byte4(0, 0, 0, 0);

            unsafe
            {
                Vector3 *points = stackalloc Vector3[2];
                points[0] = pointA;
                points[1] = pointB;
                int vertexCounter = 0;
                for (int i = 0; i < 2; ++i)
                {
                    int   baseVertex = i * 4;
                    float texCoordX  = (i - 0.5f) * length;

                    vertexPositionList.Add(new MyVertexFormatPositionH4(points[i] + offsetX));
                    vertexList.Add(new MyVertexFormatTexcoordNormalTangentTexindices(new Vector2(texCoordX, 0.0f), normal, Vector3.Cross(lineTangent, normal), defaultArrayTexIndex));

                    vertexPositionList.Add(new MyVertexFormatPositionH4(points[i] + offsetY));
                    vertexList.Add(new MyVertexFormatTexcoordNormalTangentTexindices(new Vector2(texCoordX, 0.33333f), binormal, Vector3.Cross(lineTangent, binormal), defaultArrayTexIndex));

                    vertexPositionList.Add(new MyVertexFormatPositionH4(points[i] - offsetX));
                    vertexList.Add(new MyVertexFormatTexcoordNormalTangentTexindices(new Vector2(texCoordX, 0.66667f), -normal, Vector3.Cross(lineTangent, -normal), defaultArrayTexIndex));

                    vertexPositionList.Add(new MyVertexFormatPositionH4(points[i] - offsetY));
                    vertexList.Add(new MyVertexFormatTexcoordNormalTangentTexindices(new Vector2(texCoordX, 1.0f), -binormal, Vector3.Cross(lineTangent, -binormal), defaultArrayTexIndex));
                }
            }

            stream0 = vertexPositionList.ToArray();
            stream1 = vertexList.ToArray();
        }
Beispiel #24
0
        internal static void WritePointlightConstants(LightId lid, ref MyPointlightConstants data)
        {
            if (lid == LightId.NULL)
            {
                data = default(MyPointlightConstants);
                return;
            }

            data.VsPosition = Vector3.Transform(Lights.Data[lid.Index].PositionWithOffset - MyEnvironment.CameraPosition, ref MyEnvironment.ViewAt0);
            data.Range      = Pointlights[lid.Index].Range;
            data.Color      = Pointlights[lid.Index].Color;
            data.Falloff    = Pointlights[lid.Index].Falloff;
        }
Beispiel #25
0
        internal static void DrawNormalGlare(LightId light, ref MyGlareDesc glare, Vector3 L, float distance)
        {
            //if (m_occlusionRatio <= MyMathConstants.EPSILON)
            //    return;

            var intensity   = glare.Intensity;
            var maxDistance = glare.MaxDistance;

            //float alpha = m_occlusionRatio * intensity;
            float alpha = intensity;


            const float minGlareRadius = 0.2f;
            const float maxGlareRadius = 10;
            float       radius         = MathHelper.Clamp(glare.Range * 20, minGlareRadius, maxGlareRadius);

            float drawingRadius = radius * glare.Size;

            if (glare.Type == MyGlareTypeEnum.Directional)
            {
                float dot = Vector3.Dot(L, glare.Direction);
                alpha *= dot;
            }

            if (alpha <= MyMathConstants.EPSILON)
            {
                return;
            }

            if (distance > maxDistance * .5f)
            {
                // distance falloff
                float falloff = (distance - .5f * maxDistance) / (.5f * maxDistance);
                falloff        = (float)Math.Max(0, 1 - falloff);
                drawingRadius *= falloff;
                alpha         *= falloff;
            }

            if (drawingRadius <= float.Epsilon)
            {
                return;
            }

            var color = glare.Color;

            color.A = 0;

            MyBillboardsHelper.AddBillboardOriented(glare.Material.ToString(),
                                                    color * alpha, light.SpotPosition, MyEnvironment.InvView.Left, MyEnvironment.InvView.Up, drawingRadius);
        }
Beispiel #26
0
        //internal static void AttachHemisphericalLightInfo(LightId light, ref MyHemisphericalLightInfo info)
        //{
        //}

        internal static void Update()
        {
            // touch all lights again, because they don't get updated always when parent is
            foreach (var light in IdIndex.Values)
            {
                var position = light.LocalPosition;
                var gid      = light.ParentGID;
                if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null)
                {
                    var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix;

                    Vector3.Transform(ref position, ref matrix, out position);
                }
                Lights.Data[light.Index].Position = position;
            }

            if (DirtyPointlights.Count > 0)
            {
                foreach (var id in DirtyPointlights)
                {
                    var proxy    = Pointlights[id.Index].BvhProxyId;
                    var position = Lights.Data[id.Index].Position;
                    var range    = Pointlights[id.Index].Range;

                    var aabb = new BoundingBox(position - range, position + range);
                    Pointlights[id.Index].BvhProxyId            = UpdateBvh(PointlightsBvh, id, Pointlights[id.Index].Enabled, proxy, ref aabb);
                    Pointlights[id.Index].LastBvhUpdatePosition = position;
                }

                DirtyPointlights.Clear();
            }

            if (DirtySpotlights.Count > 0)
            {
                foreach (var id in DirtySpotlights)
                {
                    var proxy    = Spotlights[id.Index].BvhProxyId;
                    var position = Lights.Data[id.Index].Position;
                    var range    = Spotlights[id.Index].Range;

                    var aabb = MakeAabbFromSpotlightCone(ref Spotlights[id.Index], position);
                    Spotlights[id.Index].BvhProxyId            = UpdateBvh(SpotlightsBvh, id, Spotlights[id.Index].Enabled, proxy, ref aabb);
                    Spotlights[id.Index].LastBvhUpdatePosition = position;
                }

                DirtySpotlights.Clear();
            }
        }
Beispiel #27
0
        internal static void UpdateEntity(LightId light, ref MyLightInfo info)
        {
            Lights.Data[light.Index] = info;

            var position = info.Position;
            var gid      = info.ParentGID;

            if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null)
            {
                var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix;

                Vector3.Transform(ref position, ref matrix, out position);
            }

            Lights.Data[light.Index].Position = position;
        }
Beispiel #28
0
        void IPrimitiveManagerBase.GetPrimitiveBox(int prim_index, out AABB primbox)
        {
            BoundingBox bbox = BoundingBox.CreateInvalid();
            Vector3     v1   = GetVertex(Triangles[prim_index].I0);
            Vector3     v2   = GetVertex(Triangles[prim_index].I1);
            Vector3     v3   = GetVertex(Triangles[prim_index].I2);

            bbox.Include(
                ref v1,
                ref v2,
                ref v3);

            primbox = new AABB()
            {
                m_min = bbox.Min.ToBullet(), m_max = bbox.Max.ToBullet()
            };
        }
Beispiel #29
0
        internal static void UpdateSpotlight(LightId light, bool enabled,
                                             Vector3 direction, float range, float apertureCos, Vector3 up,
                                             Vector3 color, float falloff, float glossFactor, TexId reflectorTexture)
        {
            var info = Spotlights[light.Index];

            var gid = light.ParentGID;

            if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null)
            {
                var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix;

                Vector3.TransformNormal(ref direction, ref matrix, out direction);
                Vector3.TransformNormal(ref up, ref matrix, out up);
            }

            bool aabbChanged = info.Direction != direction || info.Range != range || info.ApertureCos != apertureCos || info.Up != up;

            Spotlights[light.Index].Enabled          = enabled;
            Spotlights[light.Index].Direction        = direction;
            Spotlights[light.Index].Range            = range;
            Spotlights[light.Index].ApertureCos      = apertureCos;
            Spotlights[light.Index].Up               = up;
            Spotlights[light.Index].Falloff          = falloff;
            Spotlights[light.Index].GlossFactor      = glossFactor;
            Spotlights[light.Index].Color            = color;
            Spotlights[light.Index].ReflectorTexture = reflectorTexture;

            var proxy = Spotlights[light.Index].BvhProxyId;
            var positionDifference = Vector3D.RectangularDistance(ref Spotlights[light.Index].LastBvhUpdatePosition, ref Lights.Data[light.Index].SpotPosition);

            bool dirty = (enabled && ((proxy == -1) || (positionDifference > MOVE_TOLERANCE || aabbChanged))) || (!enabled && proxy != -1);

            if (dirty)
            {
                DirtySpotlights.Add(light);
            }
            else
            {
                DirtySpotlights.Remove(light);
            }
        }
Beispiel #30
0
        internal unsafe void Update(MyRenderMessageDebugDrawMesh message)
        {
            edges = !message.Shaded;
            depth = message.DepthRead;

            if (vbuffer.ElementCount < message.VertexCount)
            {
                MyManagers.Buffers.Resize(vbuffer, message.VertexCount);
            }

            var mapping = MyMapping.MapDiscard(MyPrimitivesRenderer.RC, vbuffer);

            for (int i = 0; i < message.VertexCount; i++)
            {
                MyVertexFormatPositionColor vert = new MyVertexFormatPositionColor(Vector3.Transform(message.Vertices[i].Position, message.WorldMatrix), message.Vertices[i].Color);
                mapping.WriteAndPosition(ref vert);
            }
            mapping.Unmap();

            message.Vertices.Clear();
        }
Beispiel #31
0
        internal static void UpdatePointlight(LightId light, bool enabled, float range, Vector3 color, float falloff)
        {
            Pointlights[light.Index].Range   = range;
            Pointlights[light.Index].Color   = color;
            Pointlights[light.Index].Falloff = falloff;
            Pointlights[light.Index].Enabled = enabled;


            var proxy      = Pointlights[light.Index].BvhProxyId;
            var difference = Vector3.RectangularDistance(ref Pointlights[light.Index].LastBvhUpdatePosition, ref Lights.Data[light.Index].Position);

            bool dirty = (enabled && ((proxy == -1) || (difference > MOVE_TOLERANCE))) || (!enabled && proxy != -1);

            if (dirty)
            {
                DirtyPointlights.Add(light);
            }
            else
            {
                DirtyPointlights.Remove(light);
            }
        }
        internal static void AddBillboardOriented(string material,
            Color color, Vector3D origin, Vector3 leftVector, Vector3 upVector, float radius, int priority = 0, int customViewProjection = -1)
        {
            Debug.Assert(material != null);

            origin.AssertIsValid();
            leftVector.AssertIsValid();
            upVector.AssertIsValid();
            radius.AssertIsValid();
            MyDebug.AssertDebug(radius > 0);

            MyBillboard billboard = SpawnBillboard();
            if (billboard == null)
                return;

            billboard.Priority = priority;
            billboard.CustomViewProjection = customViewProjection;

            MyQuadD quad;
            MyUtils.GetBillboardQuadOriented(out quad, ref origin, radius, ref leftVector, ref upVector);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin);
        }
 internal MyVertexFormatPositionColor(Vector3 position, Byte4 color)
 {
     Position = position;
     Color = color;
 }
 internal MyVertexFormatPositionPackedColor(Vector3 position, Color color)
 {
     Position = new HalfVector4(position.X, position.Y, position.Z, 1);
     Color = new Byte4(color.PackedValue);
 }
Beispiel #35
0
        public void SetViewMatrix(MatrixD value)
        {
            ViewMatrix = value;

            MatrixD.Invert(ref ViewMatrix, out WorldMatrix);
            Position = WorldMatrix.Translation;
            InversePositionTranslationMatrix = MatrixD.CreateTranslation(-Position);

            PreviousPosition = Position;

            ForwardVector = (Vector3)WorldMatrix.Forward;
            UpVector = (Vector3)WorldMatrix.Up;
            LeftVector = (Vector3)WorldMatrix.Left;

            //  Projection matrix according to zoom level
            ProjectionMatrix = MatrixD.CreatePerspectiveFieldOfView(FovWithZoom, ForwardAspectRatio,
                GetSafeNear(),
                FarPlaneDistance);

            ViewProjectionMatrix = ViewMatrix * ProjectionMatrix;

            //  Projection matrix according to zoom level
            float near = System.Math.Min(NearPlaneDistance, NearForNearObjects); //minimum cockpit distance 
            ProjectionMatrixForNearObjects = MatrixD.CreatePerspectiveFieldOfView(FovWithZoomForNearObjects, ForwardAspectRatio,
                near,
                FarForNearObjects);

            float safenear = System.Math.Min(4, NearPlaneDistance); //minimum cockpit distance

            ViewMatrixAtZero = value;
            ViewMatrixAtZero.M14 = 0;
            ViewMatrixAtZero.M24 = 0;
            ViewMatrixAtZero.M34 = 0;
            ViewMatrixAtZero.M41 = 0;
            ViewMatrixAtZero.M42 = 0;
            ViewMatrixAtZero.M43 = 0;
            ViewMatrixAtZero.M44 = 1;

            UpdateBoundingFrustum();

            VRageRender.MyRenderProxy.SetCameraViewMatrix(
                value,
                ProjectionMatrix,
                ProjectionMatrixForNearObjects,
                safenear,
                Zoom.GetFOVForNearObjects(),
                Zoom.GetFOV(),
                NearPlaneDistance,
                FarPlaneDistance,
                NearForNearObjects,
                FarForNearObjects,
                Position);
        }
        internal static void DrawSceneDebug()
        {
            //if(true)
            //{
            //    //m_proj = MyEnvironment.Projection;
            //    //m_vp = MyEnvironment.ViewProjection;
            //    //m_invvp = MyEnvironment.InvViewProjection;

            //    Vector2 groupDim = new Vector2(256, 256);
            //    Vector2 tileScale = new Vector2(1600, 900) / (2 * groupDim);
            //    Vector2 tileBias = tileScale - new Vector2(1, 1);


            //    //Vector4 c1 = new Vector4(m_proj.M11 * tileScale.X, 0, tileBias.X, 0);
            //    //Vector4 c2 = new Vector4(0, -m_proj.M22 * tileScale.Y, tileBias.Y, 0);
            //    Vector4 c1 = new Vector4(m_proj.M11, 0, 0, 0);
            //    Vector4 c2 = new Vector4(0, m_proj.M22, 0, 0);
            //    Vector4 c4 = new Vector4(0, 0, 1, 0);

            //    var frustumPlane0 = new VRageMath.Plane(c4 - c1);
            //    var frustumPlane1 = new VRageMath.Plane(c4 + c1);
            //    var frustumPlane2 = new VRageMath.Plane(c4 - c2);
            //    var frustumPlane3 = new VRageMath.Plane(c4 + c2);
            //    frustumPlane0.Normalize();
            //    frustumPlane1.Normalize();
            //    frustumPlane2.Normalize();
            //    frustumPlane3.Normalize();


            //    var ray0 = ComputeIntersectionLine(ref frustumPlane2, ref frustumPlane0);
            //    var ray1 = ComputeIntersectionLine(ref frustumPlane1, ref frustumPlane2);
            //    var ray2 = ComputeIntersectionLine(ref frustumPlane3, ref frustumPlane1);
            //    var ray3 = ComputeIntersectionLine(ref frustumPlane0, ref frustumPlane3);


            //    TransformRay(ref ray0, ref m_invvp);
            //    TransformRay(ref ray1, ref m_invvp);
            //    TransformRay(ref ray2, ref m_invvp);
            //    TransformRay(ref ray3, ref m_invvp);


            //    var batch = MyLinesRenderer.CreateBatch();

            //    batch.Add(ray0.Position, ray0.Position + ray0.Direction * 100, Color.Red);
            //    batch.Add(ray1.Position, ray1.Position + ray1.Direction * 100, Color.Red);
            //    batch.Add(ray2.Position, ray2.Position + ray2.Direction * 100, Color.Red);
            //    batch.Add(ray3.Position, ray3.Position + ray3.Direction * 100, Color.Red);

            //    batch.AddFrustum(new BoundingFrustum(m_vp), Color.Green);

            //    batch.Commit();
                
            //}

            // draw lights
            //if(false)
            //{
            //    MyLinesBatch batch = MyLinesRenderer.CreateBatch();

            //    foreach (var light in MyLight.Collection)
            //    {
            //        if (light.PointLightEnabled)
            //        {
            //            var position = light.GetPosition();
            //            //batch.AddBoundingBox(new BoundingBox(position - light.Pointlight.Range, position + light.Pointlight.Range), Color.Red);

            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Range), new Color(light.Pointlight.Color), Matrix.Identity);
            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Range), new Color(light.Pointlight.Color), Matrix.CreateRotationX((float)Math.PI * 0.5f));
            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Range), new Color(light.Pointlight.Color), Matrix.CreateRotationZ((float)Math.PI * 0.5f));

            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Radius), new Color(light.Pointlight.Color), Matrix.Identity);
            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Radius), new Color(light.Pointlight.Color), Matrix.CreateRotationX((float)Math.PI * 0.5f));
            //        }
            //    }

            //    batch.Commit();
            //}

            //
            if (false)
            {
                MyLinesBatch batch = MyLinesRenderer.CreateBatch();

                foreach(var r in MyComponentFactory<MyRenderableComponent>.GetAll())
                {
                    if(r.m_owner.GetComponent(MyActorComponentEnum.Instancing) != null)
                    {
                        batch.AddBoundingBox((BoundingBox)r.m_owner.Aabb, Color.Blue);
                    }
                }

                batch.Commit();
            }

            if (false)
            {
                MyLinesBatch batch = MyLinesRenderer.CreateBatch();
                //var radius = new [] { 0, 40, 72, 128, 256 , 512 };
                var radius = new[] { 0, 50, 80, 128, 256, 512 };
                float cellSize = 8;

                var colors = new[] { Color.Red, Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.MediumVioletRed };

                var prevPositionG = Vector3.PositiveInfinity;
                for(int i=0; i<4; i++)
                {
                    float levelCellSize = cellSize * (float)Math.Pow(2, i);
                    var position = MyEnvironment.CameraPosition;
                    //var position = Vector3.Zero;
                    position.Y = 0;
                    var positionG = position.Snap(levelCellSize * 2);

                    float radiusMin = radius[i];
                    float radiusMax = radius[i+1];

                    // naive

                    var pmin = (positionG - radiusMax - levelCellSize * 2).Snap(levelCellSize * 2);
                    var pmax = (positionG + radiusMax + levelCellSize * 2).Snap(levelCellSize * 2);

                    //if(i==0)
                    //{
                    //    for (var x = pmin.X; x < pmax.X; x += levelCellSize)
                    //    {
                    //        for (var y = pmin.Y; y < pmax.Y; y += levelCellSize)
                    //        {
                    //            for (var z = pmin.Z; z < pmax.Z; z += levelCellSize)
                    //            {
                    //                var cell = new Vector3(x, y, z);
                    //                var rep = cell.Snap(levelCellSize * 2);

                    //                var inLevelGrid = (rep - positionG).Length() < radiusMax;
                    //                if(inLevelGrid)
                    //                {
                    //                    batch.AddBoundingBox(new BoundingBox(cell, cell + levelCellSize), colors[i]);
                    //                }
                    //            }
                    //        }
                    //    }
                    //}
                    //else 
                    { 
                        for (var x = pmin.X; x < pmax.X; x += levelCellSize)
                        {
                            for (var z = pmin.Z; z < pmax.Z; z += levelCellSize)
                            {
                                var cell = new Vector3(x, positionG.Y, z);
                                var rep = cell.Snap(levelCellSize * 2);

                                var inPrevLevelGrid = (cell - prevPositionG).Length() < radiusMin;
                                var inLevelGrid = (rep - positionG).Length() < radiusMax;

                                if (inLevelGrid && !inPrevLevelGrid)
                                {
                                    batch.AddBoundingBox(new BoundingBox(cell, cell + levelCellSize), colors[i]);
                                }
                            }
                        }
                    }

                    prevPositionG = positionG;
                }


                batch.Commit();
            }
        }
        //  Add billboard for one frame only. This billboard isn't particle (it doesn't survive this frame, doesn't have update/draw methods, etc).
        //  This billboard isn't facing the camera. It's always oriented in specified direction. May be used as thrusts, or inner light of reflector.
        //  It's used by other classes when they want to draw some billboard (e.g. rocket thrusts, reflector glare).
        public static void AddBillboardOriented(string material,
            Color color, Vector3D origin, Vector3 leftVector, Vector3 upVector, float radius, int priority = 0, bool colorize = false, int customViewProjection = -1)
        {
            Debug.Assert(material != null);

            if (!IsEnabled) return;

            origin.AssertIsValid();
            leftVector.AssertIsValid();
            upVector.AssertIsValid();
            radius.AssertIsValid();
            MyDebug.AssertDebug(radius > 0);


            MyBillboard billboard = m_billboardOncePool.Allocate();
            if (billboard == null)
                return;

            billboard.Priority = priority;
            billboard.CustomViewProjection = customViewProjection;

            MyQuadD quad;
            MyUtils.GetBillboardQuadOriented(out quad, ref origin, radius, ref leftVector, ref upVector);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin, colorize);

            m_billboardsOnce.Add(billboard);
        }
 internal MyVertexFormatPositionTextureH(Vector3 position, HalfVector2 texcoord)
 {
     Position = position;
     Texcoord = texcoord;
 }
 internal void Translate(Vector3 v)
 {
     m_row0.W += v.X;
     m_row1.W += v.Y;
     m_row2.W += v.Z;
 }
 internal static void DrawQuadRowWise(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, Color color)
 {
     DrawTriangle(v0, v1, v2, color);
     DrawTriangle(v1, v3, v2, color);
 }
        // Assuming engine order (+Z first)
        internal static unsafe void Draw6FacedConvexZ(Vector3* vertices, Color color, float alpha)
        {
            Color c = color;
            c.A = (byte)(alpha * 255);

            DrawQuadClockWise(vertices[0], vertices[1], vertices[2], vertices[3], c);
            DrawQuadClockWise(vertices[4], vertices[5], vertices[6], vertices[7], c);

            /* top left bottom right */
            DrawQuadClockWise(vertices[0], vertices[1], vertices[5], vertices[4], c);
            DrawQuadClockWise(vertices[0], vertices[3], vertices[7], vertices[4], c);
            DrawQuadClockWise(vertices[3], vertices[2], vertices[6], vertices[7], c);
            DrawQuadClockWise(vertices[2], vertices[1], vertices[5], vertices[6], c);
        }
        internal static unsafe void Draw6FacedConvexZ(Vector3[] vertices, Color color, float alpha)
        {
            Debug.Assert(vertices.Length == 8);

            fixed(Vector3* verticesPtr = vertices)
            {
                Draw6FacedConvexZ(verticesPtr, color, alpha);
            }
        }
 internal MyVertexFormatPositionColor(Vector3 position, Color color)
 {
     Position = position;
     Color = new Byte4(color.PackedValue);
 }
Beispiel #44
0
        internal static void UpdateSpotlight(LightId light, bool enabled, 
            Vector3 direction, float range, float apertureCos, Vector3 up,
            Vector3 color, float falloff, TexId reflectorTexture)
        {
            var info = Spotlights[light.Index];

            var gid = light.ParentGID;
            if (gid != -1 && MyIDTracker<MyActor>.FindByID((uint)gid) != null)
            {
                var matrix = MyIDTracker<MyActor>.FindByID((uint)gid).WorldMatrix;
                Vector3.TransformNormal(ref direction, ref matrix, out direction);
                Vector3.TransformNormal(ref up, ref matrix, out up);
            }

            bool aabbChanged = info.Direction != direction || info.Range != range || info.ApertureCos != apertureCos || info.Up != up;

            Spotlights[light.Index].Enabled = enabled;
            Spotlights[light.Index].Direction = direction;
            Spotlights[light.Index].Range = range;
            Spotlights[light.Index].ApertureCos = apertureCos;
            Spotlights[light.Index].Up = up;
            Spotlights[light.Index].Falloff = falloff;
            Spotlights[light.Index].Color = color;
            Spotlights[light.Index].ReflectorTexture = reflectorTexture;

            var proxy = Spotlights[light.Index].BvhProxyId;
            var positionDifference = Vector3D.RectangularDistance(ref Spotlights[light.Index].LastBvhUpdatePosition, ref Lights.Data[light.Index].PositionWithOffset);

            bool dirty = (enabled && ((proxy == -1) || (positionDifference > MOVE_TOLERANCE || aabbChanged))) || (!enabled && proxy != -1);

            if (dirty)
            {
                DirtySpotlights.Add(light);
            }
            else
            {
                DirtySpotlights.Remove(light);
            }
        }
 internal MyVertexFormatPositionH4(Vector3 position)
 {
     
     Position = VF_Packer.PackPosition(ref position);
 }
Beispiel #46
0
        //  Sort of lazy-load, where constructor just saves information about what this model should be, but real load is done here - and only one time.
        //  This loads only vertex data, doesn't touch GPU
        //  Can be called from main and background thread
        public void LoadData()
        {
            if (m_loadedData) return;

            lock (this)
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadData");


                MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS);
                MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS);

                MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS);

                //  Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need.
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data");

                MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS);


                string assetForImport = AssetName;
                var fsPath = Path.IsPathRooted(AssetName) ? AssetName : Path.Combine(MyFileSystem.ContentPath, AssetName);
                if (!MyFileSystem.FileExists(fsPath))
                {
                    assetForImport = @"Models\Debug\Error.mwm";
                }

                try
                {
                    m_importer.ImportData(assetForImport);
                }
                catch
                {
                    MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName));
                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    throw;
                }
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                DataVersion = m_importer.DataVersion;

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data");
                Dictionary<string, object> tagData = m_importer.GetTagData();
                if (tagData.Count == 0)
                {
                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName));
                }
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - vertex, normals, texture coords");


                HalfVector4[] vertices = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES];

                System.Diagnostics.Debug.Assert(vertices.Length > 0);

                Byte4[] normals = (Byte4[])tagData[MyImporterConstants.TAG_NORMALS];
                m_vertices = new MyCompressedVertexNormal[vertices.Length];
                if (normals.Length > 0)
                {
                    for (int v = 0; v < vertices.Length; v++)
                    {
                        m_vertices[v] = new MyCompressedVertexNormal()
                        {
                            Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]),
                            Normal = normals[v]//VF_Packer.PackNormalB4(ref normals[v])
                        };
                    }
                }
                else
                {
                    for (int v = 0; v < vertices.Length; v++)
                    {
                        m_vertices[v] = new MyCompressedVertexNormal()
                        {
                            Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]),
                        };
                    }
                }


                m_verticesCount = vertices.Length;

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - mesh");
                m_meshContainer.Clear();

                if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_PARTS))
                {
                    List<int> indices = new List<int>(GetVerticesCount()); // Default capacity estimation
                    int maxIndex = 0;

                    List<MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List<MyMeshPartInfo>;
                    foreach (MyMeshPartInfo meshPart in meshParts)
                    {
                        MyMesh mesh = new MyMesh(meshPart, m_assetName);
                        mesh.IndexStart = indices.Count;
                        mesh.TriCount = meshPart.m_indices.Count / 3;

                        if (m_loadUV && false == m_hasUV)
                        {
                            m_texCoords = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0];
                            m_hasUV = true;
                            m_loadUV = false;
                        }

                        if (meshPart.m_MaterialDesc != null && meshPart.Technique == MyMeshDrawTechnique.GLASS)
                        {
                            GlassData = mesh;

                            HalfVector2[] forLoadingTexCoords0 = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0];
                            List<HalfVector2> neededTexCoords = new List<HalfVector2>();

                            for (int t = 0; t < meshPart.m_indices.Count; t++)
                            {
                                int index = meshPart.m_indices[t];
                                neededTexCoords.Add(forLoadingTexCoords0[index]);
                            }

                            GlassTexCoords = neededTexCoords.ToArray();
                        }

                        System.Diagnostics.Debug.Assert(mesh.TriCount > 0);

                        if (mesh.TriCount == 0)
                        {
                            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                            return;
                        }

                        foreach (var i in meshPart.m_indices)
                        {
                            indices.Add(i);
                            if (i > maxIndex)
                            {
                                maxIndex = i;
                            }
                        }



                        m_meshContainer.Add(mesh);
                    }

                    if (maxIndex <= ushort.MaxValue)
                    {
                        // create 16 bit indices
                        m_Indices_16bit = new ushort[indices.Count];
                        for (int i = 0; i < indices.Count; i++)
                        {
                            m_Indices_16bit[i] = (ushort)indices[i];
                        }
                    }
                    else
                    {
                        // use 32bit indices
                        m_Indices = indices.ToArray();
                    }
                }

                if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_BVH))
                {
                    m_bvh = new MyQuantizedBvhAdapter(tagData[MyImporterConstants.TAG_MODEL_BVH] as GImpactQuantizedBvh, this);
                }

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - other data");

                Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS];
                Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES];

                BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX];
                BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE];
                BoundingBoxSize = BoundingBox.Max - BoundingBox.Min;
                BoundingBoxSizeHalf = BoundingBoxSize / 2.0f;
                Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>;
                BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[];

                if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_FRACTURES))
                    ModelFractures = (MyModelFractures)tagData[MyImporterConstants.TAG_MODEL_FRACTURES];

                object patternScale;
                if (tagData.TryGetValue(MyImporterConstants.TAG_PATTERN_SCALE, out patternScale))
                {
                    PatternScale = (float)patternScale;
                }

                if (BoneMapping.Length == 0)
                    BoneMapping = null;

                if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY))
                {
                    HavokData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY];
                    byte[] tagCollisionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY];
                    if (tagCollisionData.Length > 0 && HkBaseSystem.IsThreadInitialized)
                    {
                        bool containsSceneData;
                        bool containsDestructionData;
                        List<HkShape> shapesList = new List<HkShape>();
                        if (!HkShapeLoader.LoadShapesListFromBuffer(tagCollisionData, shapesList, out containsSceneData, out containsDestructionData))
                        {
                            MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry", AssetName), LoggingOptions.LOADING_MODELS);
                        //Debug.Fail("Collision model was exported in wrong way: " + m_assetName);
                        }

                        if (shapesList.Count > 10)
                            MyLog.Default.WriteLine(string.Format("Model {0} - Found too many collision shapes, only the first 10 will be used", AssetName), LoggingOptions.LOADING_MODELS);

                        if (HavokCollisionShapes != null)
                        {
                            Debug.Fail("Shapes already loaded");
                        }
                        if (shapesList.Count > 0)
                        {
                            HavokCollisionShapes = shapesList.ToArray();
                        }
                        else
                        {
                            MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry from file, default collision will be used !", AssetName));
                        }

                        if (containsDestructionData)
                            HavokDestructionData = tagCollisionData;

                        ExportedWrong = !containsSceneData;
                    }
                }


                if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_DESTRUCTION))
                {
                    if (((byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]).Length > 0)
                        HavokDestructionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION];
                }

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - copy triangle indices");
                //  Prepare data
                CopyTriangleIndices();
                m_trianglesCount = Triangles.Count();

                //  Remember this numbers as list may be cleared at the end of this method
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                MyLog.Default.WriteLine("Triangles.Length: " + Triangles.Length, LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("Vertexes.Length: " + GetVerticesCount(), LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("Centered: " + (bool)tagData[MyImporterConstants.TAG_CENTERED], LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("Length in meters: " + (float)tagData[MyImporterConstants.TAG_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("Rescale to length in meters?: " + (bool)tagData[MyImporterConstants.TAG_RESCALE_TO_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS);

                Stats.PerAppLifetime.MyModelsCount++;
                Stats.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count;
                Stats.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount();
                Stats.PerAppLifetime.MyModelsTrianglesCount += Triangles.Length;

                ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize);

                m_loadedData = true;
                m_loadingErrorProcessed = false;
                MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("MyModel.LoadData -> END", LoggingOptions.LOADING_MODELS);

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
        internal static RenderableId CreateRenderable(EntityId entity, MeshId model, Vector3 keyColor)
        {
            var id = new RenderableId { Index = Renderables.Allocate() };

            Renderables.Data[id.Index] = new MyRenderableInfo
            {
                KeyColor = keyColor,
                ObjectDithering = 0,
                Mesh = model
            };

            EntityDirty.Add(entity);

            RenderableIndex[entity] = id;

            return id;
        }
Beispiel #48
0
 static void UpdateVectors()
 {
     MatrixD invertedViewMatrix;
     MatrixD.Invert(ref ViewMatrix, out invertedViewMatrix);
     ForwardVector = (Vector3)invertedViewMatrix.Forward;
     LeftVector = (Vector3)invertedViewMatrix.Left;
     UpVector = (Vector3)invertedViewMatrix.Up;
 }
Beispiel #49
0
        internal static void UpdatePointlight(LightId light, bool enabled, float range, Vector3 color, float falloff)
        {
            Pointlights[light.Index].Range = range;
            Pointlights[light.Index].Color = color;
            Pointlights[light.Index].Falloff = falloff;
            Pointlights[light.Index].Enabled = enabled;

            
            var proxy = Pointlights[light.Index].BvhProxyId;
            var difference = Vector3D.RectangularDistance(ref Pointlights[light.Index].LastBvhUpdatePosition, ref Lights.Data[light.Index].PositionWithOffset);

            bool dirty = (enabled && ((proxy == -1) || (difference > MOVE_TOLERANCE))) || (!enabled && proxy != -1);

            if(dirty)
            {
                DirtyPointlights.Add(light);
            }
            else
            {
                DirtyPointlights.Remove(light);
            }
        }
        internal override void Construct()
        {
            base.Construct();

            Type = MyActorComponentEnum.Renderable;
            //m_mesh = null;
            m_lods = null;
            m_cullProxy = MyProxiesFactory.CreateCullProxy();
            m_btreeProxy = -1;

            Mesh = MeshId.NULL;
            Instancing = InstancingId.NULL;
            
            m_instanceCount = 0;
            m_startInstance = 0;

            m_isRenderedStandalone = true;

            m_keyColor = Vector3.One;
            m_objectDithering = 0;

            m_renderableProxiesForLodTransition = null;

            m_lodTransitionState = 0;
            m_lod = 0;

            m_voxelLod = -1;
            m_additionalFlags = 0;

            ModelProperties = new Dictionary<MyEntityMaterialKey, MyModelProperties>();
        }
Beispiel #51
0
 public void GetVertex(int vertexIndex1, int vertexIndex2, int vertexIndex3, out Vector3 v1, out Vector3 v2, out Vector3 v3)
 {
     v1 = GetVertex(vertexIndex1);
     v2 = GetVertex(vertexIndex2);
     v3 = GetVertex(vertexIndex3);
 }
 internal MyVertexFormatTexcoordNormalTangent(HalfVector2 texcoord, Vector3 normal, Vector4 tangent)
 {
     Texcoord = texcoord;
     Normal = VF_Packer.PackNormalB4(ref normal);
     Tangent = VF_Packer.PackTangentSignB4(ref tangent);
 }
Beispiel #53
0
        public void LoadAnimationData()
        {
            if (m_loadedData) return;

            lock (this)
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadAnimationData");


                MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS);
                MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS);

                MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS);

                //  Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need.
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data");

                MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS);
                try
                {
                    m_importer.ImportData(AssetName);
                }
                catch
                {
                    MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName));
                    throw;
                }
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data");
                Dictionary<string, object> tagData = m_importer.GetTagData();
                if (tagData.Count == 0)
                {
                    throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName));
                }

                DataVersion = m_importer.DataVersion;

                Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS];
                Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES];

                BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX];
                BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE];
                BoundingBoxSize = BoundingBox.Max - BoundingBox.Min;
                BoundingBoxSizeHalf = BoundingBoxSize / 2.0f;
                Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>;
                BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[];
                if (BoneMapping.Length == 0)
                    BoneMapping = null;

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize);

                m_loadedData = true;

                MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("MyModel.LoadAnimationData -> END", LoggingOptions.LOADING_MODELS);

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
 internal MyVertexFormatTexcoordNormalTangentTexindices(Vector2 texcoord, Vector3 normal, Vector3 tangent, Byte4 texIndices)
 {
     Texcoord = new HalfVector2(texcoord.X, texcoord.Y);
     Normal = VF_Packer.PackNormalB4(ref normal);
     Vector4 T = new Vector4(tangent, 1);
     Tangent = VF_Packer.PackTangentSignB4(ref T);
     TexIndices = texIndices;
 }
 internal MyVertexFormatPosition(Vector3 position)
 {
     Position = position;
 }
 internal MyVertexFormatPositionPackedColor(Vector3 position, Byte4 color)
 {
     Position = new HalfVector4(position.X, position.Y, position.Z, 1);
     Color = color;
 }
Beispiel #57
0
        public void LoadBuffers(MyModelData modelData, string assetName = null)
        {
            System.Diagnostics.Debug.Assert(modelData.Sections.Count > 0, "Invalid object");
            if (modelData.Sections.Count == 0)
                return;

            // create index buffer
            {
                m_trianglesCount = modelData.Indices.Count / 3;
                m_Indices_16bit = new ushort[modelData.Indices.Count];

                for (int i = 0; i < modelData.Indices.Count; ++i)
                    m_Indices_16bit[i] = (ushort)modelData.Indices[i];

                m_indexBuffer = new IndexBuffer(MyRender.GraphicsDevice, m_Indices_16bit.Length * sizeof(short), Usage.WriteOnly, Pool.Default, true);
                m_indexBuffer.SetData(m_Indices_16bit);
                m_indexBuffer.Tag = this;
                m_indexBufferSize = m_Indices_16bit.Length * sizeof(short);

                SignResource(m_indexBuffer);
            }

            // create vertex buffer
            {
                m_verticesCount = modelData.Positions.Count;
                m_vertices      = new MyCompressedVertexNormal[m_verticesCount];
                var vertexArray = new MyVertexFormatPositionNormalTextureTangent[m_verticesCount];

                for (int i = 0; i < modelData.Positions.Count; ++i)
                {
                    vertexArray[i].Position = modelData.Positions[i];
                    vertexArray[i].Normal   = modelData.Normals[i];
                    vertexArray[i].Tangent  = modelData.Tangents[i];
                    vertexArray[i].TexCoord = modelData.TexCoords[i];

                    m_vertices[i] = new MyCompressedVertexNormal()
                    {
                        Position = vertexArray[i].PositionPacked,
                        Normal   = vertexArray[i].NormalPacked
                    };
                }

                m_vertexDeclaration = MyVertexFormatPositionNormalTextureTangent.VertexDeclaration;
                m_vertexStride      = MyVertexFormatPositionNormalTextureTangent.Stride;
                m_vertexBufferSize  = vertexArray.Length * m_vertexStride;
                m_vertexBuffer      = new VertexBuffer(MyRender.GraphicsDevice, m_vertexBufferSize, Usage.WriteOnly, VertexFormat.None, Pool.Default);
                m_vertexBuffer.SetData(vertexArray);
                m_vertexBuffer.Tag = this;

                SignResource(m_vertexBuffer);
            }

            m_meshContainer.Clear();

            // apply materials here
            for (int s = 0; s < modelData.Sections.Count; ++s)
            {
                var mpi            = new MyMeshPartInfo();
                mpi.Technique      = m_drawTechnique;
                
                // Disabled, because it assert always when models are loaded before materials
                //System.Diagnostics.Debug.Assert(MyRenderModels.Materials.ContainsKey(modelData.Sections[s].MaterialName), "Mesh material not present!");
                
                if (MyRenderModels.Materials.ContainsKey(modelData.Sections[s].MaterialName))
                    mpi.m_MaterialDesc = MyRenderModels.Materials[modelData.Sections[s].MaterialName];

                var start = modelData.Sections[s].IndexStart;
                var end   = start + modelData.Sections[s].TriCount*3;

                for (int i = start; i < end; ++i)
                    mpi.m_indices.Add(modelData.Indices[i]);

                m_meshContainer.Add(new MyRenderMesh(mpi, null)
                {
                    IndexStart = modelData.Sections[s].IndexStart,
                    TriCount   = modelData.Sections[s].TriCount
                });
            }

            // store properties of this model
            {
                BoundingBox    = modelData.AABB;
                BoundingSphere = new BoundingSphere(modelData.AABB.Center, modelData.AABB.HalfExtents.Length());

                BoundingBoxSize     = BoundingBox.Size;
                BoundingBoxSizeHalf = BoundingBox.HalfExtents;

                ModelInfo = new MyModelInfo(m_trianglesCount, m_verticesCount, BoundingBoxSize);

                PreloadTextures(LoadingMode.Immediate);
                LoadState = Textures.LoadState.Loaded;

                m_loadedContent = true;
                m_loadedData    = true;
            }
        }
        internal static void DrawNormalGlare(LightId light, ref MyGlareDesc glare, Vector3 L, float distance)
        {
            //if (m_occlusionRatio <= MyMathConstants.EPSILON)
            //    return;

            var intensity = glare.Intensity;
            var maxDistance = glare.MaxDistance;

            //float alpha = m_occlusionRatio * intensity;
            float alpha = intensity;


            const float minGlareRadius = 0.2f;
            const float maxGlareRadius = 10;
            float radius = MathHelper.Clamp(glare.Range * 20, minGlareRadius, maxGlareRadius);

            float drawingRadius = radius * glare.Size;

            if (glare.Type == MyGlareTypeEnum.Directional)
            {
                float dot = Vector3.Dot(L, glare.Direction);
                alpha *= dot;
            }

            if (alpha <= MyMathConstants.EPSILON)
                return;

            if (distance > maxDistance * .5f)
            {
                // distance falloff
                float falloff = (distance - .5f * maxDistance) / (.5f * maxDistance);
                falloff = (float)Math.Max(0, 1 - falloff);
                drawingRadius *= falloff;
                alpha *= falloff;
            }

            if (drawingRadius <= float.Epsilon)
                return;

            var color = glare.Color;
            color.A = 0;

            MyBillboardsHelper.AddBillboardOriented(glare.Material.ToString(), 
                color * alpha, light.Position, MyEnvironment.InvView.Left, MyEnvironment.InvView.Up, drawingRadius);
        }
        //  Add billboard for one frame only. This billboard isn't particle (it doesn't survive this frame, doesn't have update/draw methods, etc).
        //  It's used by other classes when they want to draw some billboard (e.g. rocket thrusts, reflector glare).
        public static void AddLineBillboard(string material,
            Color color, Vector3D origin, Vector3 directionNormalized, float length, float thickness, int priority = 0, bool near = false, int customViewProjection = -1)
        {
            Debug.Assert(material != null);

            if (!IsEnabled) return;

            origin.AssertIsValid();
            length.AssertIsValid();
            MyDebug.AssertDebug(length > 0);
            MyDebug.AssertDebug(thickness > 0);

            VRageRender.MyBillboard billboard = m_billboardOncePool.Allocate();
            if (billboard == null)
                return;

            billboard.Priority = priority;
            billboard.CustomViewProjection = customViewProjection;

            MyPolyLineD polyLine;
            polyLine.LineDirectionNormalized = directionNormalized;
            polyLine.Point0 = origin;
            polyLine.Point1 = origin + directionNormalized * length;
            polyLine.Thickness = thickness;

            MyQuadD quad;
            MyUtilsRender9.GetPolyLineQuad(out quad, ref polyLine);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin, false, near);

            m_billboardsOnce.Add(billboard);
        }
Beispiel #60
0
        //  Sort of lazy-load, where constructor just saves information about what this model should be, but real load is done here - and only one time.
        //  This loads only vertex data, doesn't touch GPU
        //  Can be called from main and background thread
        public void LoadData()
        {
            if (m_loadedData) return;
            if (m_loadedContent) return;

            lock (this)
            {
                if (m_loadedData) return;
                if (m_loadedContent) return;

                MyRender.GetRenderProfiler().StartProfilingBlock("MyModel::LoadData");


                MyRender.Log.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS);
                MyRender.Log.IncreaseIndent(LoggingOptions.LOADING_MODELS);

                MyRender.Log.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS);

                //  Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need.
                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - import data");

                string assetForImport = AssetName;
                var fsPath = Path.IsPathRooted(AssetName) ? AssetName : Path.Combine(MyFileSystem.ContentPath, AssetName);
                if (!MyFileSystem.FileExists(fsPath))
                {
                    MyRender.Log.WriteLine("ERROR: Asset " + AssetName + "not exists!");
                    assetForImport = @"Models\Debug\Error.mwm";
                }

                MyRender.Log.WriteLine(String.Format("Importing asset {0}, path: {1}", assetForImport, AssetName), LoggingOptions.LOADING_MODELS);
                try
                {
                    m_importer.ImportData(assetForImport);
                }
                catch
                {
                    MyRender.Log.WriteLine(String.Format("Importing asset failed {0}", m_assetName));
                    throw;
                }
                MyRender.GetRenderProfiler().EndProfilingBlock();

                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data");
                Dictionary<string, object> tagData = m_importer.GetTagData();
                if (tagData.Count == 0)
                {
                    throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName));
                }
                MyRender.GetRenderProfiler().EndProfilingBlock();

                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - vertex, normals, texture coords");

                object patternScale;
                if (tagData.TryGetValue(MyImporterConstants.TAG_PATTERN_SCALE, out patternScale))
                {
                    PatternScale = (float)patternScale;
                }

                HalfVector4[] vertices = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES];

                //Dont assert, it can be animation
                //System.Diagnostics.Debug.Assert(vertices.Length > 0);

                Byte4[] normals = (Byte4[])tagData[MyImporterConstants.TAG_NORMALS];
                m_vertices = new MyCompressedVertexNormal[vertices.Length];
                if (normals.Length > 0)
                {
                    for (int v = 0; v < vertices.Length; v++)
                    {
                        m_vertices[v] = new MyCompressedVertexNormal()
                        {
                            Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]),
                            Normal = normals[v]//VF_Packer.PackNormalB4(ref normals[v])
                        };
                    }
                }
                else
                {
                    for (int v = 0; v < vertices.Length; v++)
                    {
                        m_vertices[v] = new MyCompressedVertexNormal()
                        {
                            Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]),
                        };
                    }
                }

                m_verticesCount = vertices.Length;

                HalfVector2[] forLoadingTexCoords0 = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0];
                m_forLoadingTexCoords0 = new HalfVector2[forLoadingTexCoords0.Length];
                for (int t = 0; t < forLoadingTexCoords0.Length; t++)
                {
                    m_forLoadingTexCoords0[t] = forLoadingTexCoords0[t];// new HalfVector2(forLoadingTexCoords0[t]);
                    m_forLoadingTexCoords0[t] = new HalfVector2(m_forLoadingTexCoords0[t].ToVector2() / PatternScale);
                }

                MyRender.GetRenderProfiler().EndProfilingBlock();

                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - mesh");
                m_meshContainer.Clear();

                if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_PARTS))
                {
                    List<int> indices = new List<int>(GetVerticesCount()); // Default capacity estimation
                    int maxIndex = 0;

                    List<MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List<MyMeshPartInfo>;
                    foreach (MyMeshPartInfo meshPart in meshParts)
                    {
                        if (meshPart.m_MaterialDesc != null)
                            MyRenderModels.Materials[meshPart.m_MaterialDesc.MaterialName] = meshPart.m_MaterialDesc;

                        MyRenderMesh mesh = new MyRenderMesh(meshPart, m_assetName);

                        mesh.IndexStart = indices.Count;
                        mesh.TriCount = meshPart.m_indices.Count / 3;

                        System.Diagnostics.Debug.Assert(mesh.TriCount > 0);

                        foreach (var i in meshPart.m_indices)
                        {
                            indices.Add(i);
                            if (i > maxIndex)
                            {
                                maxIndex = i;
                            }
                        }

                        m_meshContainer.Add(mesh);

                        if (meshPart.m_MaterialDesc != null && meshPart.Technique == MyMeshDrawTechnique.GLASS)
                        {
                            float minimumGlassShadow = 0.0f;

                            if (string.IsNullOrEmpty(meshPart.m_MaterialDesc.GlassCW))
                                continue;

                            if (string.IsNullOrEmpty(meshPart.m_MaterialDesc.GlassCCW))
                                continue;

                            var materialCW = MyTransparentMaterials.GetMaterial(meshPart.m_MaterialDesc.GlassCW);
                            var materialCCW = MyTransparentMaterials.GetMaterial(meshPart.m_MaterialDesc.GlassCCW);

                            mesh.GlassDithering = System.Math.Max(materialCW.Color.W, minimumGlassShadow);

                            MyRenderMesh glassMesh = new MyRenderMesh(meshPart, m_assetName);
                            glassMesh.GlassDithering = System.Math.Max(materialCCW.Color.W, minimumGlassShadow);


                            glassMesh.IndexStart = indices.Count;
                            glassMesh.TriCount = meshPart.m_indices.Count / 3;

                            System.Diagnostics.Debug.Assert(glassMesh.TriCount > 0);

                            for (int i = 0; i < meshPart.m_indices.Count; i += 3)
                            {
                                indices.Add(meshPart.m_indices[i + 0]);
                                indices.Add(meshPart.m_indices[i + 2]);
                                indices.Add(meshPart.m_indices[i + 1]);
                            }

                            m_meshContainer.Add(glassMesh);
                        }
                    }

                    if (maxIndex <= ushort.MaxValue)
                    {
                        // create 16 bit indices
                        m_Indices_16bit = new ushort[indices.Count];
                        for (int i = 0; i < indices.Count; i++)
                        {
                            m_Indices_16bit[i] = (ushort)indices[i];
                        }
                    }
                    else
                    {
                        // use 32bit indices
                        m_Indices = indices.ToArray();
                    }

                    m_trianglesCount = indices.Count / 3;
                }


                MyRender.GetRenderProfiler().EndProfilingBlock();

                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - other data");
                if (MyRenderConstants.RenderQualityProfile.UseNormals && m_forLoadingTexCoords0.Length > 0)
                {
                    var verticesNum = vertices.Length;
                    
                    Byte4[] forLoadingTangents = (Byte4[])tagData[MyImporterConstants.TAG_TANGENTS];
                    Byte4[] forLoadingBitangents = (Byte4[])tagData[MyImporterConstants.TAG_BINORMALS];
                    m_forLoadingTangents = new Byte4[forLoadingTangents.Length];

                    for (int v = 0; v < forLoadingTangents.Length; v++)
                    {
                        var N = VF_Packer.UnpackNormal(m_vertices[v].Normal.PackedValue);
                        var T = VF_Packer.UnpackNormal(forLoadingTangents[v].PackedValue);
                        var B = VF_Packer.UnpackNormal(forLoadingBitangents[v].PackedValue);

                        var tangentSign = new Vector4(T.X, T.Y, T.Z, 0);
                        tangentSign.W = T.Cross(N).Dot(B) < 0 ? -1 : 1;

                        m_forLoadingTangents[v] = VF_Packer.PackTangentSignB4(ref tangentSign);
                    }
                }

                m_specularShininess = (float)tagData[MyImporterConstants.TAG_SPECULAR_SHININESS];
                m_specularPower = (float)tagData[MyImporterConstants.TAG_SPECULAR_POWER];
                m_rescaleFactor = (float)tagData[MyImporterConstants.TAG_RESCALE_FACTOR];

                BoneIndices = (Vector4I[])tagData[MyImporterConstants.TAG_BLENDINDICES];
                BoneWeights = (Vector4[])tagData[MyImporterConstants.TAG_BLENDWEIGHTS];

                Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS];
                Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES];
                
                if(BoneIndices.Length > 0 && Bones.Length > MyRenderConstants.MAX_SHADER_BONES)
                {
                    List<MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List<MyMeshPartInfo>;

                    Dictionary<int, int> vertexChanged = new Dictionary<int,int>();
                    for(int p=0; p<meshParts.Count; p++)
                    {
                        var meshPart = meshParts[p];

                        Dictionary<int, int> bonesUsed = new Dictionary<int, int>();

                        int trianglesNum = meshPart.m_indices.Count / 3;
                        for (int i = 0; i < trianglesNum; i++)
                        {
                            for (int j = 0; j < 3; j++)
                            {
                                int index = meshPart.m_indices[i * 3 + j];
                                if(BoneWeights[index].X > 0)
                                    bonesUsed[BoneIndices[index].X] = 1;
                                if (BoneWeights[index].Y > 0)
                                    bonesUsed[BoneIndices[index].Y] = 1;
                                if (BoneWeights[index].Z > 0)
                                    bonesUsed[BoneIndices[index].Z] = 1;
                                if (BoneWeights[index].W > 0)
                                    bonesUsed[BoneIndices[index].W] = 1;
                            }
                        }

                        var partBones = new List<int>(bonesUsed.Keys);
                        partBones.Sort();
                        if (partBones.Count > 0 && partBones[partBones.Count - 1] >= MyRenderConstants.MAX_SHADER_BONES)
                        {
                            for(int i=0; i<partBones.Count; i++)
                            {
                                bonesUsed[partBones[i]] = i;
                            }

                            Dictionary<int, int> vertexTouched = new Dictionary<int, int>();

                            for (int i = 0; i < trianglesNum; i++)
                            {
                                for (int j = 0; j < 3; j++)
                                {
                                    int index = meshPart.m_indices[i * 3 + j];
                                    if(!vertexTouched.ContainsKey(index))
                                    { 
                                        if (BoneWeights[index].X > 0)
                                            BoneIndices[index].X = bonesUsed[BoneIndices[index].X];
                                        if (BoneWeights[index].Y > 0)
                                            BoneIndices[index].Y = bonesUsed[BoneIndices[index].Y];
                                        if (BoneWeights[index].Z > 0)
                                            BoneIndices[index].Z = bonesUsed[BoneIndices[index].Z];
                                        if (BoneWeights[index].W > 0)
                                            BoneIndices[index].W = bonesUsed[BoneIndices[index].W];

                                        vertexTouched[index] = 1;

                                        int changes = 0;
                                        vertexChanged.TryGetValue(index, out changes);
                                        vertexChanged[index] = changes + 1;
                                    }
                                }
                            }

                            m_meshContainer[p].BonesUsed = partBones.ToArray();
                        }
                    }

                    if (vertexChanged.Values.Count > 0)
                        Debug.Assert(vertexChanged.Values.Max() < 2, "Vertex shared between model parts, will likely result in wrong skinning");
                }

                BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX];
                BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE];
                BoundingBoxSize = BoundingBox.Max - BoundingBox.Min;
                BoundingBoxSizeHalf = BoundingBoxSize / 2.0f;
                Dictionary<string, MyModelDummy> Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>;
                MyRender.GetRenderProfiler().EndProfilingBlock();

                if (tagData.ContainsKey(MyImporterConstants.TAG_LODS))
                {
                    var tagLODs = tagData[MyImporterConstants.TAG_LODS];

                    LODs.Clear();
                    LODs.AddArray((MyLODDescriptor[])tagLODs);

                    foreach (var lodDesc in LODs)
                    {
                        if (!string.IsNullOrEmpty(lodDesc.RenderQuality))
                        {
                            lodDesc.RenderQualityList = new List<int>();
                            string[] qualityStrings = lodDesc.RenderQuality.ToUpper().Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string qs in qualityStrings)
                            {
                                string qs2 = qs.Trim();
                                if (qs2 == "LOW")
                                    lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.LOW);
                                else
                                    if (qs2 == "NORMAL")
                                        lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.NORMAL);
                                    else
                                        if (qs2 == "HIGH")
                                            lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.HIGH);
                                        else
                                            if (qs2 == "EXTREME")
                                                lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.EXTREME);
                            }
                        }
                    }
                }


                MyRender.Log.WriteLine("Vertexes.Length: " + GetVerticesCount(), LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("Centered: " + (bool)tagData[MyImporterConstants.TAG_CENTERED], LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("Length in meters: " + (float)tagData[MyImporterConstants.TAG_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("Rescale to length in meters?: " + (bool)tagData[MyImporterConstants.TAG_RESCALE_TO_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("SpecularShininess: " + m_specularShininess, LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("SpecularPower: " + m_specularPower, LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("RescaleFactor: " + m_rescaleFactor, LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS);

                MyPerformanceCounter.PerAppLifetime.MyModelsCount++;
                MyPerformanceCounter.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count;
                MyPerformanceCounter.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount();
                MyPerformanceCounter.PerAppLifetime.MyModelsTrianglesCount += m_trianglesCount;

                ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize);

                m_loadedData = true;

                m_importer.Clear();

                MyRender.Log.DecreaseIndent(LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("MyModel.LoadData -> END", LoggingOptions.LOADING_MODELS);

                MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }