public static void Start() { Clear(); IsActive = true; startTime = MyMinerGame.TotalGamePlayTimeInMilliseconds; ambientSound = MyAudio.AddCue3D(MySoundCuesEnum.SfxSolarWind, MyCamera.Position + MyCamera.ForwardVector * MaxSoundDistance, Vector3.Forward, Vector3.Up, Vector3.Zero, 0); sphereCenter = MyCamera.Position + MyCamera.ForwardVector * 400; for (int i = 0; i < SmokeCount; i++) { Vector3 pos = sphereCenter + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, SmokeSphereRadius); var smokePart = new SmokeParticle { Angle = MyMwcUtils.GetRandomRadian(), Color = Vector4.Zero, AngularVelocity = MyMwcUtils.GetRandomFloat(-0.15f, 0.15f), Pos = pos, Velocity = MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 30f) }; smokeParticles.Add(smokePart); } }
// I used this method only when we didn't have real persistant sectors... for fly-through animations List <MyVoxelMapImpostor> CreateFakeImpostors() { List <MyVoxelMapImpostor> ret = new List <MyVoxelMapImpostor>(ImpostorProperties.ImpostorsCount); for (int i = 0; i < ImpostorProperties.ImpostorsCount; i++) { Vector3 sectorCenter = Vector3.Zero; float randomDistance = MyMwcUtils.GetRandomFloat(ImpostorProperties.MinDistance, ImpostorProperties.MaxDistance); Vector3 randomPositionWithinSector = MyMwcUtils.GetRandomVector3Normalized() * randomDistance; float radius = MyMwcUtils.GetRandomFloat(ImpostorProperties.MinRadius, ImpostorProperties.MaxRadius); Vector3 position = sectorCenter + randomPositionWithinSector; float angle = MyMwcUtils.GetRandomRadian(); ret.Add(new MyVoxelMapImpostor(position, radius, angle)); } // Sort by distance (back-to-front) so alpha won't make problems on overlapping quads ret.Sort(); return(ret); }
public void Start(Vector3 position, float scale, MyMwcVoxelMaterialsEnum voxelMaterial, MyGroupMask groupMask, bool explosionType) { base.Start(position, scale, groupMask, explosionType); if (explosionType) { //apply random rotation impulse base.Physics.AngularVelocity = new Vector3(MyMwcUtils.GetRandomRadian(), MyMwcUtils.GetRandomRadian(), MyMwcUtils.GetRandomRadian()) * 0.7f; if (base.Physics.AngularVelocity.Length() == 0) { Debug.Assert(false); } if (!Physics.Enabled) { Physics.Enabled = true; } } else { if (Physics.Enabled) { Physics.Enabled = false; } } VoxelMaterial = voxelMaterial; InitDrawTechniques(); RenderObjects[0].NeedsResolveCastShadow = true; RenderObjects[0].FastCastShadowResolve = true; }
protected override void Start(Vector3 position, float scale, MyGroupMask groupMask, bool explosionType) { base.Start(position, scale, groupMask, explosionType); //apply random rotation impulse Physics.AngularVelocity = new Vector3(MyMwcUtils.GetRandomRadian(), MyMwcUtils.GetRandomRadian(), MyMwcUtils.GetRandomRadian()); Physics.Enabled = true; InitDrawTechniques(); }
public MyGuiControlRotatingWheel(IMyGuiControlsParent parent, Vector2 position, Vector4 color, float scale, MyGuiDrawAlignEnum align, MyTexture2D texture) : base(parent, position, null, null, null, false) { m_rotatingAngle = MyMwcUtils.GetRandomRadian(); m_color = color; m_wheelScale = scale; //m_scale = 4; m_align = align; m_texture = texture; }
public static void Draw() { if (!IsActive) { return; } // main smoke foreach (SmokeParticle part in smokeParticles) { MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.Smoke, part.Color, part.Pos, 900, part.Angle, 0, true); } float darkeningPhase; float dt; GetDarkeningPhase(out darkeningPhase, out dt); // small pieces of debris if (darkeningPhase > 0.2) { var color = new Vector4(1, 1, 1, darkeningPhase); for (int i = 0; i < 100; i++) { Vector3 pos = MyCamera.Position + GetRandomVector3CircleNormalizedFixed(MyCamera.ForwardVector) * MyMwcUtils.GetRandomFloat(0, 500) + MyCamera.ForwardVector * 20; MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.particle_stone, color, pos, MyMwcUtils.GetRandomFloat(0.008f, 0.05f), MyMwcUtils.GetRandomRadian()); } for (int i = 0; i < 100; i++) { Vector3 pos = MyCamera.Position + GetRandomVector3CircleNormalizedFixed(MyCamera.ForwardVector) * MyMwcUtils.GetRandomFloat(0, 500) + MyCamera.ForwardVector * 20; MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.Sparks_b, color, pos, MyMwcUtils.GetRandomFloat(0.008f, 0.05f), MyMwcUtils.GetRandomRadian()); } } // storm aftersparks foreach (ElectricStorm storm in storms) { MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.Sparks_a, new Vector4(1f, 1f, 1f, 1f), storm.Position + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 50), MyMwcUtils.GetRandomFloat(10, 20), MyMwcUtils.GetRandomRadian()); } }
public override void Init(StringBuilder hudLabelText, MySmallShip parentObject, Vector3 position, Vector3 forwardVector, Vector3 upVector, MyMwcObjectBuilder_SmallShip_Weapon objectBuilder) { base.Init(hudLabelText, MyModelsEnum.Autocannon_Base, MyMaterialType.METAL, parentObject, position, forwardVector, upVector, objectBuilder); m_rotationAngle = MyMwcUtils.GetRandomRadian(); m_lastTimeShoot = MyConstants.FAREST_TIME_IN_PAST; m_smokeLastTime = MyConstants.FAREST_TIME_IN_PAST; m_smokesToGenerate = 0; m_cannonMotorEndPlayed = true; m_rotationTimeout = (float)MyAutocanonConstants.ROTATION_TIMEOUT + MyMwcUtils.GetRandomFloat(-500, +500); m_barrelMatrix = ModelLod0.Dummies["BARREL_POSITION"].Matrix; m_barrel = new MyAutocannonBarrel(); m_barrel.Init(null, m_barrelMatrix, this); }
// IMPORTANT: This class isn't realy inicialized by constructor, but by Start() // So don't initialize members here, do it in Start() public virtual void Init(MyModelsEnum modelLod0Enum, MyModelsEnum?modelLod1Enum, MyMaterialType materialType, float scale, List <MyRBElementDesc> collisionPrimitives, float mass) { MyPhysicsObjects physobj = MyPhysics.physicsSystem.GetPhysicsObjects(); base.Init(null, modelLod0Enum, modelLod1Enum, null, scale, null); m_maxLifeTimeInMiliseconds = MyMwcUtils.GetRandomInt(MyExplosionsConstants.EXPLOSION_DEBRIS_LIVING_MIN_IN_MILISECONDS, MyExplosionsConstants.EXPLOSION_DEBRIS_LIVING_MAX_IN_MILISECONDS); m_randomizedDiffuseTextureColorMultiplier = MyMwcUtils.GetRandomFloat(0.4f, 0.6f); m_initialOrientation = Matrix.CreateRotationX(MyMwcUtils.GetRandomRadian()) * Matrix.CreateRotationY(MyMwcUtils.GetRandomRadian()) * Matrix.CreateRotationZ(MyMwcUtils.GetRandomRadian()); // create physics this.Physics = new MyPhysicsBody(this, mass, 0) { MaterialType = materialType }; for (int i = 0; i < collisionPrimitives.Count; i++) { MyRBSphereElement sphereEl = (MyRBSphereElement)physobj.CreateRBElement(collisionPrimitives[i]); // sphereEl.Radius *= scale; this.Physics.AddElement(sphereEl, true); } }
// Update position, check collisions, etc. // Return false if projectile dies/timeouts in this tick. public bool Update() { // Projectile was killed , but still not last time drawn, so we don't need to do update (we are waiting for last draw) if (m_state == MyProjectileStateEnum.KILLED) { return(true); } // Projectile was killed and last time drawn, so we can finally remove it from buffer if (m_state == MyProjectileStateEnum.KILLED_AND_DRAWN) { if (m_trailEffect != null) { // stop the trail effect m_trailEffect.Stop(); m_trailEffect = null; } return(false); } Vector3 position = m_position; m_position += m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; m_velocity = m_externalVelocity * m_externalAddition + m_directionNormalized * m_speed; if (m_externalAddition < 1.0f) { m_externalAddition *= 0.5f; } // Distance timeout float trajectoryLength = Vector3.Distance(m_position, m_origin); if (trajectoryLength >= m_maxTrajectory) { if (m_trailEffect != null) { // stop the trail effect m_trailEffect.Stop(); m_trailEffect = null; } m_state = MyProjectileStateEnum.KILLED; return(true); } if (m_trailEffect != null) { m_trailEffect.WorldMatrix = Matrix.CreateTranslation(m_position); } m_checkIntersectionIndex++; m_checkIntersectionIndex = m_checkIntersectionIndex % CHECK_INTERSECTION_INTERVAL; //check only each n-th intersection if (m_checkIntersectionIndex != 0) { return(true); } // Calculate hit point, create decal and throw debris particles Vector3 lineEndPosition = position + CHECK_INTERSECTION_INTERVAL * (m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS); MyLine line = new MyLine(m_positionChecked ? position : m_origin, lineEndPosition, true); m_positionChecked = true; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyEntities.GetIntersectionWithLine()"); MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, m_ignorePhysObject, null, false); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MyEntity physObject = intersection != null ? intersection.Value.Entity : null; if (physObject != null) { while (physObject.Physics == null && physObject.Parent != null) { physObject = physObject.Parent; } } if ((intersection != null) && (physObject != null) && (physObject.Physics.CollisionLayer != MyConstants.COLLISION_LAYER_UNCOLLIDABLE) && m_ignorePhysObject != physObject) { MyIntersectionResultLineTriangleEx intersectionValue = intersection.Value; bool isPlayerShip = MySession.PlayerShip == physObject; MyMaterialType materialType = isPlayerShip ? MyMaterialType.PLAYERSHIP : physObject.Physics.MaterialType; //material properties MyMaterialTypeProperties materialProperties = MyMaterialsConstants.GetMaterialProperties(materialType); bool isProjectileGroupKilled = false; if (m_sharedGroup != null) { isProjectileGroupKilled = m_sharedGroup.Killed; m_sharedGroup.Killed = true; } if (!isProjectileGroupKilled) { // Play bullet hit cue MyAudio.AddCue3D(m_ammoProperties.IsExplosive ? materialProperties.ExpBulletHitCue : materialProperties.BulletHitCue, intersectionValue.IntersectionPointInWorldSpace, Vector3.Zero, Vector3.Zero, Vector3.Zero); } float decalAngle = MyMwcUtils.GetRandomRadian(); // If we hit the glass of a miner ship, we need to create special bullet hole decals // drawn from inside the cockpit and change phys object so rest of the code will think we hit the parent // IMPORTANT: Intersection between projectile and glass is calculated only for mining ship in which player sits. So for enemies this will be never calculated. if (intersection.Value.Entity is MyCockpitGlassEntity) { if (!isProjectileGroupKilled) { MyCockpitGlassDecalTexturesEnum bulletHoleDecalTexture; float bulletHoleDecalSize; if (MyMwcUtils.GetRandomBool(3)) { bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleOnGlass; bulletHoleDecalSize = 0.25f; } else { bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleSmallOnGlass; bulletHoleDecalSize = 0.1f; } // Place bullet hole decal on player's cockpit glass (seen from inside the ship) MyCockpitGlassDecals.Add(bulletHoleDecalTexture, bulletHoleDecalSize, decalAngle, 1.0f, ref intersectionValue, false); // Create hit particles throwed into the cockpit (it's simulation of broken glass particles) // IMPORTANT: This particles will be relative to miner ship, so we create them in object space coordinates and update them by object WorldMatrix every time we draw them //MyParticleEffects.CreateHitParticlesGlass(ref intersectionValue.IntersectionPointInObjectSpace, ref intersectionValue.NormalInWorldSpace, ref line.Direction, physObject.Parent); } } // If this was "mine", it must explode else if (physObject is MyMineBase) { m_state = MyProjectileStateEnum.KILLED; if (!IsDummy) { (physObject as MyAmmoBase).Explode(); } return(true); } // If this was missile, cannon shot, it must explode if it is not mine missile else if (physObject is MyAmmoBase) { if (((MyAmmoBase)physObject).OwnerEntity == m_ignorePhysObject) { m_state = MyProjectileStateEnum.KILLED; if (!IsDummy) { (physObject as MyAmmoBase).Explode(); } return(true); } } else if (this.OwnerEntity is MySmallShip && (MySmallShip)this.OwnerEntity == MySession.PlayerShip && physObject is MyStaticAsteroid && !physObject.IsDestructible) { if (this.m_ammoProperties.IsExplosive || (this.m_ammoProperties.AmmoType == MyAmmoType.Explosive && this.m_weapon is Weapons.MyShotGun)) { HUD.MyHud.ShowIndestructableAsteroidNotification(); } } else if (!isProjectileGroupKilled && !isPlayerShip) { // Create smoke and debris particle at the place of voxel/model hit m_ammoProperties.OnHitParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, m_weapon, OwnerEntity); MySurfaceImpactEnum surfaceImpact; if (intersectionValue.Entity is MyVoxelMap) { var voxelMap = intersectionValue.Entity as MyVoxelMap; var voxelCoord = voxelMap.GetVoxelCenterCoordinateFromMeters(ref intersectionValue.IntersectionPointInWorldSpace); var material = voxelMap.GetVoxelMaterial(ref voxelCoord); if (material == MyMwcVoxelMaterialsEnum.Indestructible_01 || material == MyMwcVoxelMaterialsEnum.Indestructible_02 || material == MyMwcVoxelMaterialsEnum.Indestructible_03 || material == MyMwcVoxelMaterialsEnum.Indestructible_04 || material == MyMwcVoxelMaterialsEnum.Indestructible_05_Craters_01) { surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE; } else { surfaceImpact = MySurfaceImpactEnum.DESTRUCTIBLE; } } else if (intersectionValue.Entity is MyStaticAsteroid) { surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE; } else { surfaceImpact = MySurfaceImpactEnum.METAL; } m_ammoProperties.OnHitMaterialSpecificParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, surfaceImpact, m_weapon); } if (!(physObject is MyExplosionDebrisBase) && physObject != MySession.PlayerShip) { // Decal size depends on material. But for mining ship create smaller decal as original size looks to large on the ship. float decalSize = MyMwcUtils.GetRandomFloat(materialProperties.BulletHoleSizeMin, materialProperties.BulletHoleSizeMax); // Place bullet hole decal float randomColor = MyMwcUtils.GetRandomFloat(0.5f, 1.0f); MyDecals.Add( materialProperties.BulletHoleDecal, decalSize, decalAngle, new Vector4(randomColor, randomColor, randomColor, 1), false, ref intersectionValue, 0.0f, m_ammoProperties.DecalEmissivity, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL); } if (!(physObject is MyVoxelMap) && !IsDummy) { ApplyProjectileForce(physObject, intersectionValue.IntersectionPointInWorldSpace, m_directionNormalized, isPlayerShip); } // If this object is miner ship, then shake his head little bit if (physObject is MySmallShip && !IsDummy) { MySmallShip minerShip = (MySmallShip)physObject; minerShip.IncreaseHeadShake(MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_AFTER_PROJECTILE_HIT); } //Handle damage MyEntity damagedObject = intersectionValue.Entity; // not a very nice way to damage actual prefab associated with the large ship weapon (if MyPrefabLargeWeapon is reworked, it might change) if (damagedObject is MyLargeShipBarrelBase) { damagedObject = damagedObject.Parent; } if (damagedObject is MyLargeShipGunBase) { MyLargeShipGunBase physObj = damagedObject as MyLargeShipGunBase; if (physObj.PrefabParent != null) { damagedObject = physObj.PrefabParent; } } // Decrease health of stricken object if (!IsDummy) { damagedObject.DoDamage(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_ammoProperties.DamageType, m_ammoProperties.AmmoType, m_ignorePhysObject); if (MyMultiplayerGameplay.IsRunning) { var ammo = MyAmmoConstants.FindAmmo(m_ammoProperties); MyMultiplayerGameplay.Static.ProjectileHit(damagedObject, intersectionValue.IntersectionPointInWorldSpace, this.m_directionNormalized, ammo, this.OwnerEntity); } } if (m_trailEffect != null) { // stop the trail effect m_trailEffect.Stop(); m_trailEffect = null; } // Kill this projectile (set the position to intersection point, so we draw trail polyline only up to this point) m_position = intersectionValue.IntersectionPointInWorldSpace; m_state = MyProjectileStateEnum.KILLED; return(true); } return(true); }
public static void Update() { // Update only if sun wind is active if (IsActive == false) { return; } float darkeningPhase; float dt; int relTime = GetDarkeningPhase(out darkeningPhase, out dt); if (relTime > MaxTimeMs) { Clear(); return; } MyAudio.UpdateCuePosition(ambientSound, MyCamera.Position + MyCamera.ForwardVector * -MaxSoundDistance * (1 - darkeningPhase), MyCamera.ForwardVector, MyCamera.UpVector, Vector3.Zero); MyAudio.UpdateCueVolume(ambientSound, darkeningPhase * MaxAmbientVolume); // update smoke foreach (SmokeParticle part in smokeParticles) { Vector3 toCamera = (MyCamera.Position - part.Pos); toCamera.Normalize(); float alpha = darkeningPhase * MaxSmokeAlpha; part.Color = new Vector4(alpha, alpha, alpha, alpha); //part.Color.W = darkeningPhase; part.Pos += part.Velocity * dt + toCamera * CenterBias * dt; part.Angle += part.AngularVelocity * dt; } // remove old ice and sparks m_iceList.Clear(); foreach (IceParticle particle in iceParticles) { if (particle.StartTime + 4000 < relTime) { m_iceList.Add(particle); } } foreach (IceParticle ice in m_iceList) { ice.AsteroidEntity.MarkForClose(); Debug.Assert(ice.TrailEffect != null, "ice.TrailEffect != null"); ice.TrailEffect.Stop(); ice.TrailEffect = null; StopCue(ice.Sound); iceParticles.Remove(ice); } int c = 0; while (c < storms.Count) { ElectricStorm storm = storms[c]; if (storm.StartTime + 1500 < relTime) { storms.RemoveAt(c); continue; } c++; } // if its dark add new sparks and ice balls if (darkeningPhase >= 1) { if (storms.Count < MaxSparkCount && MyMwcUtils.GetRandomInt(SparkEveryMs) < dt * 1000.0f) { var storm = new ElectricStorm { Position = MyCamera.Position + MyCamera.ForwardVector * 250 + MyMwcUtils.GetRandomVector3HemisphereNormalized(MyCamera.ForwardVector) * MyMwcUtils.GetRandomFloat(0, 300), StartTime = relTime, Effect = MyParticlesManager.CreateParticleEffect( (int)MyParticleEffectsIDEnum.Damage_Sparks), }; storm.Effect.WorldMatrix = Matrix.CreateTranslation(storm.Position); storm.Effect.AutoDelete = true; storm.Effect.UserScale = 2; storm.Sound = MyAudio.AddCue2D(MySoundCuesEnum.SfxSpark); storms.Add(storm); } if (iceParticles.Count < MaxIceCount && MyMwcUtils.GetRandomInt(IceEveryMs) < dt * 1000.0f) { Vector3 dir = MyMwcUtils.GetRandomVector3HemisphereNormalized(MyCamera.ForwardVector); Vector3 pos = MyCamera.Position + MyCamera.ForwardVector * 250 + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 200) + dir * MyMwcUtils.GetRandomFloat(0, 500); MyMwcObjectBuilder_StaticAsteroid rockModel = MySectorGenerator.GenerateStaticAsteroid(MyMwcUtils.GetRandomFloat(0.1f, 2f), MyStaticAsteroidTypeSetEnum.A, MyMwcVoxelMaterialsEnum.Ice_01, pos, random, asteroidTypes); Matrix matrix = Matrix.CreateFromAxisAngle(MyMwcUtils.GetRandomVector3Normalized(), MyMwcUtils.GetRandomFloat(0, MathHelper.Pi)); matrix.Translation = pos; MyEntity asteroid = MyEntities.CreateFromObjectBuilderAndAdd(null, rockModel, matrix); asteroid.Physics.Enabled = false; asteroid.CastShadows = false; MyParticleEffect effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_CannonShot); Vector3 velocity = -dir *MyMwcUtils.GetRandomInt(150, 400); iceParticles.Add(new IceParticle { StartTime = relTime, Position = pos, Direction = -dir, AsteroidEntity = asteroid, TrailEffect = effect, RotAxis = MyMwcUtils.GetRandomVector3Normalized(), RotAngle = MyMwcUtils.GetRandomRadian(), AngularVelocity = MyMwcUtils.GetRandomFloat(0.2f, 10f), Velocity = velocity, Sound = MyAudio.AddCue3D(MySoundCuesEnum.WepSniperHighFire2d, pos, dir, dir * -dir, velocity) }); } } // update ice parts foreach (IceParticle particle in iceParticles) { particle.RotAngle += particle.AngularVelocity * dt; particle.Position += particle.Velocity * dt; Matrix matrix = Matrix.CreateFromAxisAngle(particle.RotAxis, particle.RotAngle); matrix.Translation = particle.Position; particle.AsteroidEntity.SetWorldMatrix(matrix); Matrix trans = Matrix.CreateTranslation(-particle.Direction * 10); particle.TrailEffect.WorldMatrix = matrix * trans; MyAudio.UpdateCuePosition(particle.Sound, particle.Position, particle.Direction, particle.Direction * -particle.Direction, particle.Velocity); } lastUpdateMs = MyMinerGame.TotalGamePlayTimeInMilliseconds; }
// 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); } }
private void CreateDecals(Vector3 direction) { MyRender.GetRenderProfiler().StartProfilingBlock("Collisions"); MyRender.GetRenderProfiler().StartProfilingBlock("Raycast"); var intersectionEndPoint = m_explosionSphere.Center + 1.5f * m_explosionSphere.Radius * direction; var intersectionStartPoint = m_explosionSphere.Center - 1.5f * m_explosionSphere.Radius * direction; var line = new MyLine(intersectionStartPoint, intersectionEndPoint); var result = MyEntities.GetIntersectionWithLine(ref line, null, null, true, true, false, false, true, AppCode.Physics.Collisions.IntersectionFlags.ALL_TRIANGLES, true); MyRender.GetRenderProfiler().EndProfilingBlock(); MyRender.GetRenderProfiler().StartProfilingBlock("Add decal"); if (result.HasValue) { MyIntersectionResultLineTriangleEx intersection = result.Value; var radius = m_explosionSphere.Radius * (result.Value.Entity is MyVoxelMap ? 1.0f : MyMwcUtils.GetRandomFloat(0.4f, 0.6f)); MyDecals.Add( MyDecalTexturesEnum.ExplosionSmut, radius, MyMwcUtils.GetRandomRadian(), GetSmutDecalRandomColor(), true, ref intersection, 0, 0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL_FOR_SMUT_DECALS); } MyRender.GetRenderProfiler().EndProfilingBlock(); MyRender.GetRenderProfiler().EndProfilingBlock(); //var elements = MyEntities.GetElementsInBox(ref boundingBox); //foreach (MyRBElement element in elements) //{ // var rigidBody = (MyPhysicsBody)element.GetRigidBody().m_UserData; // var entity = rigidBody.Entity; // if (entity is MyExplosionDebrisBase || entity is MyPrefabContainer) // continue; // // Making interesection of line from the explosion center to every object closed to explosion // // and placing smut decals // // FIX : when hitting another samll boat explosion and entity position are equal !!! // //if (m_explosionSphere.Center == entity.GetPosition()) // // continue; // // FIX : when hitting another samll boat explosion and direction is < Epsilon !!! // if ((entity.GetPosition() - m_explosionSphere.Center).LengthSquared() < // 2 * MyMwcMathConstants.EPSILON_SQUARED) // continue; // MyRender.GetRenderProfiler().StartProfilingBlock("Line intersection"); // MyIntersectionResultLineTriangleEx? intersection = null; // if (direction.HasValue) // { // var intersectionEndPoint = m_explosionSphere.Center + 1.5f * m_explosionSphere.Radius * direction.Value; // var intersectionStartPoint = m_explosionSphere.Center - 1.5f * m_explosionSphere.Radius * direction.Value; // MyLine intersectionLine = new MyLine(intersectionStartPoint, intersectionEndPoint, true); // entity.GetIntersectionWithLine(ref intersectionLine, out intersection); // } // else if (intersection == null && entity is MyVoxelMap) // { // // fall back if we dont have direction // var intersectionEndPoint = entity.GetPosition(); // MyLine intersectionLine = new MyLine(m_explosionSphere.Center, intersectionEndPoint, true); // entity.GetIntersectionWithLine(ref intersectionLine, out intersection); // } // MyRender.GetRenderProfiler().EndProfilingBlock(); // if (intersection == null) // continue; // MyIntersectionResultLineTriangleEx intersectionValue = intersection.Value; // if (entity is MyVoxelMap) // { // MyRender.GetRenderProfiler().StartProfilingBlock("Decals"); // MyDecals.Add( // MyDecalTexturesEnum.ExplosionSmut, // m_explosionSphere.Radius, // MyMwcUtils.GetRandomRadian(), // GetSmutDecalRandomColor(), // true, // ref intersectionValue, // 0, // 0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL_FOR_SMUT_DECALS); // MyRender.GetRenderProfiler().EndProfilingBlock(); // } // else if (((entity is MySmallShip) == false) && // ((entity is MySmallDebris) == false) // && ((entity is MyAmmoBase) == false)) // { // // Create explosion smut decal on model we hit by this missile // MyDecals.Add( // MyDecalTexturesEnum.ExplosionSmut, // MyMwcUtils.GetRandomFloat(m_explosionSphere.Radius * 0.4f, m_explosionSphere.Radius * 0.6f), // MyMwcUtils.GetRandomRadian(), // GetSmutDecalRandomColor(), // true, // ref intersectionValue, // 0, // 0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL); // } //} //elements.Clear(); }
public static void LoadContent() { MyMwcLog.WriteLine("MySunWind.LoadContent() - START"); MyMwcLog.IncreaseIndent(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MySunwind::LoadContent"); // Large billboards m_largeBillboards = new MySunWindBillboard[MySunWindConstants.LARGE_BILLBOARDS_SIZE.X][]; for (int x = 0; x < MySunWindConstants.LARGE_BILLBOARDS_SIZE.X; x++) { m_largeBillboards[x] = new MySunWindBillboard[MySunWindConstants.LARGE_BILLBOARDS_SIZE.Y]; for (int y = 0; y < MySunWindConstants.LARGE_BILLBOARDS_SIZE.Y; y++) { m_largeBillboards[x][y] = new MySunWindBillboard(); MySunWindBillboard billboard = m_largeBillboards[x][y]; billboard.Radius = MyMwcUtils.GetRandomFloat(MySunWindConstants.LARGE_BILLBOARD_RADIUS_MIN, MySunWindConstants.LARGE_BILLBOARD_RADIUS_MAX); billboard.InitialAngle = MyMwcUtils.GetRandomRadian(); billboard.RotationSpeed = MyMwcUtils.GetRandomSign() * MyMwcUtils.GetRandomFloat(MySunWindConstants.LARGE_BILLBOARD_ROTATION_SPEED_MIN, MySunWindConstants.LARGE_BILLBOARD_ROTATION_SPEED_MAX); //billboard.Color = MySunWindConstants.BILLBOARD_COLOR; //billboard.Color.X = MyMwcUtils.GetRandomFloat(0.5f, 3); //billboard.Color.Y = MyMwcUtils.GetRandomFloat(0.5f, 2); //billboard.Color.Z = MyMwcUtils.GetRandomFloat(0.5f, 2); //billboard.Color.W = MyMwcUtils.GetRandomFloat(0.5f, 2); billboard.Color.X = MyMwcUtils.GetRandomFloat(0.5f, 3); billboard.Color.Y = MyMwcUtils.GetRandomFloat(0.5f, 1); billboard.Color.Z = MyMwcUtils.GetRandomFloat(0.5f, 1); billboard.Color.W = MyMwcUtils.GetRandomFloat(0.5f, 1); } } // Small billboards m_smallBillboards = new MySunWindBillboardSmall[MySunWindConstants.SMALL_BILLBOARDS_SIZE.X][]; for (int x = 0; x < MySunWindConstants.SMALL_BILLBOARDS_SIZE.X; x++) { m_smallBillboards[x] = new MySunWindBillboardSmall[MySunWindConstants.SMALL_BILLBOARDS_SIZE.Y]; for (int y = 0; y < MySunWindConstants.SMALL_BILLBOARDS_SIZE.Y; y++) { m_smallBillboards[x][y] = new MySunWindBillboardSmall(); MySunWindBillboardSmall billboard = m_smallBillboards[x][y]; billboard.Radius = MyMwcUtils.GetRandomFloat(MySunWindConstants.SMALL_BILLBOARD_RADIUS_MIN, MySunWindConstants.SMALL_BILLBOARD_RADIUS_MAX); billboard.InitialAngle = MyMwcUtils.GetRandomRadian(); billboard.RotationSpeed = MyMwcUtils.GetRandomSign() * MyMwcUtils.GetRandomFloat(MySunWindConstants.SMALL_BILLBOARD_ROTATION_SPEED_MIN, MySunWindConstants.SMALL_BILLBOARD_ROTATION_SPEED_MAX); //billboard.Color = MySunWindConstants.BILLBOARD_COLOR; billboard.Color.X = MyMwcUtils.GetRandomFloat(0.5f, 1); billboard.Color.Y = MyMwcUtils.GetRandomFloat(0.2f, 0.5f); billboard.Color.Z = MyMwcUtils.GetRandomFloat(0.2f, 0.5f); billboard.Color.W = MyMwcUtils.GetRandomFloat(0.1f, 0.5f); billboard.TailBillboardsCount = MyMwcUtils.GetRandomInt(MySunWindConstants.SMALL_BILLBOARD_TAIL_COUNT_MIN, MySunWindConstants.SMALL_BILLBOARD_TAIL_COUNT_MAX); billboard.TailBillboardsDistance = MyMwcUtils.GetRandomFloat(MySunWindConstants.SMALL_BILLBOARD_TAIL_DISTANCE_MIN, MySunWindConstants.SMALL_BILLBOARD_TAIL_DISTANCE_MAX); billboard.RadiusScales = new float[billboard.TailBillboardsCount]; for (int i = 0; i < billboard.TailBillboardsCount; i++) { billboard.RadiusScales[i] = MyMwcUtils.GetRandomFloat(0.7f, 1.0f); } } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MyMwcLog.DecreaseIndent(); MyMwcLog.WriteLine("MySunWind.LoadContent() - END"); }
public static void CreateExplosionDebris(ref BoundingSphere explosionSphere, float voxelsCountInPercent, MyMwcVoxelMaterialsEnum voxelMaterial, MyGroupMask groupMask, MyVoxelMap voxelMap) { MyCommonDebugUtils.AssertDebug((voxelsCountInPercent >= 0.0f) && (voxelsCountInPercent <= 1.0f)); MyCommonDebugUtils.AssertDebug(explosionSphere.Radius > 0); Render.MyRender.GetRenderProfiler().StartProfilingBlock("CreateExplosionDebris"); Render.MyRender.GetRenderProfiler().StartProfilingBlock("Matrices"); // This matrix will rotate all newly created debrises, so they won't apper as alligned with coordinate system Matrix randomRotationMatrix = Matrix.CreateRotationX(MyMwcUtils.GetRandomRadian()) * Matrix.CreateRotationY(MyMwcUtils.GetRandomRadian()); float highScale = MathHelper.Clamp(explosionSphere.Radius * DebrisScaleUpper, 0, DebrisScaleClamp); float lowScale = highScale * (DebrisScaleLower / DebrisScaleUpper); int objectsToGenerate = (int)(m_positionOffsets.Count * voxelsCountInPercent * MyRenderConstants.RenderQualityProfile.ExplosionDebrisCountMultiplier); long dbgObjectsGenerated = 0; Render.MyRender.GetRenderProfiler().EndProfilingBlock(); Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_positionOffsets"); for (int i = 0; i < m_positionOffsets.Count; i++) { // IMPORTANT: If you place explosion debris exactly in the center of an explosion, JLX will fail or end in endless loop // Probably it's because it can't handle external force acting from inside the object. if (dbgObjectsGenerated >= objectsToGenerate) { break; } const float cubeInsideSphereMod = 1 / 1.73f; // Resize sphere to fit inside cube Vector3 position = m_positionOffsets[i] * explosionSphere.Radius * cubeInsideSphereMod; Vector3.Transform(ref position, ref randomRotationMatrix, out position); position += explosionSphere.Center; MyExplosionDebrisVoxel newObj = Allocate(); if (newObj != null) { // Check if new object won't intersect any existing triangle - because if yes, then it will decrease JLX performace a lot float randomNewScale = MyMwcUtils.GetRandomFloat(lowScale, highScale); BoundingSphere sphere = new BoundingSphere(position, newObj.m_modelLod0.BoundingSphere.Radius * randomNewScale); Render.MyRender.GetRenderProfiler().StartProfilingBlock("GetIntersectionWithSphere"); //This takes 4-5ms, is it necessary? // if (MyEntities.GetIntersectionWithSphere(ref sphere) == null) //if (false) { Render.MyRender.GetRenderProfiler().StartProfilingBlock("newObj.Start"); newObj.Start(position, randomNewScale, voxelMaterial, groupMask, true); MyEntities.Add(newObj); Render.MyRender.GetRenderProfiler().EndProfilingBlock(); /* * Vector3 imp = position - explosionSphere.Center; * imp.Normalize(); * imp *= MyExplosionsConstants.EXPLOSION_STRENGTH_IMPULSE; * * newObj.Physics.AddForce(PhysicsManager.Physics.MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, imp, explosionSphere.Center, Vector3.Zero); */ if (MinerWars.AppCode.Game.Explosions.MyExplosion.DEBUG_EXPLOSIONS) { m_debugVoxelSpheres.Add(sphere); } dbgObjectsGenerated++; } //else { // Put back to object pool //newObj.Close(); } Render.MyRender.GetRenderProfiler().EndProfilingBlock(); //if (newObj.Physics.Enabled) // newObj.Physics.Enabled = false; // newObj.Physics.CollisionLayer = MyConstants.COLLISION_LAYER_UNCOLLIDABLE; } } Render.MyRender.GetRenderProfiler().EndProfilingBlock(); Render.MyRender.GetRenderProfiler().EndProfilingBlock(); }