private static void ComputeMaxDistance(MySunWindBillboardSmall billboard) { Vector3 sunWindVector = m_directionFromSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_HALF; var offset = (-m_directionFromSunNormalized * MySunWindConstants.RAY_CAST_DISTANCE); // This line start where billboard starts and end at place that is farest possible place billboard can reach // If intersection found, we will mark that place as small billboard's destination. It can't go further. MyLine line = new MyLine((sunWindVector + billboard.InitialAbsolutePosition) + offset, billboard.InitialAbsolutePosition + m_directionFromSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_TOTAL, true); MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref line, DoNotIgnoreTheseTypes); billboard.MaxDistance = (intersection != null) ? (intersection.Value.Triangle.Distance - billboard.Radius) : MySunWindConstants.SUN_WIND_LENGTH_TOTAL; }
public void DoWork() { m_scannedEntity = null; var result = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref m_line, m_typesToScan, true); if (result != null) { m_scannedEntity = result.Value.Entity; } else { m_scannedEntity = null; } //m_scannedEntity = MyEntities.GetAllIntersectionWithLine(ref m_line, m_owner, null, true, true); }
// If explosion was with voxels, crease dirt decals in player's cockpit glass // We don't throw random number of debris lines from explosion (because it will be waste). Instead we get intersection line from explosion center to player head, // which should intersect the cockpit glass. Plus we move player head by random vector. void CreateDirtDecalOnCockpitGlass(ref BoundingSphere explosionSphere) { MySmallShip player = MySession.PlayerShip; float maxDistance = m_explosionSphere.Radius * MyExplosionsConstants.EXPLOSION_RADIUS_MULTPLIER_FOR_DIRT_GLASS_DECALS; float distance = Vector3.Distance(player.GetPosition(), explosionSphere.Center) - player.ModelLod0.BoundingSphere.Radius; // Decal interpolator - based on distance to explosion, range <0..1> // But then increased because we aren't able to reach max distance so we need to help it little bit float interpolator = 1 - MathHelper.Clamp(distance / maxDistance, 0, 1); interpolator = (float)Math.Pow(interpolator, 3f); // Don't create dirt decal if we are too far if (interpolator <= 0.0f) { return; } // Chech intersection between explosion and player's head. BUT move the line in player's head direction, because we don't want to make intersection with object which caused the explosion //MyLine line = new MyLine(intersection.IntersectionPointInWorldSpace, player.GetPosition(), true); //MyLine line = new MyLine(intersection.IntersectionPointInWorldSpace, MyCamera.m_initialSunWindPosition, true); //Vector3 playerHeadPositionWorld = MyUtils.GetTransform(MyFakes.PLAYER_HEAD_FOR_COCKPIT_INTERIOR_FAKE_TRANSLATION * -1, ref player.WorldMatrix); Vector3 playerHeadPositionWorld = player.GetPlayerHeadForCockpitInterior(); MyLine line = new MyLine(explosionSphere.Center, playerHeadPositionWorld, true); line.From += line.Direction * MyExplosionsConstants.OFFSET_LINE_FOR_DIRT_DECAL; MyIntersectionResultLineTriangleEx?glassIntersection = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref line, new Type[] { typeof(MySmallShip) }); if ((glassIntersection != null) && (glassIntersection.Value.Entity is MyCockpitGlassEntity)) { // Decal alpha (never is 1.0f, because we want to see through the dirt) float alpha = MathHelper.Clamp(MathHelper.Lerp(0.2f, 1.0f, interpolator) - 0.1f, 0, 1); //const float ALPHA_INCREASE = 0.4f; //float alpha = 1 - (float)Math.Pow(MathHelper.Clamp(distance / maxDistance, 0, 1), 5); //float alpha = (float)MathHelper.SmoothStep(0, 1, 1 - MathHelper.Clamp(distance / maxDistance, 0, 1)); //float alpha = MathHelper.Clamp(1 - MathHelper.Clamp(distance / maxDistance, 0, 1) + ALPHA_INCREASE, ALPHA_INCREASE, 1); // Decal size float size = MathHelper.Lerp(2.5f, 4f, interpolator); MyIntersectionResultLineTriangleEx glassIntersection2 = glassIntersection.Value; MyCockpitGlassDecals.Add(MyCockpitGlassDecalTexturesEnum.DirtOnGlass, size, MyMwcUtils.GetRandomRadian(), alpha, ref glassIntersection2, true); } }
public static Matrix UpdateShapePosition() { if (DetachedVoxelHand != null) { VoxelHandShape.MoveAndRotate(DetachedVoxelHand.WorldMatrix.Translation, DetachedVoxelHand.WorldMatrix); return(DetachedVoxelHand.WorldMatrix); } Matrix world = Matrix.Identity; float minDist = 2 * VoxelHandShape.LocalVolume.Radius; float dist = 2 * minDist; Vector3 from = MyCamera.Position - MyCamera.UpVector * minDist * 0.5f; if (IsProjected) { if (!MyFakes.MWBUILDER) { var line = new MyLine(from, from + MyCamera.ForwardVector * 10000, true); var hit = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref line, new System.Type[] { typeof(MyVoxelMap) }); if (hit != null) { dist = Vector3.Distance(MyCamera.Position, hit.Value.IntersectionPointInWorldSpace); } else { dist = 5000; } m_conePosition = from + MyCamera.ForwardVector * minDist * 0.7f; Vector3 shapePosition = from + MyCamera.ForwardVector * (dist + VoxelHandShape.LocalVolume.Radius * m_distance * 2); Vector3 shapeForward = Vector3.Normalize(MyCamera.UpVector * minDist * 0.5f + shapePosition - from); Vector3 shapeUp = shapeForward - MyCamera.ForwardVector + MyCamera.UpVector; world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp); VoxelHandShape.MoveAndRotate(shapePosition, world); return(world); } else { var line = new MyLine(from, from + MyCamera.ForwardVector * 10000, true); var hit = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref line, new System.Type[] { typeof(MyVoxelMap) }); Vector3 normal = Vector3.Up; dist = 5000; Vector3 shapePosition = from + MyCamera.ForwardVector * dist; if (hit != null) { dist = Vector3.Distance(MyCamera.Position, hit.Value.IntersectionPointInWorldSpace); normal = hit.Value.NormalInWorldSpace; shapePosition = hit.Value.IntersectionPointInWorldSpace; } m_conePosition = from + MyCamera.ForwardVector * minDist * 0.7f; Vector3 shapeUp = normal; Vector3 shapeForward = Vector3.Cross(-MyCamera.LeftVector, shapeUp); float dot = Vector3.Dot(shapeUp, shapeForward); if ((dot > 0.9f) || (dot < -0.9f)) { shapeForward = Vector3.Forward; } shapePosition.X = MyEditorGrid.GetGridStepInMeters() * (float)Math.Round(shapePosition.X / MyEditorGrid.GetGridStepInMeters()); shapePosition.Y = MyEditorGrid.GetGridStepInMeters() * (float)Math.Round(shapePosition.Y / MyEditorGrid.GetGridStepInMeters()); shapePosition.Z = MyEditorGrid.GetGridStepInMeters() * (float)Math.Round(shapePosition.Z / MyEditorGrid.GetGridStepInMeters()); world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp); VoxelHandShape.MoveAndRotate(shapePosition, world); return(world); } } else if (IsProjectedToWaypoints) { //Lets find projection on closest collision with waypoint edge from = MyCamera.Position - MyCamera.UpVector * 10.5f; m_conePosition = from + MyCamera.ForwardVector * 10.7f; Vector3 shapePosition = from + MyCamera.ForwardVector * m_distance; List <Tuple <MyWayPoint, MyWayPoint> > edges = MyWayPointGraph.GetAllEdgesInSphere(shapePosition, VoxelHandShape.LocalVolume.Radius * 2); Tuple <MyWayPoint, MyWayPoint> closestEdge = null; float minDistance = float.MaxValue; Vector3 closestPoint = shapePosition; float distFromFirstWaypoint = 0; foreach (Tuple <MyWayPoint, MyWayPoint> edge in edges) { Vector3 linePos1 = edge.Item1.Position; Vector3 linePos2 = edge.Item2.Position; Vector3 point = MyUtils.GetClosestPointOnLine(ref linePos1, ref linePos2, ref shapePosition, out distFromFirstWaypoint); float distance = Vector3.Distance(shapePosition, point); if (distance < minDistance) { minDistance = distance; closestEdge = edge; closestPoint = point; } } if (closestEdge != null) { shapePosition = closestPoint; Vector3 shapeForward = Vector3.Normalize(shapePosition - from); Vector3 shapeUp = MyCamera.UpVector; world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp); VoxelHandShape.MoveAndRotate(shapePosition, world); MyWayPoint firstWaypoint = null; MyWayPoint secondWaypoint = null; float edgeDistance = Vector3.Distance(closestEdge.Item1.Position, closestEdge.Item2.Position); if (closestEdge.Item1.Position.Y < closestEdge.Item2.Position.Y) { firstWaypoint = closestEdge.Item1; secondWaypoint = closestEdge.Item2; } else { firstWaypoint = closestEdge.Item2; secondWaypoint = closestEdge.Item1; distFromFirstWaypoint = edgeDistance - distFromFirstWaypoint; } float edgeRatio = edgeDistance > 0 ? distFromFirstWaypoint / edgeDistance : 0; Quaternion quaternion1 = Quaternion.CreateFromRotationMatrix(closestEdge.Item1.WorldMatrix); Quaternion quaternion2 = Quaternion.CreateFromRotationMatrix(closestEdge.Item2.WorldMatrix); Quaternion resultQuaternion = Quaternion.Lerp(quaternion1, quaternion2, edgeRatio); Matrix resultMatrix = Matrix.CreateFromQuaternion(resultQuaternion); resultMatrix.Translation = shapePosition; VoxelHandShape.MoveAndRotate(shapePosition, resultMatrix); return(resultMatrix); } } if (MyFakes.MWBUILDER) { from = MyCamera.Position; m_conePosition = from + MyCamera.ForwardVector * 10.7f; /* * //Vector3 planeNormal = new Vector3(MyCamera.ForwardVector.X, 0, MyCamera.ForwardVector.Z); * Vector3 planeNormal = new Vector3(0, MyCamera.ForwardVector.Y, MyCamera.ForwardVector.Z); * * * planeNormal.Normalize(); * Vector3 planePoint = planePoint = from + planeNormal * m_distance; * planeNormal = -planeNormal; * * Plane plane = new Plane(planeNormal, -Vector3.Dot(planeNormal, planePoint)); * * Ray r = new Ray(from, MyCamera.ForwardVector); * float? intr = r.Intersects(plane); */ // if (intr.HasValue) { Vector3 shapePosition = from + MyCamera.ForwardVector * m_distance; Vector3 shapeForward = Vector3.Forward; Vector3 shapeUp = Vector3.Up; shapePosition.X = MyEditorGrid.GetGridStepInMeters() * (float)Math.Round(shapePosition.X / MyEditorGrid.GetGridStepInMeters()); shapePosition.Y = MyEditorGrid.GetGridStepInMeters() * (float)Math.Round(shapePosition.Y / MyEditorGrid.GetGridStepInMeters()); shapePosition.Z = MyEditorGrid.GetGridStepInMeters() * (float)Math.Round(shapePosition.Z / MyEditorGrid.GetGridStepInMeters()); world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp); VoxelHandShape.MoveAndRotate(shapePosition, world); } } else { from = MyCamera.Position - MyCamera.UpVector * 10.5f; m_conePosition = from + MyCamera.ForwardVector * 10.7f; Vector3 shapePosition = from + MyCamera.ForwardVector * m_distance; Vector3 shapeForward = Vector3.Normalize(/*MyCamera.UpVector * minDist * 0.5f*/ shapePosition - from); Vector3 shapeUp = /*shapeForward - MyCamera.ForwardVector +*/ MyCamera.UpVector; world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp); VoxelHandShape.MoveAndRotate(shapePosition, world); } return(world); }