/// <summary> /// Searches for blocks which will create fracture components from cached m_fracturedSlimBlocksShapes /// </summary> private void FindFractureComponentBlocks() { Debug.Assert(MyFakes.ENABLE_FRACTURE_COMPONENT); foreach (var pair in m_fracturedSlimBlocksShapes) { var slimBlock = pair.Key; var shapeList = pair.Value; if (slimBlock.FatBlock.Components.Has<MyFractureComponentBase>()) { // Block has fracture component - ignore continue; } else { int totalBreakableShapesCountForModel = slimBlock.GetTotalBreakableShapeChildrenCount(); Debug.Assert(shapeList.Count <= totalBreakableShapesCountForModel); // No removed pieces? Then ignore. if (slimBlock.BlockDefinition.CreateFracturedPieces && totalBreakableShapesCountForModel == shapeList.Count) continue; foreach (var s in shapeList) { s.SetTransform(ref Matrix.Identity); } ProfilerShort.Begin("CreateShapeComponent"); HkdBreakableShape compound = new HkdCompoundBreakableShape(null, shapeList); ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren(); var mp = new HkMassProperties(); compound.BuildMassProperties(ref mp); HkdBreakableShape shape = compound; var sh = compound.GetShape(); shape = new HkdBreakableShape(sh, ref mp); //shape.SetMassProperties(mp); //important! pass mp to constructor foreach (var si in shapeList) { var siRef = si; shape.AddShape(ref siRef); } compound.RemoveReference(); ProfilerShort.BeginNextBlock("Connect"); //shape.SetChildrenParent(shape); ConnectPiecesInBlock(shape, shapeList); MyFractureComponentBase.Info info = new MyFractureComponentBase.Info() { Entity = slimBlock.FatBlock, Shape = shape, Compound = true }; m_fractureBlockComponentsCache.Add(info); ProfilerShort.End(); } } m_fracturedSlimBlocksShapes.Clear(); }
private void FindFracturedBlocks(HkdBreakableBodyInfo b) { ProfilerShort.Begin("DBHelper"); var dbHelper = new HkdBreakableBodyHelper(b); ProfilerShort.BeginNextBlock("GetRBMatrix"); var bodyMatrix = dbHelper.GetRigidBodyMatrix(); ProfilerShort.BeginNextBlock("SearchChildren"); dbHelper.GetChildren(m_children); foreach (var child in m_children) { if (!child.IsFracturePiece()) continue; //var blockPosWorld = ClusterToWorld(Vector3.Transform(child.GetTransform().Translation, bodyMatrix)); var bShape = child.Shape; HkVec3IProperty pProp = bShape.GetProperty(HkdBreakableShape.PROPERTY_GRID_POSITION); var blockPos = pProp.Value; //Vector3I.Round(child.GetTransform().Translation / m_grid.GridSize); if (!m_grid.CubeExists(blockPos)) { //Debug.Fail("FindFracturedBlocks:Fracture piece missing block");//safe to ignore continue; } if (MyFakes.ENABLE_FRACTURE_COMPONENT) { var block = m_grid.GetCubeBlock(blockPos); if (block == null) continue; if (!FindFractureComponentBlocks(block, child)) continue; } else { if (!m_fracturedBlocksShapes.ContainsKey(blockPos)) m_fracturedBlocksShapes[blockPos] = new List<HkdShapeInstanceInfo>(); m_fracturedBlocksShapes[blockPos].Add(child); } } ProfilerShort.BeginNextBlock("CreateFreacturedBlocks"); if (MyFakes.ENABLE_FRACTURE_COMPONENT) { foreach (var pair in m_fracturedSlimBlocksShapes) { var slimBlock = pair.Key; var shapeList = pair.Value; if (slimBlock.FatBlock.Components.Has<MyFractureComponentBase>()) { // Block has fracture component - ignore continue; } else { foreach (var s in shapeList) { s.SetTransform(ref Matrix.Identity); } ProfilerShort.Begin("CreateShapeComponent"); HkdBreakableShape compound = new HkdCompoundBreakableShape(null, shapeList); ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren(); var mp = new HkMassProperties(); compound.BuildMassProperties(ref mp); HkdBreakableShape shape = compound; var sh = compound.GetShape(); shape = new HkdBreakableShape(sh, ref mp); //shape.SetMassProperties(mp); //important! pass mp to constructor foreach (var si in shapeList) { var siRef = si; shape.AddShape(ref siRef); } compound.RemoveReference(); ProfilerShort.BeginNextBlock("Connect"); //shape.SetChildrenParent(shape); ConnectPiecesInBlock(shape, shapeList); MyFractureComponentBase.Info info = new MyFractureComponentBase.Info() { Entity = slimBlock.FatBlock, Shape = shape, Compound = true }; m_fractureBlockComponentsCache.Add(info); ProfilerShort.End(); } } } else { foreach (var key in m_fracturedBlocksShapes.Keys) { HkdBreakableShape shape; var shapeList = m_fracturedBlocksShapes[key]; foreach (var s in shapeList) { var matrix = s.GetTransform(); matrix.Translation = Vector3.Zero; s.SetTransform(ref matrix); } ProfilerShort.Begin("CreateShape"); HkdBreakableShape compound = new HkdCompoundBreakableShape(null, shapeList); ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren(); var mp = new HkMassProperties(); compound.BuildMassProperties(ref mp); shape = compound; var sh = compound.GetShape(); shape = new HkdBreakableShape(sh, ref mp); //shape.SetMassProperties(mp); //important! pass mp to constructor foreach (var si in shapeList) { var siRef = si; shape.AddShape(ref siRef); } compound.RemoveReference(); ProfilerShort.BeginNextBlock("Connect"); //shape.SetChildrenParent(shape); ConnectPiecesInBlock(shape, shapeList); ProfilerShort.End(); var info = new MyFracturedBlock.Info() { Shape = shape, Position = key, Compound = true, }; var originalBlock = m_grid.GetCubeBlock(key); if (originalBlock == null) { //Debug.Fail("Missing fracture piece original block.");//safe to ignore shape.RemoveReference(); continue; } Debug.Assert(originalBlock != null); if (originalBlock.FatBlock is MyFracturedBlock) { var fractured = originalBlock.FatBlock as MyFracturedBlock; info.OriginalBlocks = fractured.OriginalBlocks; info.Orientations = fractured.Orientations; info.MultiBlocks = fractured.MultiBlocks; } else if (originalBlock.FatBlock is MyCompoundCubeBlock) { info.OriginalBlocks = new List<Definitions.MyDefinitionId>(); info.Orientations = new List<MyBlockOrientation>(); MyCompoundCubeBlock compoundBlock = originalBlock.FatBlock as MyCompoundCubeBlock; bool hasMultiBlockPart = false; var blocksInCompound = compoundBlock.GetBlocks(); foreach (var block in blocksInCompound) { info.OriginalBlocks.Add(block.BlockDefinition.Id); info.Orientations.Add(block.Orientation); hasMultiBlockPart = hasMultiBlockPart || block.IsMultiBlockPart; } if (hasMultiBlockPart) { info.MultiBlocks = new List<MyFracturedBlock.MultiBlockPartInfo>(); foreach (var block in blocksInCompound) { if (block.IsMultiBlockPart) info.MultiBlocks.Add(new MyFracturedBlock.MultiBlockPartInfo() { MultiBlockDefinition = block.MultiBlockDefinition.Id, MultiBlockId = block.MultiBlockId }); else info.MultiBlocks.Add(null); } } } else { info.OriginalBlocks = new List<Definitions.MyDefinitionId>(); info.Orientations = new List<MyBlockOrientation>(); info.OriginalBlocks.Add(originalBlock.BlockDefinition.Id); info.Orientations.Add(originalBlock.Orientation); if (originalBlock.IsMultiBlockPart) { info.MultiBlocks = new List<MyFracturedBlock.MultiBlockPartInfo>(); info.MultiBlocks.Add(new MyFracturedBlock.MultiBlockPartInfo() { MultiBlockDefinition = originalBlock.MultiBlockDefinition.Id, MultiBlockId = originalBlock.MultiBlockId }); } } m_fractureBlocksCache.Add(info); } } m_fracturedBlocksShapes.Clear(); m_children.Clear(); m_fracturedSlimBlocksShapes.Clear(); ProfilerShort.End(); }