//private bool TestAABB(ref BoundingBox bbox) //{ // return (bbox.Max - bbox.Min).Length() < MyLightsConstants.MAX_SPOTLIGHT_AABB_DIAGONAL; //} private static void CalculateAABB(ref BoundingBox bbox, out float scaleZ, out float scaleXY, ref Vector3 position, ref Vector3 direction, ref Vector3 up, float reflectorConeMaxAngleCos, float reflectorRange) { float cosAngle = 1 - reflectorConeMaxAngleCos; scaleZ = reflectorRange; // Calculate cone side (hypotenuse of triangle) float side = reflectorRange / cosAngle; // Calculate cone bottom scale (Pythagoras theorem) scaleXY = (float)System.Math.Sqrt(side * side - reflectorRange * reflectorRange) * 2; up = MyMwcUtils.Normalize(up); Vector3 coneSideDirection = Vector3.Cross(up, direction); coneSideDirection = MyMwcUtils.Normalize(coneSideDirection); Vector3 coneCenter = position + direction * scaleZ; Vector3 pt1 = coneCenter + coneSideDirection * scaleXY / 2 + up * scaleXY / 2; Vector3 pt2 = coneCenter - coneSideDirection * scaleXY / 2 + up * scaleXY / 2; Vector3 pt3 = coneCenter + coneSideDirection * scaleXY / 2 - up * scaleXY / 2; Vector3 pt4 = coneCenter - coneSideDirection * scaleXY / 2 - up * scaleXY / 2; bbox = bbox.CreateInvalid(); bbox = bbox.Include(ref position); //bbox = bbox.Include(ref coneCenter); bbox = bbox.Include(ref pt1); bbox = bbox.Include(ref pt2); bbox = bbox.Include(ref pt3); bbox = bbox.Include(ref pt4); }
/// <summary> /// Collapses an edge defined by its two endpoint vertices. /// </summary> /// <param name="keptVertexIndex">The index of the vertex that will NOT be removed in the process. /// However, it will be moved if it's not locked.</param> /// <param name="removedVertexIndex">The index of the vertex that WILL be removed in the process.</param> private void CollapseEdge(short keptVertexIndex, short removedVertexIndex) { Debug.Assert(!IsVertexLocked(removedVertexIndex)); // if I can move the kept vertex, make its new position the average of the previous positions bool interpolate = !IsVertexLocked(keptVertexIndex); if (interpolate) { var keptVertex = m_vertices[keptVertexIndex]; keptVertex.Position = .5f * (keptVertex.Position + m_vertices[removedVertexIndex].Position); keptVertex.Normal = MyMwcUtils.Normalize( (keptVertex.Normal + m_vertices[removedVertexIndex].Normal)); m_vertices[keptVertexIndex] = keptVertex; } var removedVertexTriangles = m_adjacentTriangleIndices[removedVertexIndex]; for (int i = removedVertexTriangles.Count - 1; i >= 0; i--) { var triangleIndex = removedVertexTriangles[i]; var triangle = m_triangles[triangleIndex]; if (triangle.VertexIndex0 == removedVertexIndex) { triangle.VertexIndex0 = keptVertexIndex; Debug.Assert(keptVertexIndex < m_vertices.Count); } if (triangle.VertexIndex1 == removedVertexIndex) { triangle.VertexIndex1 = keptVertexIndex; Debug.Assert(keptVertexIndex < m_vertices.Count); } if (triangle.VertexIndex2 == removedVertexIndex) { triangle.VertexIndex2 = keptVertexIndex; Debug.Assert(keptVertexIndex < m_vertices.Count); } // todo find out why test for zero-surface does not work if (IsDegenerated(triangle) /*|| HasZeroSurface(triangle)*/) { // delete triangle RemoveTriangle(triangleIndex); } else { // update triangle m_triangles[triangleIndex] = triangle; if (!m_adjacentTriangleIndices[keptVertexIndex].Contains(triangleIndex)) { m_adjacentTriangleIndices[keptVertexIndex].Add(triangleIndex); } } } }
//Creates rotation matrix from direction (dir must be normalized) public static Matrix MatrixFromDir(Vector3 dir) { Vector3 right = new Vector3(0.0f, 0.0f, 1.0f); Vector3 up; float d = dir.Z; if (d > -0.99999 && d < 0.99999) { // to avoid problems with normalize in special cases right = right - dir * d; right = MyMwcUtils.Normalize(right); up = Vector3.Cross(dir, right); } else { //dir lies with z axis right = new Vector3(dir.Z, 0, -dir.X); up = new Vector3(0, 1, 0); }; Matrix m = Matrix.Identity; m.Right = right; m.Up = up; m.Forward = dir; return(m); }
/// <summary> /// Updates velocity from external accel and gravitation /// </summary>= public void UpdateVelocity(float dt) { // apply directional gravity m_ExternalLinearAcceleration += MyPhysics.physicsSystem.Gravitation * dt; // apply point gravity Vector3 accelerationFromPoints = Vector3.Zero; foreach (var gravityPoint in MyPhysics.physicsSystem.GravitationPoints) { float distance = Vector3.Distance(Position, gravityPoint.Item1.Center); float power = MathHelper.Clamp(1 - distance / gravityPoint.Item1.Radius, 0, 1); Vector3 dirToCenter = Vector3.Normalize(gravityPoint.Item1.Center - Position); accelerationFromPoints += dirToCenter * power * gravityPoint.Item2; } m_ExternalLinearAcceleration += accelerationFromPoints * dt; m_Velocity += m_ExternalLinearAcceleration * dt; m_AngularVelocity += m_ExternalAngularAcceleration * dt; if (m_MaxAngularVelocity > 0.0f && m_AngularVelocity.Length() > m_MaxAngularVelocity) { m_AngularVelocity = MyMwcUtils.Normalize(m_AngularVelocity); m_AngularVelocity *= m_MaxAngularVelocity; } if (m_MaxLinearVelocity > 0.0f && m_Velocity.Length() > m_MaxLinearVelocity) { m_Velocity = MyMwcUtils.Normalize(m_Velocity); m_Velocity *= m_MaxLinearVelocity; } }
public static Vector3 PointOnOrbit(this Random random, float orbitRadius, float orbitRadiusDev, float angleRad, float angleRadDev) { float ang = MathHelper.Lerp(angleRad - angleRadDev, angleRad + angleRadDev, Float(random)); Vector3 orbitPoint = new Vector3((float)Math.Sin(ang) * orbitRadius, 0, (float)Math.Cos(ang) * orbitRadius); Vector3 toOrbit = MyMwcUtils.Normalize(orbitPoint); return(orbitPoint + MyMwcUtils.Normalize(toOrbit * Float(random, -1, 1) + Vector3.Up * Float(random, -1, 1)) * orbitRadiusDev * Float(random)); }
/// <summary> /// Simple prediction, not used /// </summary> /// <param name="targetEntity"></param> /// <returns></returns> protected Vector3 GetPredictedVelocityToTargetEntity(MyEntity targetEntity) { Vector3?targetDir = null; Vector3?decoyPosition = DetectDecoys(); if (decoyPosition.HasValue) { var decoyToMissile = decoyPosition.Value - GetPosition(); if (decoyToMissile.LengthSquared() < MyDecoyFlareConstants.DECOY_KILL_RADIUS * MyDecoyFlareConstants.DECOY_KILL_RADIUS) { Explode(); return(Vector3.Zero); } targetDir = decoyToMissile; targetDir = MyMwcUtils.Normalize(targetDir.Value); } else if (targetEntity != null) { //calculate position to navigate missile to targetDir = targetEntity.WorldMatrix.Translation - WorldMatrix.Translation; //simple solution float distance = (this.WorldMatrix.Translation - targetEntity.WorldMatrix.Translation).Length(); float time = distance / m_actualSpeed; if (time > MyGuidedMissileConstants.MISSILE_PREDICATION_TIME_TRESHOLD) { m_predicatedPosition = time * m_targetVelocity + targetEntity.WorldMatrix.Translation; targetDir = m_predicatedPosition - WorldMatrix.Translation; //simple solution } targetDir = MyMwcUtils.Normalize(targetDir.Value); } if (targetDir.HasValue) { //create new navigation direction Vector3 actualDir = WorldMatrix.Forward; Vector3 rotationAxis = Vector3.Cross(actualDir, targetDir.Value); Matrix rotationMatrix = Matrix.CreateFromAxisAngle(rotationAxis, m_turnSpeed * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS); rotationMatrix.Right = MyMwcUtils.Normalize(rotationMatrix.Right); rotationMatrix.Up = MyMwcUtils.Normalize(rotationMatrix.Up); rotationMatrix.Forward = MyMwcUtils.Normalize(rotationMatrix.Forward); Matrix newBodyMatrix = WorldMatrix * rotationMatrix; newBodyMatrix.Translation = WorldMatrix.Translation; SetWorldMatrix(newBodyMatrix); return(newBodyMatrix.Forward); } //no target ship, fly straight ahead return(WorldMatrix.Forward); }
public static Matrix NormalizeMatrix(Matrix matrix) { Matrix m = matrix; m.Right = MyMwcUtils.Normalize(m.Right); m.Up = MyMwcUtils.Normalize(m.Up); m.Forward = MyMwcUtils.Normalize(m.Forward); return(m); }
protected override bool Interact(bool staticCollision) { if (!staticCollision && GetRigidBody1().IsStatic() && GetRigidBody2().IsStatic()) { return(false); } MyRBSphereElement sphere1 = (MyRBSphereElement)RBElement1; MyRBSphereElement sphere2 = (MyRBSphereElement)RBElement2; Matrix matrix1 = sphere1.GetGlobalTransformation(); Matrix matrix2 = sphere2.GetGlobalTransformation(); Vector3 p1 = matrix1.Translation; Vector3 p2 = matrix2.Translation; Vector3 d = p2 - p1; float length = d.Length(); float contactRadius = sphere1.Radius + sphere2.Radius; float eps = MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon; if (staticCollision) { return(length < contactRadius); } // from now on we handle dynamic collision float dynEps = 0; if (!staticCollision && length > eps) { dynEps = Vector3.Dot(GetRigidBody1().LinearVelocity - GetRigidBody2().LinearVelocity, d) / length * MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; if (dynEps < 0) { dynEps = 0; } } if (length > MyMwcMathConstants.EPSILON && length < contactRadius + eps + dynEps) { Vector3 n = MyMwcUtils.Normalize(d); Vector3 p = p1 + n * (sphere1.Radius + (length - contactRadius) * 0.5f); float error = length - (contactRadius + 0.5f * eps); MySmallCollPointInfo[] collInfo = MyContactInfoCache.SCPIStackAlloc(); collInfo[0] = new MySmallCollPointInfo(p - matrix1.Translation, p - matrix2.Translation, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, n, error, p); MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collInfo, 1); MyContactInfoCache.FreeStackAlloc(collInfo); return(true); } return(false); }
// Add cockpit decal and all surounding triangles. Method needs intersection, but result of the intersection must be with ideal glass, not any other part of a miner ship. public static void Add(MyCockpitGlassDecalTexturesEnum decalTexture, float decalSize, float angle, float alpha, ref MyIntersectionResultLineTriangleEx idealIntersection, bool alphaBlendByAngle) { MyCockpitGlassDecalsBuffer buffer = GetBuffer(decalTexture); // Polomer decalu a scale faktor pre vypocet textury. // Decal size is something as radius of a decal, so when converting from real metres to texture space, we need to divide by 2.0 float decalScale = 1.0f / decalSize / 2.0f; Vector3 rightVector = MyMwcUtils.Normalize(idealIntersection.Triangle.InputTriangle.Vertex0 - idealIntersection.IntersectionPointInObjectSpace); Vector3 upVector = MyMwcUtils.Normalize(Vector3.Cross(rightVector, idealIntersection.NormalInObjectSpace)); // We create world matrix for the decal and then rotate the matrix, so we can extract rotated right/up vectors/planes for texture coord0 calculations Matrix decalMatrix = Matrix.CreateRotationZ(angle) * Matrix.CreateWorld(idealIntersection.IntersectionPointInObjectSpace, idealIntersection.NormalInObjectSpace, upVector); // Right plane MyPlane rightPlane; rightPlane.Point = idealIntersection.IntersectionPointInObjectSpace; rightPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Right, ref decalMatrix); // Up plane MyPlane upPlane; upPlane.Point = idealIntersection.IntersectionPointInObjectSpace; upPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Up, ref decalMatrix); float?maxAngle = null; if (alphaBlendByAngle == false) { maxAngle = MyCockpitGlassDecalsConstants.MAX_NEIGHBOUR_ANGLE; } BoundingSphere decalSphere = new BoundingSphere(idealIntersection.IntersectionPointInObjectSpace, decalSize); m_neighbourTriangles.Clear(); //idealIntersection.PhysObject.GetTrianglesIntersectingSphere(ref decalSphere, idealIntersection.NormalInObjectSpace, maxAngle, idealIntersection.TriangleHelperIndex, m_neighbourTriangles, buffer.MaxNeighbourTriangles); idealIntersection.Entity.GetTrianglesIntersectingSphere(ref decalSphere, idealIntersection.NormalInObjectSpace, maxAngle, m_neighbourTriangles, buffer.MaxNeighbourTriangles); int trianglesToAdd = m_neighbourTriangles.Count;// +1; if (buffer.CanAddTriangles(trianglesToAdd) == true) { // Decal on triangleVertexes we hit // buffer.Add(idealIntersection.Triangle.InputTriangle, idealIntersection.NormalInObjectSpace, ref rightPlane, ref upPlane, decalScale, color, alphaBlendByAngle, ref decalSphere); // Create decal for every neighbour triangleVertexes for (int i = 0; i < m_neighbourTriangles.Count; i++) { buffer.Add(m_neighbourTriangles[i].Vertexes, idealIntersection.NormalInObjectSpace, ref rightPlane, ref upPlane, decalScale, alpha, alphaBlendByAngle, ref decalSphere); } } }
// This method will start sun wind. Or if there is one coming, this will reset it so it will start again. public static void Start() { // Activate sun wind IsActive = true; m_smallBillboardsStarted = false; m_timeLastUpdate = MyMinerGame.TotalGamePlayTimeInMilliseconds; // Place sun wind at farest possible negative Z position //Vector3 directionToSunNormalized = MyMwcUtils.Normalize(MyGuiScreenGameBase.Static.SunPosition - MyCamera.Position); MyMwcSectorGroups.Get(MyGuiScreenGameBase.Static.Sector.SectorGroup).GetDirectionToSunNormalized(); Vector3 directionToSunNormalized = MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized(); m_initialSunWindPosition = MyCamera.Position + directionToSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_HALF; m_directionFromSunNormalized = -directionToSunNormalized; // Start the sound of burning (looping) StopCue(); m_burningCue = MyAudio.AddCue3D(MySoundCuesEnum.SfxSolarWind, m_initialSunWindPosition, m_directionFromSunNormalized, Vector3.Up, Vector3.Zero); //MySounds.UpdateCuePitch(m_burningCue, MyMwcUtils.GetRandomFloat(-1, +1)); m_speed = MyMwcUtils.GetRandomFloat(MySunWindConstants.SPEED_MIN, MySunWindConstants.SPEED_MAX); m_strength = MyMwcUtils.GetRandomFloat(0, 1); MyUtils.GetPerpendicularVector(ref m_directionFromSunNormalized, out m_rightVector); m_downVector = MyMwcUtils.Normalize(Vector3.Cross(m_directionFromSunNormalized, m_rightVector)); StartBillboards(); // Reinit computed max distances, they'll be computed in update m_computedMaxDistances = 0; m_deltaTime = 0; // Collect entities m_sunwindEntities.Clear(); foreach (var entity in MyEntities.GetEntities()) { if (!(entity is MySmallShip)) { continue; } // Do not move with indestructibles (NPCs etc) if (!entity.IsDestructible) { continue; } m_sunwindEntities.Add(entity); } }
public static void DrawLine(Vector3 start, Vector3 end, MyTransparentMaterialEnum?material, ref Vector4 color, float thickness) { Vector3 dir = end - start; float len = dir.Length(); if (len > 0.1f) { dir = MyMwcUtils.Normalize(dir); MyTransparentGeometry.AddLineBillboard(material ?? MyTransparentMaterialEnum.ProjectileTrailLine, color, start, dir, len, thickness); } }
// IMPORTANT: This struct must be initialized using this constructor, or by filling all four fields. It's because // some code may need length or distance, and if they aren't calculated, we can have problems. public MyLine(Vector3 from, Vector3 to, bool calculateBoundingBox = true) { From = from; To = to; Direction = MyMwcUtils.Normalize(to - from); Vector3.Distance(ref to, ref from, out Length); // Calculate line's bounding box, but only if we know we will need it BoundingBox = BoundingBoxHelper.InitialBox; if (calculateBoundingBox == true) { BoundingBoxHelper.AddLine(ref this, ref BoundingBox); } }
static Vector3 CalculateDominantNormal(List <MyTriangle_Vertex_Normals> triangleVertexNormals) { Vector3 normalSum = Vector3.Zero; for (int i = 0; i < triangleVertexNormals.Count; i++) { normalSum += triangleVertexNormals[i].Normals.Normal0 + triangleVertexNormals[i].Normals.Normal1 + triangleVertexNormals[i].Normals.Normal2; } return(MyMwcUtils.Normalize(normalSum)); }
/// <summary> /// Get random direction near base direction /// </summary> /// <param name="random"></param> /// <param name="baseDirection"></param> /// <param name="maxAngleDeviation">Max angle deviation in radians PI/2 is right angle</param> /// <returns></returns> public static Vector3 Direction(this Random random, Vector3 baseDirection, float maxAngleDeviation) { Vector3 otherDir = Vector3.Up; if (baseDirection == otherDir || baseDirection == -otherDir) { otherDir = Vector3.Left; } Vector3 planar1 = Vector3.Cross(baseDirection, otherDir); Vector3 planar2 = Vector3.Cross(baseDirection, planar1); float maxDist = (float)Math.Tan(maxAngleDeviation); return(MyMwcUtils.Normalize(baseDirection + planar1 * random.Float(-maxDist, maxDist) + planar2 * random.Float(-maxDist, maxDist))); }
private void UpdateLightWorldMatrix() { if (m_pointLight != null) { Matrix newMat = m_pointLocalMatrix * base.WorldMatrix; m_pointLight.SetPosition(newMat.Translation); m_pointLight.ReflectorDirection = newMat.Down; m_pointLight.ReflectorDirection = MyMwcUtils.Normalize(m_pointLight.ReflectorDirection); m_pointLight.ReflectorUp = newMat.Right; m_pointLight.ReflectorUp = MyMwcUtils.Normalize(m_pointLight.ReflectorUp); // move the light outwards in the direction of the lamp, for purposes of glare m_pointLight.SetPosition(m_pointLight.Position + 0.75f * m_pointLight.ReflectorDirection); } }
public static Vector3 LinearVector(ref Vector3 B, ref Vector3 A, float LastTime, float t) { Vector3 diffVector = A - B; float length = diffVector.Length(); if (diffVector.Length() < PREDICTION_MINIMAL_EPSILON) { return(A); } float lastSpeed = length / LastTime; float newLength = lastSpeed * t; diffVector = MyMwcUtils.Normalize(diffVector); diffVector = Vector3.Negate(diffVector); return(Vector3.Multiply(diffVector, newLength)); }
public void Draw() { Vector3 dir = MyMwcUtils.Normalize(MyCamera.Position - Position); float timeBlic = MyMinerGame.TotalGamePlayTimeInMilliseconds % TimerForBlic; if (timeBlic > BLIC_DURATON_IN_MILISECONDS) { timeBlic = TimerForBlic - timeBlic; } timeBlic = MathHelper.Clamp(1 - timeBlic / BLIC_DURATON_IN_MILISECONDS, 0, 1); float radius = MathHelper.Lerp(RadiusMin, RadiusMax, timeBlic); MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.ReflectorGlareAlphaBlended, Vector4.One, Position + dir, radius, 0); Light.Range = radius * 4; }
public void DoWork() { try { MyEntities.EntityCloseLock.AcquireShared(); if (m_bot == null) { return; } BoundingSphere boundingSphere = new BoundingSphere(m_position, m_bot.WorldVolume.Radius * 2.0f); if (MyEntities.GetIntersectionWithSphere(ref boundingSphere) != null) { return; } Matrix transform = Matrix.CreateWorld(m_position, MyMwcUtils.Normalize(m_targetPosition - m_position), m_up); float distanceToRoutePoint = Vector3.Dot(m_targetPosition - m_position, transform.Forward); for (int i = 0; i < m_points.Length; i++) { Vector3 transformedPoint = Vector3.Transform(m_points[i], transform); MyLine line = new MyLine(transformedPoint, transformedPoint + transform.Forward * distanceToRoutePoint, true); var result = MyEntities.GetIntersectionWithLine(ref line, m_bot, null, true); if (result.HasValue) { // Collision detected return; } } Result = m_position; } finally { if (m_bot != null) { m_bot.OnClose -= m_bot_OnClose; } MyEntities.EntityCloseLock.ReleaseShared(); } }
/// <summary> /// Draw occlusion bounding box method with our premade effect and box. /// </summary> /// <param name="bbox"></param> /// <param name="scale"></param> /// <param name="enableDepthTesting"></param> /// <param name="billboardLike">Indicates whether the occlusion object (box) is rotated to face the camera or not.</param> public static void DrawOcclusionBoundingBox(BoundingBox bbox, float scale, bool enableDepthTesting, bool billboardLike = false, bool useDepthTarget = true) { useDepthTarget &= !MyRenderConstants.RenderQualityProfile.ForwardRender; var cameraToBBox = bbox.GetCenter() - MyCamera.Position; Matrix worldMatrix = billboardLike ? Matrix.CreateWorld(Vector3.Zero, MyMwcUtils.Normalize(cameraToBBox), MyMwcUtils.Normalize(MyCamera.UpVector + MyCamera.LeftVector)) : Matrix.Identity; Vector3 scaleV = (bbox.Max - bbox.Min) * scale; worldMatrix *= Matrix.CreateScale(scaleV); worldMatrix.Translation = cameraToBBox; MyEffectOcclusionQueryDraw effectOQ = MyRender.GetEffect(MyEffects.OcclusionQueryDrawMRT) as MyEffectOcclusionQueryDraw; if (enableDepthTesting && !MyRenderConstants.RenderQualityProfile.ForwardRender) { effectOQ.SetTechnique(MyEffectOcclusionQueryDraw.Technique.DepthTestEnabled); } else { effectOQ.SetTechnique(MyEffectOcclusionQueryDraw.Technique.DepthTestDisabled); } effectOQ.SetWorldMatrix(worldMatrix); effectOQ.SetViewMatrix(MyCamera.ViewMatrixAtZero); effectOQ.SetProjectionMatrix(MyCamera.ProjectionMatrix); if (useDepthTarget) { var depthRenderTarget = MyRender.GetRenderTarget(MyRenderTargets.Depth); effectOQ.SetDepthRT(depthRenderTarget); effectOQ.SetScale(MyRender.GetScaleForViewport(depthRenderTarget)); } effectOQ.Begin(); //draw m_modelBoxLowRes.Render(); effectOQ.End(); }
public static void DrawTransparentPyramid(ref Vector3 start, ref MyQuad backQuad, ref Vector4 vctColor, int divideRatio, float thickness, MyTransparentMaterialEnum?lineMaterial = null) { Vector3 vctZero = Vector3.Zero; m_lineBuffer.Clear(); GenerateLines(start, backQuad.Point0, backQuad.Point1, ref m_lineBuffer, divideRatio); GenerateLines(start, backQuad.Point1, backQuad.Point2, ref m_lineBuffer, divideRatio); GenerateLines(start, backQuad.Point2, backQuad.Point3, ref m_lineBuffer, divideRatio); GenerateLines(start, backQuad.Point3, backQuad.Point0, ref m_lineBuffer, divideRatio); foreach (MyLine line in m_lineBuffer) { Vector3 dir = line.To - line.From; float len = dir.Length(); if (len > 0.1f) { dir = MyMwcUtils.Normalize(dir); MyTransparentGeometry.AddLineBillboard(lineMaterial ?? MyTransparentMaterialEnum.ProjectileTrailLine, vctColor, line.From, dir, len, thickness); } } }
public static void Draw() { if (MyFakes.TEST_MISSION_1_ENABLED) { if (m_remainingPrimaryTargetsCounter == 0) { if (m_russianDropZoneLight != null) { Vector3 dir = MyMwcUtils.Normalize(MyCamera.Position - RUSSIAN_DROP_ZONE_POSITION); float timeBlic = MyMinerGame.TotalGamePlayTimeInMilliseconds % 980; if (timeBlic > 250) { timeBlic = 980 - timeBlic; } timeBlic = MathHelper.Clamp(1 - timeBlic / 250, 0, 1); float alpha = MathHelper.Lerp(0.1f, 0.6f, timeBlic); m_dropZoneLightColor.W = alpha; m_russianDropZoneLight.Start(MyLight.LightTypeEnum.PointLight, RUSSIAN_DROP_ZONE_POSITION, m_dropZoneLightColor, 1, 200); float radius = MathHelper.Lerp(0.1f, 150f, timeBlic); MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.ReflectorGlareAlphaBlended, m_dropZoneLightColor, RUSSIAN_DROP_ZONE_POSITION + dir * 5, radius, 0); } else { m_russianDropZoneLight = MyLights.AddLight(); if (m_russianDropZoneLight != null) { m_russianDropZoneLight.Start(MyLight.LightTypeEnum.PointLight, 1); } } } } }
// AddPoint // if pt is less than Sqrt(combinationDistanceSq) from one of the // others the original is replaced with the mean of it // and pt, and false is returned. true means that pt was // added to pts private bool AddPoint(List <MyCP> pts, Vector3 pt, Vector3 normal, float depth, float combinationDistanceSq) { for (int i = pts.Count; i-- != 0;) { if (PointPointDistanceSq(pts[i].m_Position, pt) < combinationDistanceSq) { //pts[i] = 0.5f * (pts[i] + pt); return(false); } } MyCP cp = new MyCP(); cp.m_Normal = -normal; cp.m_Normal = MyMwcUtils.Normalize(cp.m_Normal); cp.m_Position = pt; cp.m_Depth = depth * 0.1f - 0.5f * MyPhysicsConfig.CollisionEpsilon; if (cp.m_Depth < -0.5f) { cp.m_Depth *= 0.5f; } pts.Add(cp); return(true); }
// Generate explosion particles. These will be smoke, explosion and some polyline particles. void GenerateExplosionParticles(MyParticleEffectsIDEnum newParticlesType, BoundingSphere explosionSphere, float particleScale) { Vector3 dirToCamera = MyCamera.Position - explosionSphere.Center; if (MyMwcUtils.IsZero(dirToCamera)) { dirToCamera = MyCamera.ForwardVector; } else { dirToCamera = MyMwcUtils.Normalize(dirToCamera); } // Move explosion particles in the direction of camera, so we won't see billboards intersecting the large ship BoundingSphere tempExplosionSphere = m_explosionSphere; tempExplosionSphere.Center = m_explosionSphere.Center + dirToCamera * 0.9f; MyParticleEffect explosionEffect = MyParticlesManager.CreateParticleEffect((int)newParticlesType); explosionEffect.WorldMatrix = Matrix.CreateTranslation(tempExplosionSphere.Center); explosionEffect.UserRadiusMultiplier = tempExplosionSphere.Radius; explosionEffect.UserScale = particleScale; }
// Draw the projectile but only if desired polyline trail distance can fit in the trajectory (otherwise we will see polyline growing from the origin and it's ugly). // Or draw if this is last draw of this projectile (useful for short-distance shots). public void Draw() { const float PROJECTILE_POLYLINE_DESIRED_LENGTH = 120; float trajectoryLength = Vector3.Distance(m_position, m_origin); if ((trajectoryLength > 0) || (m_state == MyProjectileStateEnum.KILLED)) { if (m_state == MyProjectileStateEnum.KILLED) { m_state = MyProjectileStateEnum.KILLED_AND_DRAWN; } if (!m_positionChecked) { return; } // If we calculate previous position using normalized direction (insted of velocity), projectile trails will // look like coming from cannon, and that is desired. Even during fast movement, acceleration, rotation or changes in movement directions. //Vector3 previousPosition = m_position - m_directionNormalized * projectileTrailLength * 1.05f; Vector3 previousPosition = m_position - m_directionNormalized * PROJECTILE_POLYLINE_DESIRED_LENGTH * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; //Vector3 previousPosition = m_previousPosition; //Vector3 previousPosition = m_initialSunWindPosition - MyMwcUtils.Normalize(m_desiredVelocity) * projectileTrailLength; Vector3 direction = Vector3.Normalize(m_position - previousPosition); float projectileTrailLength = 40 * LengthMultiplier;// PROJECTILE_POLYLINE_DESIRED_LENGTH; projectileTrailLength *= MyMwcUtils.GetRandomFloat(0.6f, 0.8f); if (trajectoryLength < projectileTrailLength) { projectileTrailLength = trajectoryLength; } previousPosition = m_position - projectileTrailLength * direction; if (m_externalAddition >= 1.0f) { m_externalAddition = 0.5f; } //float color = MyMwcUtils.GetRandomFloat(1, 2); float color = MyMwcUtils.GetRandomFloat(1, 2); float thickness = m_thicknessMultiplier * MyMwcUtils.GetRandomFloat(0.2f, 0.3f); // Line particles (polyline) don't look good in distance. Start and end aren't rounded anymore and they just // look like a pieces of paper. Especially when zoom-in. thickness *= MathHelper.Lerp(0.2f, 0.8f, MyCamera.Zoom.GetZoomLevel()); float alphaCone = 1; float alphaGlare = 1; if (BlendByCameraDirection) { float angle = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), direction)); alphaGlare = (float)Math.Pow(1 - angle, 2); alphaCone = (1 - (float)Math.Pow(1 - angle, 30)); } MyTransparentGeometry.AddLineBillboard(MyTransparentMaterialEnum.ProjectileTrailLine, new Vector4(m_ammoProperties.TrailColor * color, 1) * alphaCone, previousPosition, direction, projectileTrailLength, thickness); if (FrontBillboardMaterial.HasValue) { MyTransparentGeometry.AddPointBillboard(FrontBillboardMaterial.Value, new Vector4(m_ammoProperties.TrailColor * color, 1) * alphaGlare, m_position, 0.8f * FrontBillboardSize, 0); } } }
// Special method that loads data into GPU, and can be called only from Draw method, never from LoadContent or from background thread. // Because that would lead to empty vertex/index buffers if they are filled/created while game is minimized (remember the issue - alt-tab during loading screen) static void LoadInDraw() { if (m_loaded) { return; } // In fact it doesn't matter how large is cube, it will always look same as we are always in its middle // I changed it from 1.0 to 100.0 only because will small length I had problems with near frustum plane and crazy aspect ratios. const float CUBE_LENGTH_HALF = 100; Vector3 shapeSize = Vector3.One * CUBE_LENGTH_HALF; Vector3 shapePosition = Vector3.Zero; MyVertexFormatPositionTexture3[] boxVertices = new MyVertexFormatPositionTexture3[36]; Vector3 topLeftFront = shapePosition + new Vector3(-1.0f, 1.0f, -1.0f) * shapeSize; Vector3 bottomLeftFront = shapePosition + new Vector3(-1.0f, -1.0f, -1.0f) * shapeSize; Vector3 topRightFront = shapePosition + new Vector3(1.0f, 1.0f, -1.0f) * shapeSize; Vector3 bottomRightFront = shapePosition + new Vector3(1.0f, -1.0f, -1.0f) * shapeSize; Vector3 topLeftBack = shapePosition + new Vector3(-1.0f, 1.0f, 1.0f) * shapeSize; Vector3 topRightBack = shapePosition + new Vector3(1.0f, 1.0f, 1.0f) * shapeSize; Vector3 bottomLeftBack = shapePosition + new Vector3(-1.0f, -1.0f, 1.0f) * shapeSize; Vector3 bottomRightBack = shapePosition + new Vector3(1.0f, -1.0f, 1.0f) * shapeSize; Vector3 textureTopLeftFront = MyMwcUtils.Normalize(topLeftFront); Vector3 textureBottomLeftFront = MyMwcUtils.Normalize(bottomLeftFront); Vector3 textureTopRightFront = MyMwcUtils.Normalize(topRightFront); Vector3 textureBottomRightFront = MyMwcUtils.Normalize(bottomRightFront); Vector3 textureTopLeftBack = MyMwcUtils.Normalize(topLeftBack); Vector3 textureTopRightBack = MyMwcUtils.Normalize(topRightBack); Vector3 textureBottomLeftBack = MyMwcUtils.Normalize(bottomLeftBack); Vector3 textureBottomRightBack = MyMwcUtils.Normalize(bottomRightBack); textureTopLeftFront.Z *= -1; textureBottomLeftFront.Z *= -1; textureTopRightFront.Z *= -1; textureBottomRightFront.Z *= -1; textureTopLeftBack.Z *= -1; textureTopRightBack.Z *= -1; textureBottomLeftBack.Z *= -1; textureBottomRightBack.Z *= -1; // Front face. boxVertices[0] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront); boxVertices[1] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront); boxVertices[2] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront); boxVertices[3] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront); boxVertices[4] = new MyVertexFormatPositionTexture3(bottomRightFront, textureBottomRightFront); boxVertices[5] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront); // Back face. boxVertices[6] = new MyVertexFormatPositionTexture3(topLeftBack, textureTopLeftBack); boxVertices[7] = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack); boxVertices[8] = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack); boxVertices[9] = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack); boxVertices[10] = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack); boxVertices[11] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack); // Top face. boxVertices[12] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront); boxVertices[13] = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack); boxVertices[14] = new MyVertexFormatPositionTexture3(topLeftBack, textureTopLeftBack); boxVertices[15] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront); boxVertices[16] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront); boxVertices[17] = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack); // Bottom face. boxVertices[18] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront); boxVertices[19] = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack); boxVertices[20] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack); boxVertices[21] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront); boxVertices[22] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack); boxVertices[23] = new MyVertexFormatPositionTexture3(bottomRightFront, textureBottomRightFront); // Left face. boxVertices[24] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront); boxVertices[25] = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack); boxVertices[26] = new MyVertexFormatPositionTexture3(bottomLeftFront, textureBottomLeftFront); boxVertices[27] = new MyVertexFormatPositionTexture3(topLeftBack, textureTopLeftBack); boxVertices[28] = new MyVertexFormatPositionTexture3(bottomLeftBack, textureBottomLeftBack); boxVertices[29] = new MyVertexFormatPositionTexture3(topLeftFront, textureTopLeftFront); // Right face. boxVertices[30] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront); boxVertices[31] = new MyVertexFormatPositionTexture3(bottomRightFront, textureBottomRightFront); boxVertices[32] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack); boxVertices[33] = new MyVertexFormatPositionTexture3(topRightBack, textureTopRightBack); boxVertices[34] = new MyVertexFormatPositionTexture3(topRightFront, textureTopRightFront); boxVertices[35] = new MyVertexFormatPositionTexture3(bottomRightBack, textureBottomRightBack); // if we've loaded the cube from DDS, orient it towards the sun var sun = MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized(); var toSun = new Quaternion(Vector3.Cross(Vector3.UnitX, sun), Vector3.Dot(Vector3.UnitX, sun)); // default orientation is +x toSun.Normalize(); for (int i = 0; i < boxVertices.Length; i++) { boxVertices[i].Position = Vector3.Transform(boxVertices[i].Position, toSun); } m_boxVertexBuffer = new VertexBuffer(MyMinerGame.Static.GraphicsDevice, MyVertexFormatPositionTexture3.Stride * boxVertices.Length, Usage.WriteOnly, VertexFormat.None, Pool.Default); m_boxVertexBuffer.Lock(0, 0, LockFlags.None).WriteRange(boxVertices); m_boxVertexBuffer.Unlock(); m_boxVertexBuffer.DebugName = "BackgroundCube"; m_loaded = true; }
internal override void Update(MySmallShipBot bot) { base.Update(bot); if (bot.Leader != null) { if (ShouldFallAsleep(bot)) { bot.IsSleeping = true; return; } Vector3 leaderToBot = bot.GetPosition() - bot.Leader.GetPosition(); Vector3 formationPositionActual = bot.Leader.GetFormationPosition(bot); Vector3 botToFormationPosition = formationPositionActual - bot.GetPosition(); float leaderDistance = leaderToBot.Length(); float formationPositionDistance = botToFormationPosition.Length(); Vector3 flyTo; if (formationPositionDistance > MyMwcMathConstants.EPSILON_SQUARED && leaderDistance > MyMwcMathConstants.EPSILON) { float leaderFactor = MathHelper.Clamp(leaderDistance - 5, 0, 25) / 20; flyTo = (1.0f - leaderFactor) * leaderToBot / leaderDistance + leaderFactor * botToFormationPosition / formationPositionDistance; flyTo = MyMwcUtils.Normalize(flyTo); flyTo = bot.GetPosition() + flyTo * formationPositionDistance; // Update leader visibility if (visibilityCheckTimer <= 0) { MyLine line = new MyLine(bot.GetPosition(), formationPositionActual, true); leaderVisible = !MyEntities.GetIntersectionWithLine(ref line, bot, bot.Leader, true, ignoreSmallShips: true).HasValue; visibilityCheckTimer = 0.5f; } else { visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } } else { // Bot is on formation position flyTo = bot.GetPosition() + bot.WorldMatrix.Forward; leaderVisible = true; } if (leaderVisible) { bool afterburner = /*bot.Leader.IsAfterburnerOn() || */ formationPositionDistance > AFTERBURNER_DISTANCE; Vector3 lookTarget = formationPositionDistance < LOOK_DISTANCE ? formationPositionActual + bot.Leader.WorldMatrix.Forward * 5000 : formationPositionActual; float factor = MathHelper.Clamp(formationPositionDistance / 200, 0.5f, 1.0f); factor = factor * factor * factor; bot.Move(flyTo, lookTarget, bot.Leader.WorldMatrix.Up, afterburner, 1, 25, factor, slowRotation: true); checkTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; findSmallship.Init(bot); } else { if (leaderDistance > MIN_LEADER_DISTANCE) { findSmallship.Update(bot, bot.Leader); if (findSmallship.PathNotFound) { //We dont want our friends sleeping elsewhere // bot.IsSleeping = true; } } } } }
public static void Update() { //TODO: use only for profiling /* * long startTime; * MyWindowsAPIWrapper.QueryPerformanceCounter(out startTime); */ bool renderEnviromentMaps = MyRender.EnableLights && MyRender.EnableLightsRuntime && MyRender.EnableSun && (MyRender.EnableEnvironmentMapAmbient || MyRender.EnableEnvironmentMapReflection); if (!renderEnviromentMaps) { return; } if (BlendDistance > MainMapMaxDistance) { throw new InvalidOperationException("BlendDistance must be lower than MainMapMaxDistance"); } MyRender.RenderOcclusionsImmediatelly = true; Vector3 cameraPos = MyCamera.Position; if (MainMapPosition.HasValue && (cameraPos - MainMapPosition.Value).Length() > InstantRefreshDistance) { m_renderInstantly = true; } // Makes evironment camera pos 300m in front of real camera //cameraPos += Vector3.Normalize(MyCamera.ForwardVector) * 300 if (MainMapPosition == null) { LastUpdateTime = 0; MainMapPosition = cameraPos; m_environmentMapRendererMain.StartUpdate(MainMapPosition.Value, m_renderInstantly); m_renderInstantly = false; BlendFactor = 0.0f; } else { float mainMapDistance = (MainMapPosition.Value - cameraPos).Length(); // When behind blend distance if (mainMapDistance > BlendDistance) { // Create AuxMap if not created if (AuxMapPosition == null) { LastUpdateTime = 0; AuxMapPosition = cameraPos; m_environmentMapRendererAux.StartUpdate(AuxMapPosition.Value, m_renderInstantly); m_renderInstantly = false; } // Wait till rendering done before blending if (m_environmentMapRendererAux.IsDone()) { // Set proper blend factor BlendFactor = (mainMapDistance - BlendDistance) / (MainMapMaxDistance - BlendDistance); } } else if ((mainMapDistance + Hysteresis) < BlendDistance) { AuxMapPosition = null; } // If MainMap should not be even displayed...swap aux and main and display if (mainMapDistance > MainMapMaxDistance && m_environmentMapRendererAux.IsDone()) { var tmp = m_environmentMapRendererAux; m_environmentMapRendererAux = m_environmentMapRendererMain; m_environmentMapRendererMain = tmp; MainMapPosition = cameraPos + MyMwcUtils.Normalize(MainMapPosition.Value - cameraPos) * BlendDistance; AuxMapPosition = null; BlendFactor = 0.0f; } } m_environmentMapRendererMain.ContinueUpdate(); m_environmentMapRendererAux.ContinueUpdate(); MyRender.RenderOcclusionsImmediatelly = false; /* * long frq; * MyWindowsAPIWrapper.QueryPerformanceFrequency(out frq); * * long stopTime; * MyWindowsAPIWrapper.QueryPerformanceCounter(out stopTime); * * float updateTime = ((float)(stopTime - startTime)) / frq * 1000.0f; * if(updateTime > LastUpdateTime) * { * LastUpdateTime = updateTime; * } * */ }
private void UpdateParticlesLife() { int counter = 0; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-UpdateParticlesLife"); MyParticleGeneration inheritedGeneration = null; Vector3 previousParticlePosition = m_effect.WorldMatrix.Translation; float particlesToCreate = 0; m_AABB = m_AABB.CreateInvalid(); m_AABB = m_AABB.Include(ref previousParticlePosition); if (OnDie.GetValue <int>() != -1) { inheritedGeneration = GetInheritedGeneration(OnDie.GetValue <int>()); if (inheritedGeneration == null) { OnDie.SetValue(-1); } else { inheritedGeneration.IsInherited = true; particlesToCreate = inheritedGeneration.m_particlesToCreate; } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-Update01"); Vector3 previousTrail0 = previousParticlePosition; Vector3 previousTrail1 = previousParticlePosition; using (ParticlesLock.AcquireExclusiveUsing()) { while (counter < m_particles.Count) { float motionInheritance; MotionInheritance.GetInterpolatedValue(m_effect.GetElapsedTime(), out motionInheritance); MyAnimatedParticle particle = m_particles[counter]; if (motionInheritance > 0) { m_effect.CalculateDeltaMatrix = true; } if (particle.Update()) { if (motionInheritance > 0) { particle.AddMotionInheritance(ref motionInheritance, ref m_effect.DeltaMatrix); } if (counter == 0) { previousParticlePosition = particle.ActualPosition; previousTrail0 = particle.Quad.Point1; previousTrail1 = particle.Quad.Point2; particle.Quad.Point0 = particle.ActualPosition; particle.Quad.Point2 = particle.ActualPosition; } counter++; if (particle.Type == MyParticleTypeEnum.Trail) { if (particle.ActualPosition == previousParticlePosition) { particle.Quad.Point0 = particle.ActualPosition; particle.Quad.Point1 = particle.ActualPosition; particle.Quad.Point2 = particle.ActualPosition; particle.Quad.Point3 = particle.ActualPosition; } else { MyPolyLine polyLine = new MyPolyLine(); polyLine.Thickness = particle.Thickness; polyLine.Point0 = particle.ActualPosition; polyLine.Point1 = previousParticlePosition; Vector3 direction = polyLine.Point1 - polyLine.Point0; Vector3 normalizedDirection = MyMwcUtils.Normalize(polyLine.Point1 - polyLine.Point0); polyLine.Point1 = polyLine.Point0 + (polyLine.Point1 - polyLine.Point0); polyLine.LineDirectionNormalized = normalizedDirection; MyUtils.GetPolyLineQuad(out particle.Quad, ref polyLine); particle.Quad.Point0 = previousTrail0 + direction * 0.15f; particle.Quad.Point3 = previousTrail1 + direction * 0.15f; previousTrail0 = particle.Quad.Point1; previousTrail1 = particle.Quad.Point2; } } previousParticlePosition = particle.ActualPosition; m_AABB = m_AABB.Include(ref previousParticlePosition); particle.Flags = GetEffect().IsInFrustum ? particle.Flags | MyAnimatedParticle.ParticleFlags.IsInFrustum : particle.Flags & ~MyAnimatedParticle.ParticleFlags.IsInFrustum; continue; } if (inheritedGeneration != null) { inheritedGeneration.m_particlesToCreate = particlesToCreate; inheritedGeneration.EffectMatrix = Matrix.CreateWorld(particle.ActualPosition, Vector3.Normalize(particle.Velocity), Vector3.Cross(Vector3.Left, particle.Velocity)); inheritedGeneration.UpdateParticlesCreation(); } m_particles.Remove(particle); MyTransparentGeometry.DeallocateAnimatedParticle(particle); } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); }
// Update position, check collisions, etc. and draw if particle still lives. // Return false if particle dies/timeouts in this tick. public bool Draw(MyBillboard billboard) { MyTransparentGeometry.StartParticleProfilingBlock("Distance calculation"); // This time is scaled according to planned lifespan of the particle // Distance for sorting Vector3 campos = MyCamera.Position; Vector3.DistanceSquared(ref campos, ref m_actualPosition, out billboard.DistanceSquared); MyTransparentGeometry.EndParticleProfilingBlock(); // If distance to camera is really small don't draw it. if (billboard.DistanceSquared <= 1) { return(false); } MyTransparentGeometry.StartParticleProfilingBlock("Quad calculation"); MyTransparentGeometry.StartParticleProfilingBlock("actualRadius"); float actualRadius = 1; Radius.GetInterpolatedValue <float>(m_normalizedTime, out actualRadius); MyTransparentGeometry.EndParticleProfilingBlock(); billboard.ContainedBillboards.Clear(); billboard.Near = m_generation.GetEffect().Near; billboard.Lowres = m_generation.GetEffect().LowRes || MyRenderConstants.RenderQualityProfile.LowResParticles; float alpha = 1; if (Type == MyParticleTypeEnum.Point) { MyTransparentGeometry.StartParticleProfilingBlock("GetBillboardQuadRotated"); MyUtils.GetBillboardQuadRotated(billboard, ref m_actualPosition, actualRadius, m_actualAngle); MyTransparentGeometry.EndParticleProfilingBlock(); } else if (Type == MyParticleTypeEnum.Line) { if (MyMwcUtils.IsZero(Velocity.LengthSquared())) { Velocity = MyMwcUtils.GetRandomVector3Normalized(); } MyQuad quad = new MyQuad(); MyPolyLine polyLine = new MyPolyLine(); polyLine.LineDirectionNormalized = MyMwcUtils.Normalize(Velocity); if (m_actualAngle > 0) { polyLine.LineDirectionNormalized = Vector3.TransformNormal(polyLine.LineDirectionNormalized, Matrix.CreateRotationY(MathHelper.ToRadians(m_actualAngle))); } polyLine.Point0 = m_actualPosition; polyLine.Point1.X = m_actualPosition.X + polyLine.LineDirectionNormalized.X * actualRadius; polyLine.Point1.Y = m_actualPosition.Y + polyLine.LineDirectionNormalized.Y * actualRadius; polyLine.Point1.Z = m_actualPosition.Z + polyLine.LineDirectionNormalized.Z * actualRadius; if (m_actualAngle > 0) { //centerize polyLine.Point0.X = polyLine.Point0.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f; polyLine.Point0.Y = polyLine.Point0.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f; polyLine.Point0.Z = polyLine.Point0.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f; polyLine.Point1.X = polyLine.Point1.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f; polyLine.Point1.Y = polyLine.Point1.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f; polyLine.Point1.Z = polyLine.Point1.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f; } polyLine.Thickness = Thickness; MyUtils.GetPolyLineQuad(out quad, ref polyLine); if (this.m_generation.AlphaAnisotropic) { float angle = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), polyLine.LineDirectionNormalized)); float alphaCone = (float)Math.Pow(angle, 0.5f); alpha = alphaCone; } billboard.Position0 = quad.Point0; billboard.Position1 = quad.Point1; billboard.Position2 = quad.Point2; billboard.Position3 = quad.Point3; } else if (Type == MyParticleTypeEnum.Trail) { if (Quad.Point0 == Quad.Point2) //not moving particle { return(false); } if (Quad.Point1 == Quad.Point3) //not moving particle was previous one { return(false); } if (Quad.Point0 == Quad.Point3) //not moving particle was previous one { return(false); } billboard.Position0 = Quad.Point0; billboard.Position1 = Quad.Point1; billboard.Position2 = Quad.Point2; billboard.Position3 = Quad.Point3; //if (this.m_generation.AlphaAnisotropic) /* { //Trails are anisotropic by default (nobody wants them to see ugly) * Vector3 lineDir = Vector3.Normalize(Quad.Point1 - Quad.Point0); * float angle = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), lineDir)); * float alphaCone = (float)Math.Pow(angle, 0.3f); * alpha = alphaCone; * }*/ } else { throw new NotSupportedException(Type + " is not supported particle type"); } MyTransparentGeometry.EndParticleProfilingBlock(); MyTransparentGeometry.StartParticleProfilingBlock("Material calculation"); Vector4 color; Color.GetInterpolatedValue <Vector4>(m_normalizedTime, out color); int material1 = (int)MyTransparentMaterialEnum.Test; int material2 = (int)MyTransparentMaterialEnum.Test; float textureBlendRatio = 0; if ((Flags & ParticleFlags.BlendTextures) != 0) { float prevTime, nextTime, difference; Material.GetPreviousValue(m_normalizedTime, out material1, out prevTime); Material.GetNextValue(m_normalizedTime, out material2, out nextTime, out difference); if (prevTime != nextTime) { textureBlendRatio = (m_normalizedTime - prevTime) * difference; } } else { Material.GetInterpolatedValue <int>(m_normalizedTime, out material1); } MyTransparentGeometry.EndParticleProfilingBlock(); //This gets 0.44ms for 2000 particles MyTransparentGeometry.StartParticleProfilingBlock("billboard.Start"); billboard.MaterialEnum = (MyTransparentMaterialEnum)material1; billboard.BlendMaterial = (MyTransparentMaterialEnum)material2; billboard.BlendTextureRatio = textureBlendRatio; billboard.EnableColorize = false; billboard.Color = color * alpha * m_generation.GetEffect().UserColorMultiplier; MyTransparentGeometry.EndParticleProfilingBlock(); return(true); }
protected override bool Interact(bool staticCollision) { if (!staticCollision && GetRigidBody1().IsStatic() && GetRigidBody2().IsStatic()) { return(false); } MyRBBoxElement box = null; MyRBSphereElement sphere = null; if (RBElement1.GetElementType() == MyRBElementType.ET_BOX) { SwapElements(); } box = (MyRBBoxElement)RBElement2; sphere = (MyRBSphereElement)RBElement1; Matrix boxMatrix = box.GetGlobalTransformation(); Vector3 sphereCenter = sphere.GetGlobalTransformation().Translation; Matrix invBoxMatrix = Matrix.Invert(boxMatrix); Vector3 boxLocalsphereCenter = Vector3.Transform(sphereCenter, invBoxMatrix); bool penetration = false; Vector3 normal = new Vector3(); Vector3 closestPos = new Vector3(); uint customData = 0; box.GetClosestPoint(boxLocalsphereCenter, ref closestPos, ref normal, ref penetration, ref customData); closestPos = Vector3.Transform(closestPos, boxMatrix); normal = -Vector3.TransformNormal(normal, boxMatrix); normal = MyMwcUtils.Normalize(normal); float vLength = (sphereCenter - closestPos).Length(); if (staticCollision) { return(vLength > 0 && vLength < sphere.Radius); } else { float eps = MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon; float dt = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; Vector3 pointVelocity1 = new Vector3(); Vector3 pointVelocity2 = new Vector3(); GetRigidBody1().GetGlobalPointVelocity(ref closestPos, out pointVelocity1); GetRigidBody2().GetGlobalPointVelocity(ref closestPos, out pointVelocity2); float dynEps = 0; if (vLength >= eps) { float dot = Vector3.Dot(pointVelocity1 - pointVelocity2, normal) * dt; if (dot >= 0) { dynEps = dot; } } float radius = sphere.Radius; //Second part of condition commented due to 5968: Bug B - rocket passing through prefab //Does not seem to have any reason to be there if (vLength > 0 /*&& vLength < (radius + eps + dynEps)*/) { float error = vLength - (radius + 0.5f * eps); //error = System.Math.Min(error, eps); MySmallCollPointInfo[] collInfo = MyContactInfoCache.SCPIStackAlloc(); collInfo[0] = new MySmallCollPointInfo(closestPos - sphereCenter, closestPos - boxMatrix.Translation, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, normal, error, closestPos); MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collInfo, 1); MyContactInfoCache.FreeStackAlloc(collInfo); } } return(false); }