/// <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); }
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); } }
// 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 }); }
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)); }