/// <summary> /// Only for some testing values /// </summary> public void InitDefault() { Birth.AddKey(0, 1.0f); Life.AddKey(0, 10.0f); Thickness.AddKey(0, 1.0f); Velocity.AddKey(0, new Vector3(0, 1, 0)); MyAnimatedPropertyVector4 colorKey = new MyAnimatedPropertyVector4(Color.Name); colorKey.AddKey(0, new Vector4(1, 0, 0, 1)); colorKey.AddKey(1, new Vector4(0, 0, 1, 1)); Color.AddKey(0, colorKey); MyAnimatedPropertyFloat radiusKey = new MyAnimatedPropertyFloat(Radius.Name); radiusKey.AddKey(0, 1.0f); Radius.AddKey(0, radiusKey); MyAnimatedPropertyTransparentMaterial materialKey = new MyAnimatedPropertyTransparentMaterial(Material.Name); materialKey.AddKey(0, MyTransparentMaterials.GetMaterial("Smoke")); Material.AddKey(0, materialKey); LODBirth.AddKey(0, 1.0f); LODRadius.AddKey(0, 1.0f); UseLayerSorting.SetValue(false); SortLayer.SetValue(-1); }
public void InitDefault() { Birth.AddKey(0, 1.0f); Life.AddKey(0, 10.0f); Thickness.AddKey(0, 1.0f); Velocity.AddKey(0, new Vector3(0, 1, 0)); MyAnimatedPropertyVector4 colorKey = new MyAnimatedPropertyVector4(Color.Name); colorKey.AddKey(0, new Vector4(1, 0, 0, 1)); colorKey.AddKey(1, new Vector4(0, 0, 1, 1)); Color.AddKey(0, colorKey); MyAnimatedPropertyFloat radiusKey = new MyAnimatedPropertyFloat(Radius.Name); radiusKey.AddKey(0, 1.0f); Radius.AddKey(0, radiusKey); MyAnimatedPropertyTransparentMaterial materialKey = new MyAnimatedPropertyTransparentMaterial(Material.Name); materialKey.AddKey(0, MyTransparentMaterials.GetMaterial("Smoke")); Material.AddKey(0, materialKey); LODBirth.AddKey(0, 1.0f); LODBirth.AddKey(MyConstants.MAX_PARTICLE_DISTANCE_DEFAULT, 0f); LODRadius.AddKey(0, 1.0f); PivotDistVar.SetValue(1.0f); AccelerationVar.SetValue(0.0f); UseLayerSorting.SetValue(false); SortLayer.SetValue(-1); }
public void InitDefault() { ArraySize.SetValue(Vector3.One); ArrayModulo.SetValue(1); var colorAnim = new MyAnimatedPropertyVector4(); colorAnim.AddKey(0, Vector4.One); colorAnim.AddKey(0.33f, Vector4.One); colorAnim.AddKey(0.66f, Vector4.One); colorAnim.AddKey(1, Vector4.One); Color.AddKey(0, colorAnim); var colorIntensityAnim = new MyAnimatedPropertyFloat(); colorIntensityAnim.AddKey(0, 1.0f); colorIntensityAnim.AddKey(0.33f, 1.0f); colorIntensityAnim.AddKey(0.66f, 1.0f); colorIntensityAnim.AddKey(1, 1.0f); ColorIntensity.AddKey(0, colorIntensityAnim); Offset.SetValue(new Vector3(0, 0, 0)); Direction.SetValue(new Vector3(0, 0, -1)); var radiusAnim = new MyAnimatedPropertyFloat(); radiusAnim.AddKey(0, 0.1f); radiusAnim.AddKey(0.33f, 0.1f); radiusAnim.AddKey(0.66f, 0.1f); radiusAnim.AddKey(1, 0.1f); Radius.AddKey(0, radiusAnim); Life.SetValue(1); StreakMultiplier.SetValue(4); AnimationFrameTime.SetValue(1); Enabled.SetValue(true); EmitterSize.AddKey(0, new Vector3(0.0f, 0.0f, 0.0f)); EmitterSizeMin.AddKey(0, 0.0f); DirectionCone.AddKey(0, 0.0f); DirectionConeVar.AddKey(0, 0.0f); Velocity.AddKey(0, 1.0f); VelocityVar.AddKey(0, 0.0f); ParticlesPerSecond.AddKey(0, 1000.0f); Material.SetValue(MyTransparentMaterials.GetMaterial("WhiteBlock")); SoftParticleDistanceScale.SetValue(1); Bounciness.SetValue(0.5f); ColorVar.SetValue(0); HueVar.SetValue(0); OITWeightFactor.SetValue(1f); TargetCoverage.SetValue(1f); }
// This method is like a constructor (which we can't use because billboards are allocated from a pool). // It starts/initializes a billboard. Refs used only for optimalization public static void CreateBillboard(VRageRender.MyBillboard billboard, ref MyQuadD quad, string material, ref Vector4 color, ref Vector3D origin, Vector2 uvOffset, int customViewProjection = -1, float reflectivity = 0) { System.Diagnostics.Debug.Assert(material != null); if (string.IsNullOrEmpty(material) || !MyTransparentMaterials.ContainsMaterial(material)) { material = "ErrorMaterial"; color = Vector4.One; } billboard.Material = material; MyUtils.AssertIsValid(quad.Point0); MyUtils.AssertIsValid(quad.Point1); MyUtils.AssertIsValid(quad.Point2); MyUtils.AssertIsValid(quad.Point3); // Billboard vertices billboard.Position0 = quad.Point0; billboard.Position1 = quad.Point1; billboard.Position2 = quad.Point2; billboard.Position3 = quad.Point3; billboard.UVOffset = uvOffset; billboard.UVSize = Vector2.One; // Distance for sorting // IMPORTANT: Must be calculated before we do color and alpha misting, because we need distance there Vector3D cameraPosition = customViewProjection == -1 ? MyTransparentGeometry.Camera.Translation : VRageRender.MyRenderProxy.BillboardsViewProjectionWrite[customViewProjection].CameraPosition; billboard.DistanceSquared = (float)Vector3D.DistanceSquared(cameraPosition, origin); // Color billboard.Color = color; billboard.ColorIntensity = 1; billboard.Reflectivity = reflectivity; billboard.CustomViewProjection = customViewProjection; billboard.ParentID = -1; billboard.SoftParticleDistanceScale = 1; // Alpha depends on distance to camera. Very close bilboards are more transparent, so player won't see billboard errors or rotating billboards var mat = MyTransparentMaterials.GetMaterial(billboard.Material); if (mat.AlphaMistingEnable) { billboard.Color *= MathHelper.Clamp(((float)Math.Sqrt(billboard.DistanceSquared) - mat.AlphaMistingStart) / (mat.AlphaMistingEnd - mat.AlphaMistingStart), 0, 1); } billboard.Color *= mat.Color; }
public static void AddTriangleBillboard( Vector3 p0, Vector3 p1, Vector3 p2, Vector3 n0, Vector3 n1, Vector3 n2, Vector2 uv0, Vector2 uv1, Vector2 uv2, string material, int parentID, Vector3 worldPosition, int priority = 0, bool colorize = false, bool window = true) { VRageRender.MyTriangleBillboard billboard = VRageRender.MyRenderProxy.TriangleBillboardsPoolWrite.Allocate(); if (billboard == null) { return; } var materialInstance = MyTransparentMaterials.GetMaterial(material); billboard.Window = window; billboard.Position0 = p0; billboard.Position1 = p1; billboard.Position2 = p2; billboard.Position3 = p0; billboard.UV0 = uv0; billboard.UV1 = uv1; billboard.UV2 = uv2; billboard.Normal0 = n0; billboard.Normal1 = n1; billboard.Normal2 = n2; billboard.Near = false; billboard.Lowres = false; billboard.DistanceSquared = (float)Vector3D.DistanceSquared(MyTransparentGeometry.Camera.Translation, worldPosition); billboard.Material = material; billboard.Color = materialInstance.Color; Debug.Assert(materialInstance.Color.W != 0); billboard.ColorIntensity = 1; billboard.Priority = priority; billboard.EnableColorize = colorize; billboard.CustomViewProjection = -1; billboard.Reflectivity = materialInstance.Reflectivity; billboard.ParentID = parentID; VRageRender.MyRenderProxy.AddBillboard(billboard); }
public MyGlassMaterial GetGlassMaterial(string materialName) { MyRenderProxy.Assert(!string.IsNullOrEmpty(materialName)); if (!m_glassMaterials.ContainsKey(materialName)) { MyTransparentMaterial oldTransparentMaterial = MyTransparentMaterials.GetMaterial(materialName); string textureFilepath = oldTransparentMaterial.Texture; Vector4 color = oldTransparentMaterial.Color; float reflectivity = oldTransparentMaterial.Reflectivity; MyGlassMaterial glassMaterial = new MyGlassMaterial(materialName, textureFilepath, color, reflectivity); m_glassMaterials.Add(materialName, glassMaterial); } return(m_glassMaterials[materialName]); }
public void DeserializeKeys(List <AnimationKey> keys, string type) { m_keys.Clear(); foreach (var key in keys) { object v; switch (type) { case "Float": v = key.ValueFloat; break; case "Vector3": v = key.ValueVector3; break; case "Vector4": v = key.ValueVector4; break; default: case "Enum": case "GenerationIndex": case "Int": v = key.ValueInt; break; case "Bool": v = key.ValueBool; break; case "MyTransparentMaterial": v = MyTransparentMaterials.GetMaterial(key.ValueString); break; case "String": v = key.ValueString; break; } AddKey <T>(key.Time, (T)v); } }
public virtual void DeserializeFromObjectBuilder(GenerationProperty property) { m_name = property.Name; object v; switch (property.Type) { case "Float": v = property.ValueFloat; break; case "Vector3": v = property.ValueVector3; break; case "Vector4": v = property.ValueVector4; break; default: case "Int": v = property.ValueInt; break; case "Bool": v = property.ValueBool; break; case "String": v = property.ValueString; break; case "MyTransparentMaterial": v = MyTransparentMaterials.GetMaterial(property.ValueString); break; } m_value = (T)v; }
public void InitDefault() { ArraySize.SetValue(Vector3.One); ArrayModulo.SetValue(1); var colorAnim = new MyAnimatedPropertyVector4(); colorAnim.AddKey(0, Vector4.One); colorAnim.AddKey(0.33f, Vector4.One); colorAnim.AddKey(0.66f, Vector4.One); colorAnim.AddKey(1, Vector4.One); Color.AddKey(0, colorAnim); Velocity.SetValue(new Vector3(0, 0, -1)); var radiusAnim = new MyAnimatedPropertyFloat(); radiusAnim.AddKey(0, 0.1f); radiusAnim.AddKey(0.33f, 0.1f); radiusAnim.AddKey(0.66f, 0.1f); radiusAnim.AddKey(1, 0.1f); Radius.AddKey(0, radiusAnim); Life.SetValue(1); StreakMultiplier.SetValue(4); AnimationFrameTime.SetValue(1); Enabled.SetValue(true); ParticlesPerSecond.SetValue(30000); Material.SetValue(MyTransparentMaterials.GetMaterial("WhiteBlock")); SoftParticleDistanceScale.SetValue(1); Bounciness.SetValue(0.5f); OITWeightFactor.SetValue(1f); }
// Update position, check collisions, etc. and draw if particle still lives. // Return false if particle dies/timeouts in this tick. public bool Draw(VRageRender.MyBillboard billboard) { if (Pivot != null) { if (PivotRotation != null) { Matrix pivotRotationTransform = Matrix.CreateRotationX(MathHelper.ToRadians(m_actualPivotRotation.X) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS) * Matrix.CreateRotationY(MathHelper.ToRadians(m_actualPivotRotation.Y) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS) * Matrix.CreateRotationZ(MathHelper.ToRadians(m_actualPivotRotation.Z) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); m_actualPivot = Vector3.TransformNormal(m_actualPivot, pivotRotationTransform); } m_actualPivot = Vector3D.TransformNormal(m_actualPivot, m_generation.GetEffect().WorldMatrix); } var actualPosition = m_actualPosition + m_actualPivot; MyTransparentGeometry.StartParticleProfilingBlock("Distance calculation"); // This time is scaled according to planned lifespan of the particle // Distance for sorting billboard.DistanceSquared = (float)Vector3D.DistanceSquared(MyTransparentGeometry.Camera.Translation, actualPosition); MyTransparentGeometry.EndParticleProfilingBlock(); // If distance to camera is really small don't draw it. if (billboard.DistanceSquared <= 0.1f) { return(false); } MyTransparentGeometry.StartParticleProfilingBlock("Quad calculation"); MyTransparentGeometry.StartParticleProfilingBlock("actualRadius"); float actualRadius = 1; Radius.GetInterpolatedValue <float>(m_normalizedTime, out actualRadius); MyTransparentGeometry.EndParticleProfilingBlock(); float actualAlphaCutout = 0; if (AlphaCutout != null) { MyTransparentGeometry.StartParticleProfilingBlock("AlphaCutout calculation"); AlphaCutout.GetInterpolatedValue <float>(m_normalizedTime, out actualAlphaCutout); MyTransparentGeometry.EndParticleProfilingBlock(); } billboard.ContainedBillboards.Clear(); billboard.Near = m_generation.GetEffect().Near; billboard.Lowres = m_generation.GetEffect().LowRes || VRageRender.MyRenderConstants.RenderQualityProfile.LowResParticles; billboard.CustomViewProjection = -1; billboard.ParentID = -1; billboard.AlphaCutout = actualAlphaCutout; billboard.UVOffset = Vector2.Zero; billboard.UVSize = Vector2.One; float alpha = 1; Matrix transform = Matrix.Identity; Vector3 normal = Vector3.Forward; Vector3 actualVelocity = (Vector3)(m_actualPosition - m_previousPosition); float radiusBySpeed = m_generation.RadiusBySpeed; if (radiusBySpeed > 0) { float actualSpeed = actualVelocity.Length(); actualRadius = Math.Max(actualRadius, actualRadius * m_generation.RadiusBySpeed * actualSpeed); } if (Type == MyParticleTypeEnum.Point) { MyTransparentGeometry.StartParticleProfilingBlock("GetBillboardQuadRotated"); Vector2 actualRadiusV2 = new Vector2(actualRadius, actualRadius); if (Thickness > 0) { actualRadiusV2.Y = Thickness; } if (m_generation.RotationReference == MyRotationReference.Camera) { transform = Matrix.CreateFromAxisAngle(MyTransparentGeometry.Camera.Right, m_actualAngle.X) * Matrix.CreateFromAxisAngle(MyTransparentGeometry.Camera.Up, m_actualAngle.Y) * Matrix.CreateFromAxisAngle(MyTransparentGeometry.Camera.Forward, m_actualAngle.Z); GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, MyTransparentGeometry.Camera.Left, MyTransparentGeometry.Camera.Up); } else if (m_generation.RotationReference == MyRotationReference.Local) { transform = Matrix.CreateFromAxisAngle(m_generation.GetEffect().WorldMatrix.Right, m_actualAngle.X) * Matrix.CreateFromAxisAngle(m_generation.GetEffect().WorldMatrix.Up, m_actualAngle.Y) * Matrix.CreateFromAxisAngle(m_generation.GetEffect().WorldMatrix.Forward, m_actualAngle.Z); GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, m_generation.GetEffect().WorldMatrix.Left, m_generation.GetEffect().WorldMatrix.Up); } else if (m_generation.RotationReference == MyRotationReference.Velocity) { if (actualVelocity.LengthSquared() < 0.00001f) { return(false); } Matrix velocityRef = Matrix.CreateFromDir(Vector3.Normalize(actualVelocity)); transform = Matrix.CreateFromAxisAngle(velocityRef.Right, m_actualAngle.X) * Matrix.CreateFromAxisAngle(velocityRef.Up, m_actualAngle.Y) * Matrix.CreateFromAxisAngle(velocityRef.Forward, m_actualAngle.Z); GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, velocityRef.Left, velocityRef.Up); } else if (m_generation.RotationReference == MyRotationReference.VelocityAndCamera) { if (actualVelocity.LengthSquared() < 0.0001f) { return(false); } Vector3 cameraToPoint = Vector3.Normalize(m_actualPosition - MyTransparentGeometry.Camera.Translation); Vector3 velocityDir = Vector3.Normalize(actualVelocity); Vector3 sideVector = Vector3.Cross(cameraToPoint, velocityDir); Vector3 upVector = Vector3.Cross(sideVector, velocityDir); Matrix velocityRef = Matrix.CreateWorld(m_actualPosition, velocityDir, upVector); transform = Matrix.CreateFromAxisAngle(velocityRef.Right, m_actualAngle.X) * Matrix.CreateFromAxisAngle(velocityRef.Up, m_actualAngle.Y) * Matrix.CreateFromAxisAngle(velocityRef.Forward, m_actualAngle.Z); GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, velocityRef.Left, velocityRef.Up); } else if (m_generation.RotationReference == MyRotationReference.LocalAndCamera) { Vector3 cameraToPoint = Vector3.Normalize(m_actualPosition - MyTransparentGeometry.Camera.Translation); Vector3 localDir = m_generation.GetEffect().WorldMatrix.Forward; Vector3 sideVector = Vector3.Cross(cameraToPoint, localDir); Vector3 upVector = Vector3.Cross(sideVector, localDir); Matrix velocityRef = Matrix.CreateWorld(m_actualPosition, localDir, upVector); transform = Matrix.CreateFromAxisAngle(velocityRef.Right, m_actualAngle.X) * Matrix.CreateFromAxisAngle(velocityRef.Up, m_actualAngle.Y) * Matrix.CreateFromAxisAngle(velocityRef.Forward, m_actualAngle.Z); GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, velocityRef.Left, velocityRef.Up); } else { System.Diagnostics.Debug.Fail("Unknown RotationReference enum"); } MyTransparentGeometry.EndParticleProfilingBlock(); } else if (Type == MyParticleTypeEnum.Line) { if (MyUtils.IsZero(Velocity.LengthSquared())) { Velocity = MyUtils.GetRandomVector3Normalized(); } MyQuadD quad = new MyQuadD(); MyPolyLineD polyLine = new MyPolyLineD(); //polyLine.LineDirectionNormalized = MyUtils.Normalize(Velocity); if (actualVelocity.LengthSquared() > 0) { polyLine.LineDirectionNormalized = MyUtils.Normalize(actualVelocity); } else { polyLine.LineDirectionNormalized = MyUtils.Normalize(Velocity); } if (m_actualAngle.Z != 0) { polyLine.LineDirectionNormalized = Vector3.TransformNormal(polyLine.LineDirectionNormalized, Matrix.CreateRotationY(m_actualAngle.Z)); } polyLine.Point0 = actualPosition; polyLine.Point1.X = actualPosition.X - polyLine.LineDirectionNormalized.X * actualRadius; polyLine.Point1.Y = actualPosition.Y - polyLine.LineDirectionNormalized.Y * actualRadius; polyLine.Point1.Z = actualPosition.Z - polyLine.LineDirectionNormalized.Z * actualRadius; if (m_actualAngle.LengthSquared() > 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; var camPos = MyTransparentGeometry.Camera.Translation; MyUtils.GetPolyLineQuad(out quad, ref polyLine, camPos); transform.Forward = polyLine.LineDirectionNormalized; 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; } else { throw new NotSupportedException(Type + " is not supported particle type"); } if (this.m_generation.AlphaAnisotropic) { normal = Vector3.Normalize(Vector3.Cross(billboard.Position0 - billboard.Position1, billboard.Position0 - billboard.Position2)); Vector3 forward = (billboard.Position0 + billboard.Position1 + billboard.Position2 + billboard.Position3) / 4 - MyTransparentGeometry.Camera.Translation; //Vector3 forward = MyTransparentGeometry.Camera.Forward; float angle = Math.Abs(Vector3.Dot(MyUtils.Normalize(forward), normal)); float alphaCone = 1 - (float)Math.Pow(1 - angle, 4); alpha = alphaCone; } MyTransparentGeometry.EndParticleProfilingBlock(); MyTransparentGeometry.StartParticleProfilingBlock("Material calculation"); Vector4 color = Vector4.One; if (Color.GetKeysCount() > 0) { Color.GetInterpolatedValue <Vector4>(m_normalizedTime, out color); } if (m_arrayIndex != -1) { Vector3 arraySize = m_generation.ArraySize; if (arraySize.X > 0 && arraySize.Y > 0) { int arrayOffset = m_generation.ArrayOffset; int arrayModulo = m_generation.ArrayModulo == 0 ? (int)arraySize.X * (int)arraySize.Y : m_generation.ArrayModulo; m_arrayIndex = m_arrayIndex % arrayModulo + arrayOffset; float xDiv = 1.0f / arraySize.X; float yDiv = 1.0f / arraySize.Y; int xIndex = m_arrayIndex % (int)arraySize.X; int yIndex = m_arrayIndex / (int)arraySize.X; billboard.UVOffset = new Vector2(xDiv * xIndex, yDiv * yIndex); billboard.UVSize = new Vector2(xDiv, yDiv); } } var material1 = MyTransparentMaterials.GetMaterial("ErrorMaterial"); var material2 = MyTransparentMaterials.GetMaterial("ErrorMaterial"); 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(m_normalizedTime, out material1); } MyTransparentGeometry.EndParticleProfilingBlock(); //This gets 0.44ms for 2000 particles MyTransparentGeometry.StartParticleProfilingBlock("billboard.Start"); if (material1 != null) { billboard.Material = material1.Name; } billboard.BlendMaterial = material2.Name; billboard.BlendTextureRatio = textureBlendRatio; billboard.EnableColorize = false; billboard.Color = color * alpha * m_generation.GetEffect().UserColorMultiplier; billboard.ColorIntensity = ColorIntensity; MyTransparentGeometry.EndParticleProfilingBlock(); return(true); }
// Update position, check collisions, etc. and draw if particle still lives. // Return false if particle dies/timeouts in this tick. public bool Draw(VRageRender.MyBillboard billboard) { MyTransparentGeometry.StartParticleProfilingBlock("Distance calculation"); // This time is scaled according to planned lifespan of the particle // Distance for sorting billboard.DistanceSquared = (float)Vector3D.DistanceSquared(MyTransparentGeometry.Camera.Translation, m_actualPosition); MyTransparentGeometry.EndParticleProfilingBlock(); // If distance to camera is really small don't draw it. if (billboard.DistanceSquared <= 0.1f) { 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 || VRageRender.MyRenderConstants.RenderQualityProfile.LowResParticles; billboard.CustomViewProjection = -1; billboard.ParentID = -1; float alpha = 1; if (Type == MyParticleTypeEnum.Point) { MyTransparentGeometry.StartParticleProfilingBlock("GetBillboardQuadRotated"); GetBillboardQuadRotated(billboard, ref m_actualPosition, actualRadius, m_actualAngle); MyTransparentGeometry.EndParticleProfilingBlock(); } else if (Type == MyParticleTypeEnum.Line) { if (MyUtils.IsZero(Velocity.LengthSquared())) { Velocity = MyUtils.GetRandomVector3Normalized(); } MyQuadD quad = new MyQuadD(); MyPolyLineD polyLine = new MyPolyLineD(); polyLine.LineDirectionNormalized = MyUtils.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; var camPos = MyTransparentGeometry.Camera.Translation; MyUtils.GetPolyLineQuad(out quad, ref polyLine, camPos); if (this.m_generation.AlphaAnisotropic) { float angle = 1 - Math.Abs(Vector3.Dot(MyUtils.Normalize(MyTransparentGeometry.Camera.Forward), 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); var material1 = MyTransparentMaterials.GetMaterial("ErrorMaterial"); var material2 = MyTransparentMaterials.GetMaterial("ErrorMaterial"); 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(m_normalizedTime, out material1); } MyTransparentGeometry.EndParticleProfilingBlock(); //This gets 0.44ms for 2000 particles MyTransparentGeometry.StartParticleProfilingBlock("billboard.Start"); billboard.Material = material1.Name; billboard.BlendMaterial = material2.Name; billboard.BlendTextureRatio = textureBlendRatio; billboard.EnableColorize = false; billboard.Color = color * alpha * m_generation.GetEffect().UserColorMultiplier; MyTransparentGeometry.EndParticleProfilingBlock(); return(true); }
public override void DeserializeValue(XmlReader reader, out object value) { base.DeserializeValue(reader, out value); value = MyTransparentMaterials.GetMaterial((string)value); }
public bool Read(BinaryReader reader, int version) { Textures.Clear(); UserData.Clear(); MaterialName = reader.ReadString(); if (String.IsNullOrEmpty(MaterialName)) { MaterialName = null; } if (version < 1052002) { var diffuseTextureName = reader.ReadString(); if (!string.IsNullOrEmpty(diffuseTextureName)) { Textures.Add("DiffuseTexture", diffuseTextureName); } var normalsTextureName = reader.ReadString(); if (!string.IsNullOrEmpty(normalsTextureName)) { Textures.Add("NormalTexture", normalsTextureName); } } else { int texturesCount = reader.ReadInt32(); for (int i = 0; i < texturesCount; i++) { var textureName = reader.ReadString(); var texturePath = reader.ReadString(); Textures.Add(textureName, texturePath); } } if (version >= 1068001) // 01068001 { int userDataCount = reader.ReadInt32(); for (int i = 0; i < userDataCount; i++) { var name = reader.ReadString(); var data = reader.ReadString(); UserData.Add(name, data); } } if (version < 1157001) { reader.ReadSingle(); //SpecularPower reader.ReadSingle(); //DiffuseColor.X reader.ReadSingle(); //DiffuseColor.Y reader.ReadSingle(); //DiffuseColor.Z reader.ReadSingle(); //ExtraData.X reader.ReadSingle(); //ExtraData.Y reader.ReadSingle(); //ExtraData.Z } if (version < 1052001) { Technique = ((MyMeshDrawTechnique)reader.ReadInt32()).ToString(); } else { Technique = reader.ReadString(); } if (Technique == "GLASS") { if (version >= 1043001) { GlassCW = reader.ReadString(); GlassCCW = reader.ReadString(); GlassSmoothNormals = reader.ReadBoolean(); // Partial backwards compatibility for old mods if (!string.IsNullOrEmpty(GlassCCW) && !MyTransparentMaterials.ContainsMaterial(MaterialName) && // Can be removed when all our materials are fixed MyTransparentMaterials.ContainsMaterial(GlassCCW)) // Can be removed when all our materials are fixed { MaterialName = GlassCCW; } } else { reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); GlassCW = "GlassCW"; GlassCCW = "GlassCCW"; GlassSmoothNormals = false; } } return(true); }