Example #1
0
        /// <summary>
        /// Adds instance of the given model and returns its internal id which can be used for removing the instance. Local matrix specified will be changed to internal packed matrix.
        /// </summary>
        /// <param name="model"></param>
        /// <param name="localMatrix">Local transformation matrix. Changed to internal matrix.</param>
        /// <param name="colorMaskHsv"></param>
        public uint AddInstance(ModelId model, ref Matrix localMatrix, BoundingBox localAabb, Vector4 colorMaskHsv = default(Vector4))
        {
            MyModelInstanceData builderInstanceData;

            if (!m_instanceParts.TryGetValue(model, out builderInstanceData))
            {
                builderInstanceData       = new MyModelInstanceData(m_instanceFlags, m_maxViewDistance);
                builderInstanceData.Model = model;
                m_instanceParts.Add(model, builderInstanceData);
            }

            uint instanceId = m_idCounter++;

            var instanceData = new MyCubeInstanceData()
            {
                ColorMaskHSV   = colorMaskHsv,
                EnableSkinning = false,
                LocalMatrix    = localMatrix
            };

            instanceData.SetColorMaskHSV(colorMaskHsv);

            builderInstanceData.InstanceData.Add(instanceId, instanceData);
            // Matrix has been changed due to packing.
            localMatrix = builderInstanceData.InstanceData[instanceId].LocalMatrix;

            m_AABB = m_AABB.Include(localAabb.Transform(localMatrix));

            return(instanceId);
        }
Example #2
0
        private void AddEdgeParts(Dictionary <MyInstanceBucket, Tuple <List <MyCubeInstanceMergedData>, Sandbox.Game.Entities.Cube.MyInstanceInfo> > instanceParts)
        {
            MyCubeInstanceData instance = new MyCubeInstanceData();

            instance.ResetBones();
            instance.SetTextureOffset(new Vector4UByte(0, 0, 1, 1));
            foreach (KeyValuePair <long, MyEdgeRenderData> pair in this.m_edgesToRender)
            {
                int            modelId  = pair.Value.ModelId;
                MyFourEdgeInfo edgeInfo = pair.Value.EdgeInfo;
                instance.PackedOrthoMatrix = edgeInfo.LocalOrthoMatrix;
                this.AddInstancePart(instanceParts, modelId, MyStringHash.NullOrEmpty, ref instance, null, 0, this.EdgeViewDistance);
            }
        }
Example #3
0
        // TODO: this parameter won't be optional
        public void AddInstance(ModelId model, MatrixD matrix, ref MatrixD invGridWorldMatrix, Vector4 colorMaskHsv = default(Vector4), Vector3UByte[] bones = null, float gridSize = 1f)
        {
            Matrix localMatrix = (Matrix)(matrix * invGridWorldMatrix);

            MyBuilderInstanceData builderInstanceData;

            if (!m_instanceParts.TryGetValue(model, out builderInstanceData))
            {
                builderInstanceData       = new MyBuilderInstanceData();
                builderInstanceData.Model = model;
                m_instanceParts.Add(model, builderInstanceData);
            }

            if (bones == null)
            {
                builderInstanceData.InstanceData.Add(new MyCubeInstanceData()
                {
                    ColorMaskHSV   = new Vector4(MyPlayer.SelectedColor, 0),
                    EnableSkinning = false,
                    LocalMatrix    = localMatrix
                });
            }
            else
            {
                var cubeInstance = new MyCubeInstanceData()
                {
                    ColorMaskHSV   = new Vector4(MyPlayer.SelectedColor, 0),
                    EnableSkinning = true,
                    LocalMatrix    = localMatrix,
                };

                cubeInstance.BoneRange = gridSize;

                for (int i = 0; i < 9; i++)
                {
                    cubeInstance[i] = bones[i];
                }

                builderInstanceData.InstanceData.Add(cubeInstance);
            }

            m_cubeBuilderAABB = m_cubeBuilderAABB.Include(
                new BoundingBox(new Vector3(-MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large)),
                                new Vector3(MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large))).Transform(localMatrix));
        }
        void AddInstancePart(Dictionary <ModelId, Tuple <List <MyCubeInstanceMergedData>, MyInstanceInfo> > instanceParts,
                             ModelId modelId, ref MyCubeInstanceData instance, List <uint> decals,
                             MyInstanceFlagsEnum flags, float maxViewDistance = float.MaxValue)
        {
            Tuple <List <MyCubeInstanceMergedData>, MyInstanceInfo> matrices;

            if (!instanceParts.TryGetValue(modelId, out matrices))
            {
                matrices = Tuple.Create(new List <MyCubeInstanceMergedData>(), new MyInstanceInfo(flags, maxViewDistance));
                instanceParts.Add(modelId, matrices);
            }

            m_tmpBoundingBox.Min = instance.LocalMatrix.Translation - new Vector3(m_gridRenderComponent.GridSize);
            m_tmpBoundingBox.Max = instance.LocalMatrix.Translation + new Vector3(m_gridRenderComponent.GridSize);
            m_boundingBox.Include(m_tmpBoundingBox);

            matrices.Item1.Add(new MyCubeInstanceMergedData()
            {
                CubeInstanceData = instance, Decals = decals
            });
        }
Example #5
0
        private void AddInstancePart(Dictionary <MyInstanceBucket, Tuple <List <MyCubeInstanceMergedData>, Sandbox.Game.Entities.Cube.MyInstanceInfo> > instanceParts, int modelId, MyStringHash skinSubtypeId, ref MyCubeInstanceData instance, ConcurrentDictionary <uint, bool> decals, MyInstanceFlagsEnum flags, float maxViewDistance = 3.402823E+38f)
        {
            Tuple <List <MyCubeInstanceMergedData>, Sandbox.Game.Entities.Cube.MyInstanceInfo> tuple;
            MyInstanceBucket key = new MyInstanceBucket(modelId, skinSubtypeId);

            if (!instanceParts.TryGetValue(key, out tuple))
            {
                tuple = Tuple.Create <List <MyCubeInstanceMergedData>, Sandbox.Game.Entities.Cube.MyInstanceInfo>(new List <MyCubeInstanceMergedData>(), new Sandbox.Game.Entities.Cube.MyInstanceInfo(flags, maxViewDistance));
                instanceParts.Add(key, tuple);
            }
            Vector3 translation = instance.LocalMatrix.Translation;

            this.m_tmpBoundingBox.Min = translation - new Vector3(this.m_gridRenderComponent.GridSize);
            this.m_tmpBoundingBox.Max = translation + new Vector3(this.m_gridRenderComponent.GridSize);
            this.m_boundingBox.Include(this.m_tmpBoundingBox);
            MyCubeInstanceMergedData item = new MyCubeInstanceMergedData {
                CubeInstanceData = instance,
                Decals           = decals
            };

            tuple.Item1.Add(item);
        }
        /// <summary>
        /// Adds instance of the given model and returns its internal id which can be used for removing the instance. Local matrix specified will be changed to internal packed matrix.
        /// </summary>
        /// <param name="model"></param>
        /// <param name="localMatrix">Local transformation matrix. Changed to internal matrix.</param>
        /// <param name="colorMaskHsv"></param>
        public uint AddInstance(ModelId model, ref Matrix localMatrix, BoundingBox localAabb, Vector4 colorMaskHsv = default(Vector4))
        {
            MyModelInstanceData builderInstanceData;
            if (!m_instanceParts.TryGetValue(model, out builderInstanceData))
            {
                builderInstanceData = new MyModelInstanceData(m_instanceFlags, m_maxViewDistance);
                builderInstanceData.Model = model;
                m_instanceParts.Add(model, builderInstanceData);
            }

            uint instanceId = m_idCounter++;

            var instanceData = new MyCubeInstanceData()
            {
                ColorMaskHSV = colorMaskHsv,
                EnableSkinning = false,
                LocalMatrix = localMatrix
            };
            instanceData.SetColorMaskHSV(colorMaskHsv);

            builderInstanceData.InstanceData.Add(instanceId, instanceData);
            // Matrix has been changed due to packing.
            localMatrix = builderInstanceData.InstanceData[instanceId].LocalMatrix;

            m_AABB = m_AABB.Include(localAabb.Transform(localMatrix));

            return instanceId;
        }
        void AddInstancePart(Dictionary<ModelId, Tuple<List<MyCubeInstanceData>, MyInstanceInfo>> instanceParts, ModelId modelId, ref MyCubeInstanceData instance, MyInstanceFlagsEnum flags, float maxViewDistance = float.MaxValue)
        {
            Tuple<List<MyCubeInstanceData>, MyInstanceInfo> matrices;
            if (!instanceParts.TryGetValue(modelId, out matrices))
            {
                matrices = new Tuple<List<MyCubeInstanceData>, MyInstanceInfo>(new List<MyCubeInstanceData>(), new MyInstanceInfo(flags, maxViewDistance));
                instanceParts.Add(modelId, matrices);
            }

            m_tmpBoundingBox.Min = instance.LocalMatrix.Translation - new Vector3(m_gridRenderComponent.GridSize);
            m_tmpBoundingBox.Max = instance.LocalMatrix.Translation + new Vector3(m_gridRenderComponent.GridSize);
            m_boundingBox.Include(m_tmpBoundingBox);

            matrices.Item1.Add(instance);
        }
        private void AddEdgeParts(Dictionary<ModelId, Tuple<List<MyCubeInstanceData>, MyInstanceInfo>> instanceParts)
        {
            // This can be optimized in same way as cube parts are
            m_edgesToCompare.Clear();
            float reduceEpsilon = 0.1f;

            MyCubeInstanceData inst = new MyCubeInstanceData();
            inst.ResetBones();
            inst.SetTextureOffset(new Vector2(0, 0));

            foreach (var edgeInfoPair in m_edgeInfosNew)
            {
                if (edgeInfoPair.Value.Full/* || edgeInfoPair.Value.Empty*/)
                    continue;

                bool isVisible = false;
                m_edgesToCompare.Clear();

                //Find opposite normals and remove them
                Color color;
                int edgeModel;
                Base27Directions.Direction normal0, normal1;
                for (int i = 0; i < MyFourEdgeInfo.MaxInfoCount; i++)
                {
                    if (edgeInfoPair.Value.GetNormalInfo(i, out color, out edgeModel, out normal0, out normal1))
                    {
                        m_edgesToCompare.Add(new EdgeInfoNormal() { Normal = Base27Directions.GetVector(normal0), Color = color, EdgeModel = edgeModel });
                        m_edgesToCompare.Add(new EdgeInfoNormal() { Normal = Base27Directions.GetVector(normal1), Color = color, EdgeModel = edgeModel });
                    }
                }

                int c = 0;
                bool wasFour = m_edgesToCompare.Count == 4;
                int baseEdgeModel = m_edgesToCompare[0].EdgeModel;

                while (c < m_edgesToCompare.Count)
                {
                    bool normalsRemoved = false;
                    for (int c2 = c + 1; c2 < m_edgesToCompare.Count; c2++)
                    {
                        //opposite normals?
                        if (MyUtils.IsZero(m_edgesToCompare[c].Normal + m_edgesToCompare[c2].Normal, reduceEpsilon))
                        {
                            if (c > c2)
                            {
                                m_edgesToCompare.RemoveAt(c);
                                m_edgesToCompare.RemoveAt(c2);
                            }
                            else
                            {
                                m_edgesToCompare.RemoveAt(c2);
                                m_edgesToCompare.RemoveAt(c);
                            }

                            normalsRemoved = true;
                            break;
                        }
                    }

                    if (normalsRemoved)
                        continue;

                    c++;
                }

                Debug.Assert(m_edgesToCompare.Count != 1, "Alone edge with one normal cannot exist");

                bool resultEdgesHaveDifferentColor = false;
                bool resultEdgesHaveDifferentArmorType = false;
                
                if (m_edgesToCompare.Count > 0)
                {
                    Color baseColor = m_edgesToCompare[0].Color;
                    foreach (var edge in m_edgesToCompare)
                    {
                        if (edge.Color != baseColor)
                        {
                            resultEdgesHaveDifferentColor = true;
                            break;
                        }
                    }


                    baseEdgeModel = m_edgesToCompare[0].EdgeModel;
                    foreach (var edge in m_edgesToCompare)
                    {
                        resultEdgesHaveDifferentArmorType |= baseEdgeModel != edge.EdgeModel;
                    }
                }

                if (m_edgesToCompare.Count == 1)
                    isVisible = false;
                else if (resultEdgesHaveDifferentColor || resultEdgesHaveDifferentArmorType)
                    isVisible = true;
                else
                    if (m_edgesToCompare.Count > 2)
                        isVisible = true;
                    else
                        if (m_edgesToCompare.Count == 0)
                            isVisible = wasFour;
                        else
                        {
                            Debug.Assert(m_edgesToCompare.Count == 2);

                            //Check normals angle to get visibility
                            float d = Vector3.Dot(m_edgesToCompare[0].Normal, m_edgesToCompare[1].Normal);

                            Debug.Assert(d != -1, "We already removed opposite normals");

                            if (Math.Abs(d) > 0.85f)
                            {   //consider this without outline
                                isVisible = false;
                            }
                            else
                                isVisible = true;
                        }

                if (isVisible)
                {
                    var definition = MyDefinitionManager.Static.GetEdgesDefinition(new MyDefinitionId(new MyObjectBuilderType(typeof(MyObjectBuilder_EdgesDefinition)), MyStringId.Get(baseEdgeModel)));
                    var edgesSet = m_gridRenderComponent.GridSizeEnum == MyCubeSize.Large ? definition.Large : definition.Small;

                    int modelId = 0;
                    switch (edgeInfoPair.Value.EdgeType)
                    {
                        case MyCubeEdgeType.Horizontal:
                            modelId = MyModel.GetId(edgesSet.Horisontal);
                            break;
                        case MyCubeEdgeType.Horizontal_Diagonal:
                            modelId = MyModel.GetId(edgesSet.HorisontalDiagonal);
                            break;
                        case MyCubeEdgeType.Vertical:
                            modelId = MyModel.GetId(edgesSet.Vertical);
                            break;
                        case MyCubeEdgeType.Vertical_Diagonal:
                            modelId = MyModel.GetId(edgesSet.VerticalDiagonal);
                            break;
                    }

                    //var modelId = resultEdgesHaveDifferentArmorType || baseHeavy ? 
                      //  m_cubeHeavyEdgeModelIds[(int)Grid.GridSizeEnum][(int)edgeInfoPair.Value.EdgeType] :
                        //m_cubeEdgeModelIds[(int)Grid.GridSizeEnum][(int)edgeInfoPair.Value.EdgeType];

                    inst.PackedOrthoMatrix = edgeInfoPair.Value.LocalOrthoMatrix;
                    AddInstancePart(instanceParts, modelId, ref inst, 0, EdgeViewDistance);
                }
            }
        }
        private void AddEdgeParts(Dictionary <ModelId, Tuple <List <MyCubeInstanceMergedData>, MyInstanceInfo> > instanceParts)
        {
            // This can be optimized in same way as cube parts are
            m_edgesToCompare.Clear();
            float reduceEpsilon = 0.1f;

            MyCubeInstanceData inst = new MyCubeInstanceData();

            inst.ResetBones();
            inst.SetTextureOffset(new Vector2(0, 0));

            foreach (var edgeInfoPair in m_edgeInfosNew)
            {
                if (edgeInfoPair.Value.Full /* || edgeInfoPair.Value.Empty*/)
                {
                    continue;
                }

                bool isVisible = false;
                m_edgesToCompare.Clear();

                //Find opposite normals and remove them
                Color        color;
                MyStringHash edgeModel;
                Base27Directions.Direction normal0, normal1;
                for (int i = 0; i < MyFourEdgeInfo.MaxInfoCount; i++)
                {
                    if (edgeInfoPair.Value.GetNormalInfo(i, out color, out edgeModel, out normal0, out normal1))
                    {
                        m_edgesToCompare.Add(new EdgeInfoNormal()
                        {
                            Normal = Base27Directions.GetVector(normal0), Color = color, EdgeModel = edgeModel
                        });
                        m_edgesToCompare.Add(new EdgeInfoNormal()
                        {
                            Normal = Base27Directions.GetVector(normal1), Color = color, EdgeModel = edgeModel
                        });
                    }
                }

                int  c             = 0;
                bool wasFour       = m_edgesToCompare.Count == 4;
                var  baseEdgeModel = m_edgesToCompare[0].EdgeModel;

                while (c < m_edgesToCompare.Count)
                {
                    bool normalsRemoved = false;
                    for (int c2 = c + 1; c2 < m_edgesToCompare.Count; c2++)
                    {
                        //opposite normals?
                        if (MyUtils.IsZero(m_edgesToCompare[c].Normal + m_edgesToCompare[c2].Normal, reduceEpsilon))
                        {
                            if (c > c2)
                            {
                                m_edgesToCompare.RemoveAt(c);
                                m_edgesToCompare.RemoveAt(c2);
                            }
                            else
                            {
                                m_edgesToCompare.RemoveAt(c2);
                                m_edgesToCompare.RemoveAt(c);
                            }

                            normalsRemoved = true;
                            break;
                        }
                    }

                    if (normalsRemoved)
                    {
                        continue;
                    }

                    c++;
                }

                Debug.Assert(m_edgesToCompare.Count != 1, "Alone edge with one normal cannot exist");

                bool resultEdgesHaveDifferentColor     = false;
                bool resultEdgesHaveDifferentArmorType = false;

                if (m_edgesToCompare.Count > 0)
                {
                    Color baseColor = m_edgesToCompare[0].Color;
                    foreach (var edge in m_edgesToCompare)
                    {
                        if (edge.Color != baseColor)
                        {
                            resultEdgesHaveDifferentColor = true;
                            break;
                        }
                    }


                    baseEdgeModel = m_edgesToCompare[0].EdgeModel;
                    foreach (var edge in m_edgesToCompare)
                    {
                        resultEdgesHaveDifferentArmorType |= baseEdgeModel != edge.EdgeModel;
                    }
                }

                if (m_edgesToCompare.Count == 1)
                {
                    isVisible = false;
                }
                else if (resultEdgesHaveDifferentColor || resultEdgesHaveDifferentArmorType)
                {
                    isVisible = true;
                }
                else
                if (m_edgesToCompare.Count > 2)
                {
                    isVisible = true;
                }
                else
                if (m_edgesToCompare.Count == 0)
                {
                    isVisible = wasFour;
                }
                else
                {
                    Debug.Assert(m_edgesToCompare.Count == 2);

                    //Check normals angle to get visibility
                    float d = Vector3.Dot(m_edgesToCompare[0].Normal, m_edgesToCompare[1].Normal);

                    Debug.Assert(d != -1, "We already removed opposite normals");

                    if (Math.Abs(d) > 0.85f)
                    {           //consider this without outline
                        isVisible = false;
                    }
                    else
                    {
                        isVisible = true;
                    }
                }

                if (isVisible)
                {
                    var definition = MyDefinitionManager.Static.GetEdgesDefinition(new MyDefinitionId(new MyObjectBuilderType(typeof(MyObjectBuilder_EdgesDefinition)), baseEdgeModel));
                    var edgesSet   = m_gridRenderComponent.GridSizeEnum == MyCubeSize.Large ? definition.Large : definition.Small;

                    int modelId = 0;
                    switch (edgeInfoPair.Value.EdgeType)
                    {
                    case MyCubeEdgeType.Horizontal:
                        modelId = MyModel.GetId(edgesSet.Horisontal);
                        break;

                    case MyCubeEdgeType.Horizontal_Diagonal:
                        modelId = MyModel.GetId(edgesSet.HorisontalDiagonal);
                        break;

                    case MyCubeEdgeType.Vertical:
                        modelId = MyModel.GetId(edgesSet.Vertical);
                        break;

                    case MyCubeEdgeType.Vertical_Diagonal:
                        modelId = MyModel.GetId(edgesSet.VerticalDiagonal);
                        break;
                    }

                    //var modelId = resultEdgesHaveDifferentArmorType || baseHeavy ?
                    //  m_cubeHeavyEdgeModelIds[(int)Grid.GridSizeEnum][(int)edgeInfoPair.Value.EdgeType] :
                    //m_cubeEdgeModelIds[(int)Grid.GridSizeEnum][(int)edgeInfoPair.Value.EdgeType];

                    inst.PackedOrthoMatrix = edgeInfoPair.Value.LocalOrthoMatrix;
                    AddInstancePart(instanceParts, modelId, ref inst, null, 0, EdgeViewDistance);
                }
            }
        }
        // TODO: this parameter won't be optional
        public void AddInstance(ModelId model, MatrixD matrix, ref MatrixD invGridWorldMatrix, Vector4 colorMaskHsv = default(Vector4), Vector3UByte[] bones = null, float gridSize = 1f)
        {
            Matrix localMatrix = (Matrix)(matrix * invGridWorldMatrix);

            MyBuilderInstanceData builderInstanceData;
            if (!m_instanceParts.TryGetValue(model, out builderInstanceData))
            {
                builderInstanceData = new MyBuilderInstanceData();
                builderInstanceData.Model = model;
                m_instanceParts.Add(model, builderInstanceData);
            }

            if (bones == null)
            {
                builderInstanceData.InstanceData.Add(new MyCubeInstanceData()
                {
                    ColorMaskHSV = new Vector4(MyToolbar.ColorMaskHSV, 0),
                    EnableSkinning = false,
                    LocalMatrix = localMatrix
                });
            }
            else
            {
                var cubeInstance = new MyCubeInstanceData()
                {
                    ColorMaskHSV = new Vector4(MyToolbar.ColorMaskHSV, 0),
                    EnableSkinning = true,
                    LocalMatrix = localMatrix,
                };

                cubeInstance.BoneRange = gridSize;

                for (int i = 0; i < 9; i++)
                {
                    cubeInstance[i] = bones[i];
                }

                builderInstanceData.InstanceData.Add(cubeInstance);
            }

            m_cubeBuilderAABB = m_cubeBuilderAABB.Include(
                new BoundingBox(new Vector3(-MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large)),
                                new Vector3(MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large))).Transform(localMatrix));
        }