private static void PrepareMaterialBatches(MyRenderContext RC, List <MyScreenDecal> decals, uint sinceStartTs) { if (decals.Count == 0) { return; } List <uint> decalsToRemove = new List <uint>(); foreach (MyScreenDecal decal in decals) { var parent = MyIDTracker <MyActor> .FindByID(decal.ParentID); bool world = decal.Flags.HasFlag(MyDecalFlags.World); if (parent == null && !world) { decalsToRemove.Add(decal.ID); continue; } Matrix volumeMatrix; if (world) { volumeMatrix = decal.OBBox; Vector3D translation = decal.Data.Position - MyRender11.Environment.CameraPosition; volumeMatrix.Translation = translation; } else { MatrixD transform = decal.OBBox * parent.WorldMatrix; transform.Translation = transform.Translation - MyRender11.Environment.CameraPosition; volumeMatrix = transform; } uint fadeDiff = decal.FadeTimestamp - sinceStartTs; float fadeAlpha = decal.FadeTimestamp - sinceStartTs >= DECAL_FADE_DURATION ? 1 : fadeDiff / (float)DECAL_FADE_DURATION; m_jobs.Add(new MyDecalJob() { WorldMatrix = volumeMatrix, FadeAlpha = fadeAlpha }); if (MyRenderProxy.Settings.DebugDrawDecals) { MatrixD worldMatrix; if (parent == null) { worldMatrix = decal.OBBox; worldMatrix.Translation = decal.Data.Position; } else { worldMatrix = decal.OBBox * parent.WorldMatrix; } MyRenderProxy.DebugDrawAxis(worldMatrix, 0.2f, false, true); MyRenderProxy.DebugDrawOBB(worldMatrix, Color.Blue, 0.1f, false, false); Vector3 position = worldMatrix.Translation; MyRenderProxy.DebugDrawText3D(position, decal.SourceTarget, Color.White, 1, false); } } foreach (uint id in decalsToRemove) { DecalNode node = m_nodeMap[id]; RemoveDecalByNode(node); } }
public override bool DebugDraw() { if (MyDebugDrawSettings.DEBUG_DRAW_FIXED_BLOCK_QUERIES) { foreach (var b in m_cubeGrid.GetBlocks()) { var geometryBox = b.FatBlock.GetGeometryLocalBox(); //geometryBox.Inflate(0.5f); Vector3 halfExtents = geometryBox.Size / 2; Vector3D pos; b.ComputeScaledCenter(out pos); pos += geometryBox.Center; pos = Vector3D.Transform(pos, m_cubeGrid.WorldMatrix); Matrix blockMatrix; b.Orientation.GetMatrix(out blockMatrix); var q = Quaternion.CreateFromRotationMatrix(blockMatrix * m_cubeGrid.WorldMatrix.GetOrientation()); Sandbox.Engine.Physics.MyPhysics.GetPenetrationsBox(ref halfExtents, ref pos, ref q, m_penetrations, Sandbox.Engine.Physics.MyPhysics.CollideWithStaticLayer); bool isStatic = false; foreach (var p in m_penetrations) { var e = p.GetCollisionEntity(); if (e != null && e is MyVoxelMap) { isStatic = true; break; } } m_penetrations.Clear(); MyOrientedBoundingBoxD obb = new MyOrientedBoundingBoxD(pos, halfExtents, q); MyRenderProxy.DebugDrawOBB(obb, isStatic ? Color.Green : Color.Red, 0.1f, false, false); } } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_NAMES || MyDebugDrawSettings.DEBUG_DRAW_GRID_CONTROL) { string text = ""; var color = Color.White; if (MyDebugDrawSettings.DEBUG_DRAW_GRID_NAMES) { text += m_cubeGrid.ToString() + " "; } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_CONTROL) { var controllingPlayer = Sync.Players.GetControllingPlayer(m_cubeGrid); if (controllingPlayer != null) { text += "Controlled by: " + controllingPlayer.DisplayName; color = Color.LightGreen; } } MyRenderProxy.DebugDrawText3D(m_cubeGrid.PositionComp.WorldAABB.Center, text, color, 0.7f, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); } MyRenderComponentCubeGrid gridRender = m_cubeGrid.Render; if (MyDebugDrawSettings.DEBUG_DRAW_BLOCK_GROUPS) { var tpos = m_cubeGrid.PositionComp.WorldMatrix.Translation; foreach (var group in m_cubeGrid.BlockGroups) { MyRenderProxy.DebugDrawText3D(tpos, group.Name.ToString(), Color.Red, 1, false); tpos += m_cubeGrid.PositionComp.WorldMatrix.Right * group.Name.Length * 0.1f; } } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_DIRTY_BLOCKS) { foreach (var b in m_dirtyBlocks) { var color = m_cubeGrid.GetCubeBlock(b.Key) != null?Color.Red.ToVector3() : Color.Yellow.ToVector3(); var m = Matrix.CreateScale(m_cubeGrid.GridSize) * Matrix.CreateTranslation(b.Key * m_cubeGrid.GridSize) * m_cubeGrid.WorldMatrix; MyRenderProxy.DebugDrawOBB(m, color, 0.15f, false, true); } } // Bone debug draw if (MyDebugDrawSettings.DEBUG_DRAW_DISPLACED_BONES) { Vector3 cameraPos = (Vector3)MySector.MainCamera.Position; foreach (var bone in m_cubeGrid.Skeleton.Bones) { var bonePos = (bone.Key / (float)m_cubeGrid.Skeleton.BoneDensity) * gridRender.GridSize + bone.Value; bonePos -= new Vector3(gridRender.GridSize / m_cubeGrid.Skeleton.BoneDensity); Vector3 pos = Vector3.Transform(bonePos, (Matrix)m_cubeGrid.PositionComp.WorldMatrix); MyRenderProxy.DebugDrawSphere(pos, 0.05f, Color.Red.ToVector3(), 0.5f, false, true); if ((cameraPos - pos).LengthSquared() < 200.0f) { MyRenderProxy.DebugDrawText3D(pos, bone.Key.ToString(), Color.Red, 0.4f, false); } } } if (MyDebugDrawSettings.DEBUG_DRAW_STRUCTURAL_INTEGRITY && m_cubeGrid.StructuralIntegrity != null) { m_cubeGrid.StructuralIntegrity.DebugDraw(); } if (MyDebugDrawSettings.DEBUG_DRAW_CUBES) { foreach (var cubeBlock in m_cubeGrid.CubeBlocks) { var cb = cubeBlock.FatBlock; if (cb == null) { continue; } cb.DebugDraw(); } } m_cubeGrid.GridSystems.DebugDraw(); if (MyDebugDrawSettings.DEBUG_DRAW_GRID_TERMINAL_SYSTEMS) { /* if (grid.OnBlockAdded != null) * { * MyRenderProxy.DebugDrawText3D(Entity.PositionComp.WorldMatrix.Translation + new Vector3(0.0f, 0.0f, 0.5f), grid.OnBlockAdded.GetInvocationList().Count().ToString(), Color.NavajoWhite, 1.0f, false); * }*/ } if (MyFakes.ENABLE_TRASH_REMOVAL && MyDebugDrawSettings.DEBUG_DRAW_TRASH_REMOVAL) { Color color = m_cubeGrid.IsTrash() ? Color.Red : Color.Green; float sphereRadius = m_cubeGrid.PositionComp.LocalAABB.HalfExtents.AbsMax(); MyRenderProxy.DebugDrawSphere(m_cubeGrid.Physics != null ? m_cubeGrid.Physics.CenterOfMassWorld : m_cubeGrid.PositionComp.WorldMatrix.Translation, sphereRadius, color, 1.0f, false); } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_ORIGINS) { MyRenderProxy.DebugDrawAxis(m_cubeGrid.PositionComp.WorldMatrix, 1.0f, false); } if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_ALL) { foreach (MySlimBlock block in m_cubeGrid.GetBlocks()) { if ((m_cubeGrid.GridIntegerToWorld(block.Position) - MySector.MainCamera.Position).LengthSquared() < 200) { DebugDrawMountPoints(block); } } } if (MyDebugDrawSettings.DEBUG_DRAW_BLOCK_INTEGRITY) { if (MySector.MainCamera != null && (MySector.MainCamera.Position - m_cubeGrid.PositionComp.WorldVolume.Center).Length() < 16 + m_cubeGrid.PositionComp.WorldVolume.Radius) { foreach (var cubeBlock in m_cubeGrid.CubeBlocks) { var pos = m_cubeGrid.GridIntegerToWorld(cubeBlock.Position); if (m_cubeGrid.GridSizeEnum == MyCubeSize.Large || (MySector.MainCamera != null && (MySector.MainCamera.Position - pos).LengthSquared() < 9)) { float integrity = 0; if (cubeBlock.FatBlock is MyCompoundCubeBlock) { foreach (var b in (cubeBlock.FatBlock as MyCompoundCubeBlock).GetBlocks()) { integrity += b.Integrity; } } else { integrity = cubeBlock.Integrity; } MyRenderProxy.DebugDrawText3D(m_cubeGrid.GridIntegerToWorld(cubeBlock.Position), ((int)integrity).ToString(), Color.White, m_cubeGrid.GridSizeEnum == MyCubeSize.Large ? 0.65f : 0.5f, false); } } } } return(base.DebugDraw()); }
public override void Draw() { base.Draw(); if (MyTrashRemoval.PreviewEnabled && MySession.Static.HasCreativeRights) { DrawTrashAdminView(); } bool visible = false; for (int i = 0; i < RenderObjectIDs.Length; i++) { if (RenderObjectIDs[i] == MyRenderProxy.RENDER_ID_UNASSIGNED) { break; } if (MyRenderProxy.VisibleObjectsRead.Contains(this.RenderObjectIDs[i])) { visible = true; break; } } if (visible) { foreach (var block in m_grid.BlocksForDraw) { if (MyRenderProxy.VisibleObjectsRead.Contains(block.Render.RenderObjectIDs[0])) { block.Render.Draw(); } } } if (MyCubeGrid.ShowCenterOfMass && !IsStatic && Container.Entity.Physics != null && Container.Entity.Physics.HasRigidBody) { var matrix = Container.Entity.Physics.GetWorldMatrix(); var center = Container.Entity.Physics.CenterOfMassWorld; var cam = MySector.MainCamera.Position; var dist = Vector3.Distance(cam, center); bool draw = false; if (dist < 30) { draw = true; } else if (dist < 200) { draw = true; MyPhysics.CastRay(cam, center, m_tmpHitList, MyPhysics.CollisionLayers.DynamicDoubledCollisionLayer); foreach (var hit in m_tmpHitList) { if (hit.HkHitInfo.GetHitEntity() != this) { draw = false; break; } } m_tmpHitList.Clear(); } if (draw) { float size = MathHelper.Lerp(1, 9, dist / 200); var mat = "WeaponLaserIgnoreDepth"; var color = Color.Yellow.ToVector4(); var thickness = 0.02f * size; MySimpleObjectDraw.DrawLine(center - matrix.Up * 0.5f * size, center + matrix.Up * 0.5f * size, mat, ref color, thickness); MySimpleObjectDraw.DrawLine(center - matrix.Forward * 0.5f * size, center + matrix.Forward * 0.5f * size, mat, ref color, thickness); MySimpleObjectDraw.DrawLine(center - matrix.Right * 0.5f * size, center + matrix.Right * 0.5f * size, mat, ref color, thickness); MyTransparentGeometry.AddBillboardOriented("RedDotIgnoreDepth", Color.White.ToVector4(), center, MySector.MainCamera.LeftVector, MySector.MainCamera.UpVector, 0.1f * size); } } if (MyCubeGrid.ShowGridPivot) { var matrix = Container.Entity.WorldMatrix; var pos = matrix.Translation; var cam = MySector.MainCamera.Position; var dist = Vector3.Distance(cam, pos); bool draw = false; if (dist < 30) { draw = true; } else if (dist < 200) { draw = true; MyPhysics.CastRay(cam, pos, m_tmpHitList, MyPhysics.CollisionLayers.DynamicDoubledCollisionLayer); foreach (var hit in m_tmpHitList) { if (hit.HkHitInfo.GetHitEntity() != this) { draw = false; break; } } m_tmpHitList.Clear(); } if (draw) { float size = MathHelper.Lerp(1, 9, dist / 200); var mat = "WeaponLaserIgnoreDepth"; var thickness = 0.02f * size; var color = Color.Green.ToVector4(); MySimpleObjectDraw.DrawLine(pos, pos + matrix.Up * 0.5f * size, mat, ref color, thickness); color = Color.Blue.ToVector4(); MySimpleObjectDraw.DrawLine(pos, pos + matrix.Forward * 0.5f * size, mat, ref color, thickness); color = Color.Red.ToVector4(); MySimpleObjectDraw.DrawLine(pos, pos + matrix.Right * 0.5f * size, mat, ref color, thickness); MyTransparentGeometry.AddBillboardOriented("RedDotIgnoreDepth", Color.White.ToVector4(), pos, MySector.MainCamera.LeftVector, MySector.MainCamera.UpVector, 0.1f * size); MyRenderProxy.DebugDrawAxis(matrix, 0.5f, false);//DX 11 desnt support depthRead false } } if (MyCubeGrid.ShowStructuralIntegrity) { if (m_grid.StructuralIntegrity == null) { if (MyFakes.ENABLE_STRUCTURAL_INTEGRITY) { m_grid.CreateStructuralIntegrity(); if (m_grid.StructuralIntegrity != null) { m_grid.StructuralIntegrity.EnabledOnlyForDraw = true; } } } else { m_grid.StructuralIntegrity.Draw(); } } else if (m_grid.StructuralIntegrity != null && m_grid.StructuralIntegrity.EnabledOnlyForDraw) { m_grid.CloseStructuralIntegrity(); } if (MyFakes.ENABLE_ATMOSPHERIC_ENTRYEFFECT) { ProfilerShort.Begin("DrawAtmosphericEntryEffect"); DrawAtmosphericEntryEffect(); ProfilerShort.End(); } }
/// <summary> /// Update shown position of the weapon. /// </summary> private void UpdateGraphicalWeaponPosition() { var animController = Character.AnimationController; MyHandItemDefinition handItemDefinition = Character.HandItemDefinition; if (handItemDefinition == null || Character.CurrentWeapon == null || animController.CharacterBones == null) { return; } // --------- // gather useful variables bool isLocallyControlled = Character.ControllerInfo.IsLocallyControlled(); bool isInFirstPerson = (Character.IsInFirstPersonView || Character.ForceFirstPersonCamera) && isLocallyControlled; var jetpack = Character.JetpackComp; bool flying = jetpack != null && jetpack.Running; if (m_lastStateWasFalling && flying) { m_currentAnimationToIkTime = m_animationToIKDelay * (float)Math.Cos(Character.HeadLocalXAngle - m_lastLocalRotX); } if (m_lastStateWasCrouching != Character.IsCrouching) { m_suppressBouncingForTimeSec = m_suppressBouncingDelay; } if (m_suppressBouncingForTimeSec > 0) { m_spineRestPositionX.Clear(); m_spineRestPositionY.Clear(); m_spineRestPositionZ.Clear(); } m_lastLocalRotX = Character.HeadLocalXAngle; // get head matrix MatrixD weaponMatrixPositioned = Character.GetHeadMatrix(false, !flying, false, true, preferLocalOverSync: true) * Character.PositionComp.WorldMatrixInvScaled; if (!isInFirstPerson && animController.CharacterBones.IsValidIndex(Character.HeadBoneIndex)) { // apply feet ik (head bone is stabilized) weaponMatrixPositioned.M42 += animController.CharacterBonesSorted[0].Translation.Y; } // --------- // mix positioning matrices (variants: stand/walk/shoot/ironsight), all in character local space // standing (IK) MatrixD standingMatrix = isInFirstPerson ? handItemDefinition.ItemLocation : handItemDefinition.ItemLocation3rd; // walking (IK) MatrixD walkingMatrix = isInFirstPerson ? handItemDefinition.ItemWalkingLocation : handItemDefinition.ItemWalkingLocation3rd; // shooting (IK) MatrixD shootingMatrix = isInFirstPerson ? handItemDefinition.ItemShootLocation : handItemDefinition.ItemShootLocation3rd; // ironsight (IK) MatrixD ironsightMatrix = handItemDefinition.ItemIronsightLocation; // animation pose MatrixD weaponAnimMatrix = animController.CharacterBones.IsValidIndex(Character.WeaponBone) ? GetWeaponRelativeMatrix() * animController.CharacterBones[Character.WeaponBone].AbsoluteTransform : GetWeaponRelativeMatrix(); ironsightMatrix.Translation = m_weaponIronsightTranslation; if (Character.CurrentWeapon is MyEngineerToolBase) { ironsightMatrix.Translation = m_toolIronsightTranslation; } // get weights of all state variants Vector4D variantWeights = UpdateAndGetWeaponVariantWeights(handItemDefinition); // interpolate matrices to get the resulting one MatrixD weaponMatrixLocal = variantWeights.X * standingMatrix + variantWeights.Y * walkingMatrix + variantWeights.Z * shootingMatrix + variantWeights.W * ironsightMatrix; weaponMatrixLocal = MatrixD.Normalize(weaponMatrixLocal); // weapon positioning - IK weight double weaponDataPosWeight = 0; if (handItemDefinition.ItemPositioning == MyItemPositioningEnum.TransformFromData && isInFirstPerson || handItemDefinition.ItemPositioning3rd == MyItemPositioningEnum.TransformFromData && !isInFirstPerson) { weaponDataPosWeight += variantWeights.X; } if (handItemDefinition.ItemPositioningWalk == MyItemPositioningEnum.TransformFromData && isInFirstPerson || handItemDefinition.ItemPositioningWalk3rd == MyItemPositioningEnum.TransformFromData && !isInFirstPerson) { weaponDataPosWeight += variantWeights.Y; } if (handItemDefinition.ItemPositioningShoot == MyItemPositioningEnum.TransformFromData && isInFirstPerson || handItemDefinition.ItemPositioningShoot3rd == MyItemPositioningEnum.TransformFromData && !isInFirstPerson) { weaponDataPosWeight += variantWeights.Z; } weaponDataPosWeight += variantWeights.W; weaponDataPosWeight /= variantWeights.X + variantWeights.Y + variantWeights.Z + variantWeights.W; // now computing hand IK weight double armsIkWeight = 0; if (handItemDefinition.ItemPositioning != MyItemPositioningEnum.TransformFromAnim && isInFirstPerson || handItemDefinition.ItemPositioning3rd != MyItemPositioningEnum.TransformFromAnim && !isInFirstPerson) { armsIkWeight += variantWeights.X; } if (handItemDefinition.ItemPositioningWalk != MyItemPositioningEnum.TransformFromAnim && isInFirstPerson || handItemDefinition.ItemPositioningWalk3rd != MyItemPositioningEnum.TransformFromAnim && !isInFirstPerson) { armsIkWeight += variantWeights.Y; } if (handItemDefinition.ItemPositioningShoot != MyItemPositioningEnum.TransformFromAnim && isInFirstPerson || handItemDefinition.ItemPositioningShoot3rd != MyItemPositioningEnum.TransformFromAnim && !isInFirstPerson) { armsIkWeight += variantWeights.Z; } armsIkWeight /= variantWeights.X + variantWeights.Y + variantWeights.Z + variantWeights.W; ApplyWeaponBouncing(handItemDefinition, ref weaponMatrixLocal, (float)(1.0 - 0.95 * variantWeights.W)); // apply head transform on top of it if (!isInFirstPerson) { weaponMatrixPositioned.M43 += 0.5 * weaponMatrixLocal.M43 * Math.Max(0, weaponMatrixPositioned.M32); // offset not to interfere with body weaponMatrixPositioned.M42 += 0.5 * weaponMatrixLocal.M42 * Math.Max(0, weaponMatrixPositioned.M32); // offset not to interfere with body } MatrixD weaponMatrixPositionedLocal = weaponMatrixLocal * weaponMatrixPositioned; // displace sensor (maybe move to logical part? does not seem to be used at all) var characterWeaponEngToolBase = Character.CurrentWeapon as MyEngineerToolBase; if (characterWeaponEngToolBase != null) { characterWeaponEngToolBase.SensorDisplacement = -weaponMatrixLocal.Translation; } // mix plain animation with (anim+ik) result - for example, medieval uses plain animations double ikRatio = weaponDataPosWeight * m_currentAnimationToIkTime / m_animationToIKDelay; MatrixD weaponFinalWorld = MatrixD.Lerp(weaponAnimMatrix, weaponMatrixPositionedLocal, ikRatio) * Character.WorldMatrix; // propagate result to fields GraphicalPositionWorld = weaponFinalWorld.Translation; ArmsIkWeight = (float)armsIkWeight; ((MyEntity)Character.CurrentWeapon).WorldMatrix = weaponFinalWorld; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW) { MyRenderProxy.DebugDrawAxis(weaponFinalWorld, 0.5f, false); } }
public override void DebugDraw() { MatrixD worldMatrix; Vector3D vectord4; if (MyDebugDrawSettings.DEBUG_DRAW_GRID_AABB) { MatrixD worldMatrix = this.m_cubeGrid.PositionComp.WorldMatrix; MyRenderProxy.DebugDrawOBB(new MyOrientedBoundingBoxD(this.m_cubeGrid.PositionComp.LocalAABB, worldMatrix), Color.Yellow, 0.2f, false, true, false); MyRenderProxy.DebugDrawAxis(worldMatrix, 1f, false, false, false); } if (MyDebugDrawSettings.DEBUG_DRAW_FIXED_BLOCK_QUERIES) { foreach (MySlimBlock local1 in this.m_cubeGrid.GetBlocks()) { Vector3D vectord; Matrix matrix; BoundingBox geometryLocalBox = local1.FatBlock.GetGeometryLocalBox(); Vector3 halfExtents = geometryLocalBox.Size / 2f; local1.ComputeScaledCenter(out vectord); vectord = Vector3D.Transform(vectord + geometryLocalBox.Center, this.m_cubeGrid.WorldMatrix); local1.Orientation.GetMatrix(out matrix); worldMatrix = this.m_cubeGrid.WorldMatrix; Quaternion rotation = Quaternion.CreateFromRotationMatrix((MatrixD)(matrix * worldMatrix.GetOrientation())); MyPhysics.GetPenetrationsBox(ref halfExtents, ref vectord, ref rotation, this.m_penetrations, 14); bool flag = false; using (List <HkBodyCollision> .Enumerator enumerator2 = this.m_penetrations.GetEnumerator()) { while (enumerator2.MoveNext()) { IMyEntity collisionEntity = enumerator2.Current.GetCollisionEntity(); if ((collisionEntity != null) && (collisionEntity is MyVoxelMap)) { flag = true; break; } } } this.m_penetrations.Clear(); MyRenderProxy.DebugDrawOBB(new MyOrientedBoundingBoxD(vectord, halfExtents, rotation), flag ? Color.Green : Color.Red, 0.1f, false, false, false); } } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_NAMES || MyDebugDrawSettings.DEBUG_DRAW_GRID_CONTROL) { string text = ""; Color white = Color.White; if (MyDebugDrawSettings.DEBUG_DRAW_GRID_NAMES) { text = text + this.m_cubeGrid.ToString() + " "; } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_CONTROL) { MyPlayer controllingPlayer = Sync.Players.GetControllingPlayer(this.m_cubeGrid); if (controllingPlayer != null) { text = text + "Controlled by: " + controllingPlayer.DisplayName; white = Color.LightGreen; } } MyRenderProxy.DebugDrawText3D(this.m_cubeGrid.PositionComp.WorldAABB.Center, text, white, 0.7f, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, -1, false); } MyRenderComponentCubeGrid render = this.m_cubeGrid.Render; if (MyDebugDrawSettings.DEBUG_DRAW_BLOCK_GROUPS) { worldMatrix = this.m_cubeGrid.PositionComp.WorldMatrix; Vector3D translation = worldMatrix.Translation; foreach (MyBlockGroup group in this.m_cubeGrid.BlockGroups) { MyRenderProxy.DebugDrawText3D(translation, group.Name.ToString(), Color.Red, 1f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); worldMatrix = this.m_cubeGrid.PositionComp.WorldMatrix; translation += (worldMatrix.Right * group.Name.Length) * 0.10000000149011612; } } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_DIRTY_BLOCKS) { foreach (KeyValuePair <Vector3I, MyTimeSpan> pair in this.m_dirtyBlocks) { Vector3 vector1; if (this.m_cubeGrid.GetCubeBlock(pair.Key) == null) { vector1 = Color.Yellow.ToVector3(); } else { vector1 = Color.Red.ToVector3(); } Vector3 color = vector1; MyRenderProxy.DebugDrawOBB((Matrix.CreateScale(this.m_cubeGrid.GridSize) * Matrix.CreateTranslation(pair.Key * this.m_cubeGrid.GridSize)) * this.m_cubeGrid.WorldMatrix, color, 0.15f, false, true, true, false); } } if (MyDebugDrawSettings.DEBUG_DRAW_DISPLACED_BONES) { Vector3D position = MySector.MainCamera.Position; foreach (MySlimBlock block in this.m_cubeGrid.CubeBlocks) { MyCube cube; if (this.m_cubeGrid.TryGetCube(block.Position, out cube)) { int num = 0; foreach (MyCubePart part in cube.Parts) { if ((part.Model.BoneMapping != null) && (num == MyPetaInputComponent.DEBUG_INDEX)) { for (int i = 0; i < Math.Min(part.Model.BoneMapping.Length, 9); i++) { Matrix orientation = part.InstanceData.LocalMatrix.GetOrientation(); Vector3I vectori = Vector3I.Round(Vector3.Transform((Vector3)(((part.Model.BoneMapping[i] * 1f) - Vector3.One) * 1f), orientation)); Vector3I bonePos = Vector3I.Round(Vector3.Transform((Vector3)(((part.Model.BoneMapping[i] * 1f) - Vector3.One) * 1f), orientation) + Vector3.One); Vector3 bone = this.m_cubeGrid.Skeleton.GetBone(block.Position, bonePos); Vector3D vectord3 = Vector3D.TransformNormal(bone, this.m_cubeGrid.PositionComp.WorldMatrix); Vector3D vectord6 = Vector3D.Transform((Vector3)(this.m_cubeGrid.GridSize * (block.Position + (vectori / 2f))), this.m_cubeGrid.PositionComp.WorldMatrix); MyRenderProxy.DebugDrawSphere(vectord6, 0.025f, Color.Green, 0.5f, false, true, true, false); MyRenderProxy.DebugDrawText3D(vectord6, i.ToString(), Color.Green, 0.5f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); Color?colorTo = null; MyRenderProxy.DebugDrawArrow3D(vectord6, vectord6 + vectord3, Color.Red, colorTo, false, 0.1, null, 0.5f, false); } } num++; } } } } if (MyDebugDrawSettings.DEBUG_DRAW_STRUCTURAL_INTEGRITY && (this.m_cubeGrid.StructuralIntegrity != null)) { this.m_cubeGrid.StructuralIntegrity.DebugDraw(); } if (MyDebugDrawSettings.DEBUG_DRAW_CUBES) { foreach (MySlimBlock local2 in this.m_cubeGrid.CubeBlocks) { Matrix matrix4; local2.GetLocalMatrix(out matrix4); MyRenderProxy.DebugDrawAxis(matrix4 * this.m_cubeGrid.WorldMatrix, 1f, false, false, false); MyCubeBlock fatBlock = local2.FatBlock; if (fatBlock != null) { fatBlock.DebugDraw(); } } } this.m_cubeGrid.GridSystems.DebugDraw(); bool flag1 = MyDebugDrawSettings.DEBUG_DRAW_GRID_TERMINAL_SYSTEMS; if (MyDebugDrawSettings.DEBUG_DRAW_GRID_ORIGINS) { MyRenderProxy.DebugDrawAxis(this.m_cubeGrid.PositionComp.WorldMatrix, 1f, false, false, false); } if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_ALL) { foreach (MySlimBlock block3 in this.m_cubeGrid.GetBlocks()) { vectord4 = this.m_cubeGrid.GridIntegerToWorld(block3.Position) - MySector.MainCamera.Position; if (vectord4.LengthSquared() < 200.0) { this.DebugDrawMountPoints(block3); } } } if (MyDebugDrawSettings.DEBUG_DRAW_BLOCK_INTEGRITY && (MySector.MainCamera != null)) { vectord4 = MySector.MainCamera.Position - this.m_cubeGrid.PositionComp.WorldVolume.Center; if (vectord4.Length() < (16.0 + this.m_cubeGrid.PositionComp.WorldVolume.Radius)) { using (HashSet <MySlimBlock> .Enumerator enumerator = this.m_cubeGrid.CubeBlocks.GetEnumerator()) { MySlimBlock current; float num4; goto TR_0011; TR_0002: MyRenderProxy.DebugDrawText3D(this.m_cubeGrid.GridIntegerToWorld(current.Position), ((int)num4).ToString(), Color.White, (this.m_cubeGrid.GridSizeEnum == MyCubeSize.Large) ? 0.65f : 0.5f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); TR_0011: while (true) { if (!enumerator.MoveNext()) { break; } current = enumerator.Current; Vector3D vectord5 = this.m_cubeGrid.GridIntegerToWorld(current.Position); if (this.m_cubeGrid.GridSizeEnum != MyCubeSize.Large) { if (MySector.MainCamera == null) { continue; } if ((MySector.MainCamera.Position - vectord5).LengthSquared() >= 9.0) { continue; } } num4 = 0f; if (current.FatBlock is MyCompoundCubeBlock) { foreach (MySlimBlock block5 in (current.FatBlock as MyCompoundCubeBlock).GetBlocks()) { num4 += block5.Integrity * block5.BlockDefinition.MaxIntegrityRatio; } } else { num4 = current.Integrity * current.BlockDefinition.MaxIntegrityRatio; } goto TR_0002; } } } } base.DebugDraw(); }
public override void DebugDraw() { var minCorner = m_voxelMap.PositionLeftBottomCorner; if (MyDebugDrawSettings.DEBUG_DRAW_VOXEL_MAP_AABB) { MyRenderProxy.DebugDrawAABB(m_voxelMap.PositionComp.WorldAABB, Color.White, alpha: 0.2f); MyRenderProxy.DebugDrawLine3D(minCorner, minCorner + new Vector3(1f, 0f, 0f), Color.Red, Color.Red, true); MyRenderProxy.DebugDrawLine3D(minCorner, minCorner + new Vector3(0f, 1f, 0f), Color.Green, Color.Green, true); MyRenderProxy.DebugDrawLine3D(minCorner, minCorner + new Vector3(0f, 0f, 1f), Color.Blue, Color.Blue, true); MyRenderProxy.DebugDrawAxis(m_voxelMap.PositionComp.WorldMatrix, 2f, false); MyRenderProxy.DebugDrawSphere(m_voxelMap.PositionComp.GetPosition(), 1, Color.OrangeRed, 1, false); } m_voxelMap.Storage.DebugDraw(m_voxelMap, MyDebugDrawSettings.DEBUG_DRAW_VOXELS_MODE); if (m_voxelMap.Physics != null) { m_voxelMap.Physics.DebugDraw(); } //if (MyDebugDrawSettings.DEBUG_DRAW_VOXEL_GEOMETRY_CELL) //{ // LineD worldLine; // if (false) // { // var entityMatrix = MySession.Static.ControlledEntity.Entity.WorldMatrix; // worldLine = new LineD(entityMatrix.Translation, entityMatrix.Translation + 25f * entityMatrix.Forward); // } // else // { // var camera = MySector.MainCamera; // worldLine = new LineD(camera.Position, camera.Position + 25f * camera.ForwardVector); // } // VRage.Game.Models.MyIntersectionResultLineTriangleEx? result; // bool depthRead = true; // if (m_voxelMap.GetIntersectionWithLine(ref worldLine, out result)) // { // var t = result.Value.Triangle.InputTriangle; // MyRenderProxy.DebugDrawTriangle( // t.Vertex0 + minCorner, // t.Vertex1 + minCorner, // t.Vertex2 + minCorner, // Color.Red, true, false); // Vector3I cellCoord, voxelCoord; // var worldPosition = result.Value.IntersectionPointInWorldSpace; // BoundingBoxD voxelAabb; // MyVoxelCoordSystems.WorldPositionToVoxelCoord(minCorner, ref worldPosition, out voxelCoord); // MyVoxelCoordSystems.VoxelCoordToWorldAABB(minCorner, ref voxelCoord, out voxelAabb); // MyRenderProxy.DebugDrawAABB(voxelAabb, Vector3.UnitY, 1f, 1f, true); // MyVoxelCoordSystems.WorldPositionToGeometryCellCoord(minCorner, ref worldPosition, out cellCoord); // MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(minCorner, ref cellCoord, out voxelAabb); // MyRenderProxy.DebugDrawAABB(voxelAabb, Vector3.UnitZ, 1f, 1f, true); // bool isEmpty; // MyIsoMesh cell; // if (m_voxelMap.Storage.Geometry.TryGetMesh(new MyCellCoord(0, cellCoord), out isEmpty, out cell) && !isEmpty) // { // MyVoxelVertex tmp; // var triangleBatch = MyRenderProxy.PrepareDebugDrawTriangles(); // for (int i = 0; i < cell.VerticesCount; ++i) // { // cell.GetUnpackedVertex(i, out tmp); // triangleBatch.AddVertex(tmp.Position); // tmp.Position += minCorner; // MyRenderProxy.DebugDrawLine3D(tmp.Position, tmp.Position + tmp.Normal * MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF, Color.Gray, Color.White, depthRead); // } // for (int i = 0; i < cell.TrianglesCount; ++i) // { // triangleBatch.AddIndex(cell.Triangles[i].VertexIndex2); // triangleBatch.AddIndex(cell.Triangles[i].VertexIndex1); // triangleBatch.AddIndex(cell.Triangles[i].VertexIndex0); // } // MyRenderProxy.DebugDrawTriangles(triangleBatch, Matrix.CreateTranslation(minCorner), Color.CornflowerBlue, depthRead, false); // } // } //} }
public static void DebugDrawClusters() { if (Clusters == null) { return; } double previewScale = 2000; MatrixD previewMatrix = MatrixD.CreateWorld(DebugDrawClustersMatrix.Translation + previewScale * DebugDrawClustersMatrix.Forward, Vector3D.Forward, Vector3D.Up); m_resultWorlds.Clear(); Clusters.GetAll(m_resultWorlds); BoundingBoxD totalBox = BoundingBoxD.CreateInvalid(); foreach (var res in m_resultWorlds) { totalBox = totalBox.Include(res.AABB); } double maxAxis = totalBox.Size.AbsMax(); //double scaleAxis = 0.057142857142857141; double scaleAxis = previewScale / maxAxis; //Vector3D scale = new Vector3D(totalBox.Size.X * scaleAxis, totalBox.Size.Y * scaleAxis, totalBox.Size.Z * scaleAxis); Vector3D center = totalBox.Center; totalBox.Min -= center; totalBox.Max -= center; { BoundingBoxD scaledBox = new BoundingBoxD(totalBox.Min * scaleAxis * 1.02f, totalBox.Max * scaleAxis * 1.02f); MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix); MyRenderProxy.DebugDrawOBB(oriented, Vector3.Up, 1, false, false); MyRenderProxy.DebugDrawAxis(previewMatrix, 50, false); if (MySession.Static != null) { foreach (var player in Sandbox.Game.Multiplayer.Sync.Players.GetOnlinePlayers()) { if (player.Character != null) { var playerPos = Vector3D.Transform((player.Character.PositionComp.GetPosition() - center) * scaleAxis, previewMatrix); MyRenderProxy.DebugDrawSphere(playerPos, 10, Vector3.One, 1, false); } } } } Clusters.GetAllStaticObjects(m_clusterStaticObjects); foreach (var staticBB in m_clusterStaticObjects) { BoundingBoxD scaledBox = new BoundingBoxD((staticBB.Min - center) * scaleAxis, (staticBB.Max - center) * scaleAxis); MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix); MyRenderProxy.DebugDrawOBB(oriented, Color.Blue, 1, false, false); } foreach (var res in m_resultWorlds) { BoundingBoxD scaledBox = new BoundingBoxD((res.AABB.Min - center) * scaleAxis, (res.AABB.Max - center) * scaleAxis); MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix); MyRenderProxy.DebugDrawOBB(oriented, Vector3.One, 1, false, false); foreach (var rb in ((HkWorld)res.UserData).CharacterRigidBodies) { Vector3D rbCenter = res.AABB.Center + rb.Position; rbCenter = (rbCenter - center) * scaleAxis; rbCenter = Vector3D.Transform(rbCenter, previewMatrix); Vector3D velocity = rb.LinearVelocity; velocity = Vector3D.TransformNormal(velocity, previewMatrix) * 10; MyRenderProxy.DebugDrawLine3D(rbCenter, rbCenter + velocity, Color.Blue, Color.White, false); } foreach (var rb in ((HkWorld)res.UserData).RigidBodies) { MyOrientedBoundingBoxD rbbb = new MyOrientedBoundingBoxD((BoundingBoxD)rb.GetEntity().LocalAABB, rb.GetEntity().WorldMatrix); rbbb.Center = (rbbb.Center - center) * scaleAxis; rbbb.HalfExtent *= scaleAxis; rbbb.Transform(previewMatrix); MyRenderProxy.DebugDrawOBB(rbbb, Color.Yellow, 1, false, false); //BoundingBoxD rbaa = rb.GetEntity().WorldAABB; //rbaa.Min = (rbaa.Min - center) * scaleAxis; //rbaa.Max = (rbaa.Max - center) * scaleAxis; //MyRenderProxy.DebugDrawAABB(rbaa, new Vector3(0.8f, 0.8f, 0.8f), 1, 1, false); Vector3D velocity = rb.LinearVelocity; velocity = Vector3D.TransformNormal(velocity, previewMatrix) * 10; MyRenderProxy.DebugDrawLine3D(rbbb.Center, rbbb.Center + velocity, Color.Red, Color.White, false); if (velocity.Length() > 1) { BoundingBoxD ideal = new BoundingBoxD(rb.GetEntity().WorldAABB.Center - MyHavokCluster.IdealClusterSize / 2, rb.GetEntity().WorldAABB.Center + MyHavokCluster.IdealClusterSize / 2); MyOrientedBoundingBoxD idealObb = new MyOrientedBoundingBoxD(ideal, MatrixD.Identity); idealObb.Center = (ideal.Center - center) * scaleAxis; idealObb.HalfExtent *= scaleAxis; idealObb.Transform(previewMatrix); MyRenderProxy.DebugDrawOBB(idealObb, new Vector3(0, 0, 1), 1, false, false); } } } }
public override unsafe void Draw() { List <MyPhysics.HitInfo> .Enumerator enumerator2; base.Draw(); foreach (MyCubeBlock block in this.m_grid.BlocksForDraw) { if (MyRenderProxy.VisibleObjectsRead.Contains(block.Render.RenderObjectIDs[0])) { block.Render.Draw(); } } if ((MyCubeGrid.ShowCenterOfMass && (!this.IsStatic && (base.Container.Entity.Physics != null))) && base.Container.Entity.Physics.HasRigidBody) { MatrixD worldMatrix = base.Container.Entity.Physics.GetWorldMatrix(); Vector3D centerOfMassWorld = base.Container.Entity.Physics.CenterOfMassWorld; Vector3D position = MySector.MainCamera.Position; float num = Vector3.Distance((Vector3)position, (Vector3)centerOfMassWorld); bool flag = false; if (num < 30f) { flag = true; } else if (num < 200f) { flag = true; MyPhysics.CastRay(position, centerOfMassWorld, m_tmpHitList, 0x10); using (enumerator2 = m_tmpHitList.GetEnumerator()) { while (enumerator2.MoveNext()) { if (!ReferenceEquals(enumerator2.Current.HkHitInfo.GetHitEntity(), this)) { flag = false; break; } } } m_tmpHitList.Clear(); } if (flag) { float num2 = MathHelper.Lerp((float)1f, (float)9f, (float)(num / 200f)); MyStringId id = ID_WEAPON_LASER_IGNORE_DEPTH; Vector4 color = Color.Yellow.ToVector4(); float thickness = 0.02f * num2; MySimpleObjectDraw.DrawLine(centerOfMassWorld - ((worldMatrix.Up * 0.5) * num2), centerOfMassWorld + ((worldMatrix.Up * 0.5) * num2), new MyStringId?(id), ref color, thickness, MyBillboard.BlendTypeEnum.AdditiveTop); MySimpleObjectDraw.DrawLine(centerOfMassWorld - ((worldMatrix.Forward * 0.5) * num2), centerOfMassWorld + ((worldMatrix.Forward * 0.5) * num2), new MyStringId?(id), ref color, thickness, MyBillboard.BlendTypeEnum.AdditiveTop); MySimpleObjectDraw.DrawLine(centerOfMassWorld - ((worldMatrix.Right * 0.5) * num2), centerOfMassWorld + ((worldMatrix.Right * 0.5) * num2), new MyStringId?(id), ref color, thickness, MyBillboard.BlendTypeEnum.AdditiveTop); MyTransparentGeometry.AddBillboardOriented(ID_RED_DOT_IGNORE_DEPTH, Color.White.ToVector4(), centerOfMassWorld, MySector.MainCamera.LeftVector, MySector.MainCamera.UpVector, 0.1f * num2, MyBillboard.BlendTypeEnum.AdditiveTop, -1, 0f); } } if (MyCubeGrid.ShowGridPivot) { MatrixD worldMatrix = base.Container.Entity.WorldMatrix; Vector3D translation = worldMatrix.Translation; Vector3D position = MySector.MainCamera.Position; float num4 = Vector3.Distance((Vector3)position, (Vector3)translation); bool flag2 = false; if (num4 < 30f) { flag2 = true; } else if (num4 < 200f) { flag2 = true; MyPhysics.CastRay(position, translation, m_tmpHitList, 0x10); using (enumerator2 = m_tmpHitList.GetEnumerator()) { while (enumerator2.MoveNext()) { if (!ReferenceEquals(enumerator2.Current.HkHitInfo.GetHitEntity(), this)) { flag2 = false; break; } } } m_tmpHitList.Clear(); } if (flag2) { float num5 = MathHelper.Lerp((float)1f, (float)9f, (float)(num4 / 200f)); MyStringId id2 = ID_WEAPON_LASER_IGNORE_DEPTH; float thickness = 0.02f * num5; Vector4 color = Color.Green.ToVector4(); MySimpleObjectDraw.DrawLine(translation, translation + ((worldMatrix.Up * 0.5) * num5), new MyStringId?(id2), ref color, thickness, MyBillboard.BlendTypeEnum.Standard); color = Color.Blue.ToVector4(); MySimpleObjectDraw.DrawLine(translation, translation + ((worldMatrix.Forward * 0.5) * num5), new MyStringId?(id2), ref color, thickness, MyBillboard.BlendTypeEnum.Standard); color = Color.Red.ToVector4(); MySimpleObjectDraw.DrawLine(translation, translation + ((worldMatrix.Right * 0.5) * num5), new MyStringId?(id2), ref color, thickness, MyBillboard.BlendTypeEnum.Standard); MyTransparentGeometry.AddBillboardOriented(ID_RED_DOT_IGNORE_DEPTH, Color.White.ToVector4(), translation, MySector.MainCamera.LeftVector, MySector.MainCamera.UpVector, 0.1f * num5, MyBillboard.BlendTypeEnum.Standard, -1, 0f); MyRenderProxy.DebugDrawAxis(worldMatrix, 0.5f, false, false, false); } } if (!MyCubeGrid.ShowStructuralIntegrity) { if ((this.m_grid.StructuralIntegrity != null) && this.m_grid.StructuralIntegrity.EnabledOnlyForDraw) { this.m_grid.CloseStructuralIntegrity(); } } else if (this.m_grid.StructuralIntegrity != null) { this.m_grid.StructuralIntegrity.Draw(); } else if (MyFakes.ENABLE_STRUCTURAL_INTEGRITY) { this.m_grid.CreateStructuralIntegrity(); if (this.m_grid.StructuralIntegrity != null) { this.m_grid.StructuralIntegrity.EnabledOnlyForDraw = true; } } if (MyFakes.ENABLE_ATMOSPHERIC_ENTRYEFFECT) { this.DrawAtmosphericEntryEffect(); } if (this.m_grid.MarkedAsTrash) { BoundingBoxD localAABB = this.m_grid.PositionComp.LocalAABB; Vector3D * vectordPtr1 = (Vector3D *)ref localAABB.Max; vectordPtr1[0] += 0.2f; Vector3D *vectordPtr2 = (Vector3D *)ref localAABB.Min; vectordPtr2[0] -= 0.20000000298023224; MatrixD worldMatrix = this.m_grid.PositionComp.WorldMatrix; Color red = Color.Red; red.A = (byte)(((100.0 * (Math.Sin((double)(((float)this.m_grid.TrashHighlightCounter) / 10f)) + 1.0)) / 2.0) + 100.0); red.R = (byte)(((200.0 * (Math.Sin((double)(((float)this.m_grid.TrashHighlightCounter) / 10f)) + 1.0)) / 2.0) + 50.0); Color * colorPtr1 = (Color *)ref red; MyStringId?faceMaterial = null; faceMaterial = null; MySimpleObjectDraw.DrawTransparentBox(ref worldMatrix, ref localAABB, ref (Color) ref colorPtr1, ref red, MySimpleObjectRasterizer.SolidAndWireframe, 1, 0.008f, faceMaterial, faceMaterial, false, -1, MyBillboard.BlendTypeEnum.LDR, 1f, null); } }
private static void PrepareMaterialBatches(MyRenderContext rc, List <MyScreenDecal> decals, uint sinceStartTs) { if (decals.Count == 0) { return; } List <uint> decalsToRemove = new List <uint>(); foreach (MyScreenDecal decal in decals) { var parent = MyIDTracker <MyActor> .FindByID(decal.ParentID); bool world = decal.Flags.HasFlag(MyDecalFlags.World); if (parent == null && !world) { decalsToRemove.Add(decal.ID); continue; } Matrix volumeMatrix; if (world) { volumeMatrix = decal.TopoData.MatrixCurrent; volumeMatrix.Translation = (Vector3)(decal.TopoData.WorldPosition - MyRender11.Environment.Matrices.CameraPosition); } else { MatrixD volumeMatrixD = ((MatrixD)decal.TopoData.MatrixCurrent) * parent.WorldMatrix; volumeMatrix = volumeMatrixD; volumeMatrix.Translation = (Vector3)(volumeMatrixD.Translation - MyRender11.Environment.Matrices.CameraPosition); } uint fadeDiff = decal.FadeTimestamp - sinceStartTs; float fadeAlpha = decal.FadeTimestamp - sinceStartTs >= DECAL_FADE_DURATION ? 1 : fadeDiff / (float)DECAL_FADE_DURATION; m_jobs.Add(new MyDecalJob() { WorldMatrix = volumeMatrix, FadeAlpha = fadeAlpha }); if (MyRender11.Settings.DebugDrawDecals) { MatrixD worldMatrix; if (parent == null) { worldMatrix = decal.TopoData.MatrixCurrent; worldMatrix.Translation = decal.TopoData.WorldPosition; //{X:5.27669191360474 Y:12.7891067266464 Z:-54.623966217041} } else { worldMatrix = ((MatrixD)decal.TopoData.MatrixCurrent) * parent.WorldMatrix; } MyRenderProxy.DebugDrawAxis(worldMatrix, 0.2f, false, true); MyRenderProxy.DebugDrawOBB(worldMatrix, Color.Blue, 0.1f, false, false); Vector3D position = worldMatrix.Translation; MyRenderProxy.DebugDrawText3D(position, decal.SourceTarget, Color.White, 0.5f, false); } } foreach (uint id in decalsToRemove) { DecalNode node = m_nodeMap[id]; RemoveDecalByNode(node); } }
protected override void CalculateTransforms(float distance) { ProfilerShort.Begin("MyCharacter.CalculateTransforms"); base.CalculateTransforms(distance); if (m_headBoneIndex >= 0 && AnimationController.CharacterBones != null && (IsInFirstPersonView || ForceFirstPersonCamera) && ControllerInfo.IsLocallyControlled() && !IsBot) { Vector3 headHorizontalTranslation = AnimationController.CharacterBones[m_headBoneIndex].AbsoluteTransform.Translation; headHorizontalTranslation.Y = 0; MyCharacterBone.TranslateAllBones(AnimationController.CharacterBones, -headHorizontalTranslation); } VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Calculate Hand IK"); if (this == MySession.Static.ControlledEntity) { // (OM) Note: only controlled character can get it's aimed point from camera, otherwise all character's will aim the same direction // set the aimed point explicitly using AimedPoint property m_aimedPoint = GetAimedPointFromCamera(); } VRageRender.MyRenderProxy.GetRenderProfiler().StartNextBlock("Update anim IK"); AnimationController.UpdateInverseKinematics(); // since we already have absolute transforms VRageRender.MyRenderProxy.GetRenderProfiler().StartNextBlock("UpdateLeftHandItemPosition"); if (m_leftHandItem != null) { UpdateLeftHandItemPosition(); } if (m_currentWeapon != null && WeaponPosition != null) { if (!MyPerGameSettings.CheckUseAnimationInsteadOfIK(m_currentWeapon)) { WeaponPosition.Update(); //mainly IK and some zoom + ironsight stuff if (m_handItemDefinition.SimulateLeftHand && m_leftHandIKStartBone != -1 && m_leftHandIKEndBone != -1 && (!UseAnimationForWeapon)) { MatrixD leftHand = (MatrixD)m_handItemDefinition.LeftHand * ((MyEntity)m_currentWeapon).WorldMatrix; CalculateHandIK(m_leftHandIKStartBone, m_leftForearmBone, m_leftHandIKEndBone, ref leftHand); } if (m_handItemDefinition.SimulateRightHand && m_rightHandIKStartBone != -1 && m_rightHandIKEndBone != -1 && (!UseAnimationForWeapon) && IsSitting == false) { MatrixD rightHand = (MatrixD)m_handItemDefinition.RightHand * ((MyEntity)m_currentWeapon).WorldMatrix; CalculateHandIK(m_rightHandIKStartBone, m_rightForearmBone, m_rightHandIKEndBone, ref rightHand); } } else { GetHeadMatrix(true); // CH: REMOVE ME! I'M A TERRIBLE HACK! Debug.Assert(m_rightHandItemBone != -1, "Invalid bone for weapon."); if (m_rightHandItemBone != -1) { //use animation for right hand item MyCharacterBone boneRightHand = AnimationController.CharacterBones[m_rightHandItemBone]; ((MyEntity)m_currentWeapon).PositionComp.WorldMatrix = boneRightHand.AbsoluteTransform * PositionComp.WorldMatrix; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW) { MyRenderProxy.DebugDrawAxis(((MyEntity)m_currentWeapon).PositionComp.WorldMatrix, 0.5f, false); } } } } else { if (WeaponPosition != null) { WeaponPosition.UpdateIkTransitions(); } GetHeadMatrix(true); // CH: REMOVE ME! I'M A TERRIBLE HACK! } VRageRender.MyRenderProxy.GetRenderProfiler().StartNextBlock("ComputeBoneTransform"); var characterBones = AnimationController.CharacterBones; if (characterBones == null) { return; } for (int i = 0; i < characterBones.Length; i++) { MyCharacterBone bone = characterBones[i]; bone.ComputeBoneTransform(); BoneRelativeTransforms[i] = bone.RelativeTransform; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); ProfilerShort.End(); }
// ------------------------------------------------------------------------------------ /// <summary> /// Solve IK for chain of two bones + change rotation of end bone. /// </summary> /// <param name="characterBones">bone storage</param> /// <param name="ikChain">description of bone chain</param> /// <param name="finalPosition">desired position of end bone</param> /// <param name="finalNormal">desired normal of end bone - would be projected on plane first bone-second bone-third bone</param> /// <param name="fromBindPose">solve this starting from the bind pose</param> /// <returns>true on success</returns> public static bool SolveIkTwoBones(MyCharacterBone[] characterBones, MyAnimationIkChainExt ikChain, ref Vector3 finalPosition, ref Vector3 finalNormal, bool fromBindPose) { int boneIndex = ikChain.BoneIndex; float finalMinRot = MathHelper.ToRadians(ikChain.MinEndPointRotation); float finalMaxRot = MathHelper.ToRadians(ikChain.MaxEndPointRotation); Vector3 lastPoleVector = ikChain.LastPoleVector; int chainLength = ikChain.ChainLength; bool alignBoneWithTerrain = ikChain.AlignBoneWithTerrain; MyCharacterBone thirdBone = characterBones[boneIndex]; if (thirdBone == null) { return(false); } MyCharacterBone secondBone = thirdBone.Parent; for (int i = 2; i < chainLength; i++) { secondBone = secondBone.Parent; } if (secondBone == null) { return(false); } MyCharacterBone firstBone = secondBone.Parent; if (firstBone == null) { return(false); } if (fromBindPose) { firstBone.SetCompleteBindTransform(); secondBone.SetCompleteBindTransform(); thirdBone.SetCompleteBindTransform(); firstBone.ComputeAbsoluteTransform(true); } Matrix thirdBoneTransformBackup = thirdBone.AbsoluteTransform; //Vector3 firstBoneTransformRightDir = firstBone.AbsoluteTransform.Right; Vector3 firstBoneOrigin = firstBone.AbsoluteTransform.Translation; Vector3 secondBoneOrigin = secondBone.AbsoluteTransform.Translation; Vector3 thirdBoneOrigin = thirdBone.AbsoluteTransform.Translation; // Vector3D finalPosition comes from parameter Vector3 secondMinusFirst = secondBoneOrigin - firstBoneOrigin; Vector3 finalMinusFirst = finalPosition - firstBoneOrigin; //Vector3 finalMinusSecond = finalPosition - secondBoneOrigin; Vector3 poleVectorNormalized; Vector3 thirdMinusFirst = thirdBoneOrigin - firstBoneOrigin; Vector3.Cross(ref secondMinusFirst, ref thirdMinusFirst, out poleVectorNormalized); // project to 2D (only vectors) poleVectorNormalized.Normalize(); poleVectorNormalized = Vector3.Normalize(Vector3.Lerp(poleVectorNormalized, lastPoleVector, m_poleVectorChangeSmoothness)); Vector3 planeDirY = Vector3.Normalize(finalMinusFirst); // finalMinusFirst? thirdMinusFirst? Vector3 planeDirX = Vector3.Normalize(Vector3.Cross(planeDirY, poleVectorNormalized)); //Vector2 firstBoneOrigin2D = new Vector2(0, 0); Vector2 secondBoneOrigin2D = new Vector2(planeDirX.Dot(ref secondMinusFirst), planeDirY.Dot(ref secondMinusFirst)); Vector2 thirdBoneOrigin2D = new Vector2(planeDirX.Dot(ref thirdMinusFirst), planeDirY.Dot(ref thirdMinusFirst)); Vector2 finalPosition2D = new Vector2(planeDirX.Dot(ref finalMinusFirst), planeDirY.Dot(ref finalMinusFirst)); Vector2 terrainNormal2D = new Vector2(planeDirX.Dot(ref finalNormal), planeDirY.Dot(ref finalNormal)); float firstBoneLength = (secondBoneOrigin2D /* - 0*/).Length(); float secondBoneLength = (thirdBoneOrigin2D - secondBoneOrigin2D).Length(); float finalDistance = finalPosition2D.Length(); if (firstBoneLength + secondBoneLength <= finalDistance) { finalPosition2D = (firstBoneLength + secondBoneLength) * finalPosition2D / finalDistance; // too far //return false; } // mid-joint -> wanted position in 2D Vector2 newSecondBoneOrigin2D; { newSecondBoneOrigin2D.Y = (finalPosition2D.Y * finalPosition2D.Y - secondBoneLength * secondBoneLength + firstBoneLength * firstBoneLength) / (2.0f * finalPosition2D.Y); float srqtArg = firstBoneLength * firstBoneLength - newSecondBoneOrigin2D.Y * newSecondBoneOrigin2D.Y; newSecondBoneOrigin2D.X = (float)Math.Sqrt(srqtArg > 0 ? srqtArg : 0); } // project back Vector3 newSecondBoneOrigin = firstBoneOrigin + planeDirX * newSecondBoneOrigin2D.X + planeDirY * newSecondBoneOrigin2D.Y; Vector3 newSecondMinusFirst = newSecondBoneOrigin - firstBoneOrigin; Vector3 newThirdMinusSecond = finalPosition - newSecondBoneOrigin; Vector3 newTerrainNormal = planeDirX * terrainNormal2D.X + planeDirY * terrainNormal2D.Y; newTerrainNormal.Normalize(); // set the rotations in the bones // first bone --------------------------------- Matrix firstBoneAbsoluteFinal = firstBone.AbsoluteTransform; Quaternion rotFirstDelta = Quaternion.CreateFromTwoVectors(secondMinusFirst, newSecondMinusFirst); firstBoneAbsoluteFinal.Right = Vector3.Transform(firstBoneAbsoluteFinal.Right, rotFirstDelta); firstBoneAbsoluteFinal.Up = Vector3.Transform(firstBoneAbsoluteFinal.Up, rotFirstDelta); firstBoneAbsoluteFinal.Forward = Vector3.Transform(firstBoneAbsoluteFinal.Forward, rotFirstDelta); firstBone.SetCompleteTransformFromAbsoluteMatrix(ref firstBoneAbsoluteFinal, true); firstBone.ComputeAbsoluteTransform(); // second bone --------------------------------- Matrix secondBoneAbsoluteFinal = secondBone.AbsoluteTransform; Quaternion rotSecondDelta = Quaternion.CreateFromTwoVectors(thirdBone.AbsoluteTransform.Translation - secondBone.AbsoluteTransform.Translation, newThirdMinusSecond); secondBoneAbsoluteFinal.Right = Vector3.Transform(secondBoneAbsoluteFinal.Right, rotSecondDelta); secondBoneAbsoluteFinal.Up = Vector3.Transform(secondBoneAbsoluteFinal.Up, rotSecondDelta); secondBoneAbsoluteFinal.Forward = Vector3.Transform(secondBoneAbsoluteFinal.Forward, rotSecondDelta); secondBone.SetCompleteTransformFromAbsoluteMatrix(ref secondBoneAbsoluteFinal, true); secondBone.ComputeAbsoluteTransform(); //// third bone ---------------------------------- if (ikChain.EndBoneTransform.HasValue) { MatrixD localTransformRelated = ikChain.EndBoneTransform.Value * MatrixD.Invert((MatrixD)thirdBone.BindTransform * thirdBone.Parent.AbsoluteTransform); thirdBone.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)localTransformRelated.GetOrientation())); thirdBone.Translation = (Vector3)localTransformRelated.Translation; thirdBone.ComputeAbsoluteTransform(); } else if (alignBoneWithTerrain) { Matrix footRotation; Vector3 finalRotPoleVec; Vector3.Cross(ref newTerrainNormal, ref Vector3.Up, out finalRotPoleVec); float deltaAngle = MyUtils.GetAngleBetweenVectors(newTerrainNormal, Vector3.Up); if (finalRotPoleVec.Dot(poleVectorNormalized) > 0) { deltaAngle = -deltaAngle; } deltaAngle = MathHelper.Clamp(deltaAngle, finalMinRot, finalMaxRot); Matrix.CreateFromAxisAngle(ref poleVectorNormalized, deltaAngle, out footRotation); ikChain.LastAligningRotationMatrix = Matrix.Lerp(ikChain.LastAligningRotationMatrix, footRotation, ikChain.AligningSmoothness); Matrix thirdBoneAbsoluteFinal = thirdBoneTransformBackup.GetOrientation() * ikChain.LastAligningRotationMatrix; thirdBoneAbsoluteFinal.Translation = thirdBone.AbsoluteTransform.Translation; thirdBone.SetCompleteTransformFromAbsoluteMatrix(ref thirdBoneAbsoluteFinal, true); thirdBone.ComputeAbsoluteTransform(); } // Debugging of the solver. if (m_showDebugDrawings) { MyRenderProxy.DebugDrawLine3D(Vector3D.Transform(firstBoneOrigin, ref DebugTransform), Vector3D.Transform(secondBoneOrigin, ref DebugTransform), Color.Yellow, Color.Red, false); MyRenderProxy.DebugDrawLine3D(Vector3D.Transform(secondBoneOrigin, ref DebugTransform), Vector3D.Transform(thirdBoneOrigin, ref DebugTransform), Color.Yellow, Color.Red, false); MyRenderProxy.DebugDrawSphere(Vector3D.Transform(finalPosition, ref DebugTransform), 0.05f, Color.Cyan, 1.0f, false); MyRenderProxy.DebugDrawLine3D(Vector3D.Transform(secondBoneOrigin, ref DebugTransform), Vector3D.Transform(secondBoneOrigin + poleVectorNormalized, ref DebugTransform), Color.PaleGreen, Color.PaleGreen, false); MyRenderProxy.DebugDrawLine3D(Vector3D.Transform(firstBoneOrigin, ref DebugTransform), Vector3D.Transform(firstBoneOrigin + planeDirX, ref DebugTransform), Color.White, Color.White, false); MyRenderProxy.DebugDrawLine3D(Vector3D.Transform(firstBoneOrigin, ref DebugTransform), Vector3D.Transform(firstBoneOrigin + planeDirY, ref DebugTransform), Color.White, Color.White, false); MyRenderProxy.DebugDrawSphere(Vector3D.Transform(newSecondBoneOrigin, ref DebugTransform), 0.05f, Color.Green, 1.0f, false); MyRenderProxy.DebugDrawAxis(firstBone.AbsoluteTransform * DebugTransform, 0.5f, false); MyRenderProxy.DebugDrawLine3D(Vector3D.Transform(finalPosition, ref DebugTransform), Vector3D.Transform(finalPosition + newTerrainNormal, ref DebugTransform), Color.Black, Color.LightBlue, false); MyRenderProxy.DebugDrawArrow3D(Vector3D.Transform(secondBoneOrigin, ref DebugTransform), Vector3D.Transform(newSecondBoneOrigin, ref DebugTransform), Color.Green, Color.White, false); } ikChain.LastPoleVector = poleVectorNormalized; return(true); }