public static void SimulateParticleAging(PartSysEmitter emitter, float timeToSimulateSec) { var it = emitter.NewIterator(); var ages = emitter.GetParticles(); while (it.HasNext()) { var particleIdx = it.Next(); ages[particleIdx] += timeToSimulateSec; } emitter.PruneExpiredParticles(); }
private void RenderParticles(PartSysEmitter emitter) { var it = emitter.NewIterator(); var totalCount = emitter.GetActiveCount(); if (totalCount == 0) { return; } // Lazily initialize render state if (!emitter.HasRenderState()) { emitter.SetRenderState( new QuadEmitterRenderState(_device, emitter)); } var renderState = (QuadEmitterRenderState)emitter.GetRenderState(); using var spriteMemory = MemoryPool.Rent(4 * totalCount); var sUpdateBuffer = spriteMemory.Memory.Span.Slice(0, 4 * totalCount); var i = 0; while (it.HasNext()) { var particleIdx = it.Next(); FillVertex(emitter, particleIdx, sUpdateBuffer, i); i += 4; } renderState.vertexBuffer.Resource.Update <SpriteVertex>(sUpdateBuffer); _device.SetMaterial(renderState.material); renderState.bufferBinding.Resource.Bind(); // Draw the batch _device.DrawIndexed(PrimitiveType.TriangleList, 4 * totalCount, 6 * totalCount); }
public override void Render(IGameViewport viewport, PartSysEmitter emitter) { var it = emitter.NewIterator(); var animParams = AnimatedModelParams.Default; animParams.rotation3d = true; // Lazily initialize render state if (!emitter.HasRenderState()) { // Resolve the mesh filename var baseName = ResolveBasename(emitter.GetSpec().GetMeshName()); var skmName = baseName + ".skm"; var skaName = baseName + ".ska"; try { var animId = new EncodedAnimId(NormalAnimType.ItemIdle); // This seems to be item_idle var model = _modelFactory.FromFilenames(skmName, skaName, animId, animParams); emitter.SetRenderState( new ModelEmitterRenderState(model) ); } catch (Exception e) { Logger.Error("Unable to load model {0} for particle system {1}: {2}", baseName, emitter.GetSpec().GetParent().GetName(), e); emitter.SetRenderState(new ModelEmitterRenderState(null)); } } var renderState = (ModelEmitterRenderState)emitter.GetRenderState(); if (renderState.Model == null) { return; // The loader above was unable to load the model for this emitter } var overrides = new MdfRenderOverrides { ignoreLighting = true, overrideDiffuse = true }; var yaw = emitter.GetParamState(PartSysParamId.part_yaw); var pitch = emitter.GetParamState(PartSysParamId.part_pitch); var roll = emitter.GetParamState(PartSysParamId.part_roll); while (it.HasNext()) { var particleIdx = it.Next(); var age = emitter.GetParticleAge(particleIdx); overrides.overrideColor = GeneralEmitterRenderState.GetParticleColor(emitter, particleIdx); // Yes, this is *actually* swapped for Y / Z var particleState = emitter.GetParticleState(); animParams.offsetX = particleState.GetState(ParticleStateField.PSF_POS_VAR_X, particleIdx); animParams.offsetY = particleState.GetState(ParticleStateField.PSF_POS_VAR_Z, particleIdx); animParams.offsetZ = particleState.GetState(ParticleStateField.PSF_POS_VAR_Y, particleIdx); if (yaw != null) { animParams.rotationYaw = Angles.ToRadians(yaw.GetValue(emitter, particleIdx, age)); } if (pitch != null) { animParams.rotationPitch = Angles.ToRadians(pitch.GetValue(emitter, particleIdx, age)); } if (roll != null) { animParams.rotationRoll = Angles.ToRadians(roll.GetValue(emitter, particleIdx, age)); } renderState.Model.SetTime(animParams, age); _modelRenderer.Render(viewport, renderState.Model, animParams, new List <Light3d>(), overrides); } }
public static void SimulateParticleMovement(PartSysEmitter emitter, float timeToSimulateSecs) { var spec = emitter.GetSpec(); // Used as a factor in integrating the acceleration to retroactively calculate // its influence on the particle position var accelIntegrationFactor = timeToSimulateSecs * timeToSimulateSecs * 0.5f; var state = emitter.GetParticleState(); var it = emitter.NewIterator(); while (it.HasNext()) { var particleIdx = it.Next(); var particleAge = emitter.GetParticleAge(particleIdx); var valueSource = new ParticleValueSource(emitter, particleIdx, particleAge); var x = state.GetState(ParticleStateField.PSF_X, particleIdx); var y = state.GetState(ParticleStateField.PSF_Y, particleIdx); var z = state.GetState(ParticleStateField.PSF_Z, particleIdx); var velX = state.GetState(ParticleStateField.PSF_VEL_X, particleIdx); var velY = state.GetState(ParticleStateField.PSF_VEL_Y, particleIdx); var velZ = state.GetState(ParticleStateField.PSF_VEL_Z, particleIdx); // Calculate new position of particle based on velocity x += timeToSimulateSecs * velX; y += timeToSimulateSecs * velY; z += timeToSimulateSecs * velZ; // Apply acceleration to velocity (retroactively to position as well) float value; if (valueSource.GetValue(PartSysParamId.part_accel_X, out value)) { x += accelIntegrationFactor * value; velX += timeToSimulateSecs * value; } if (valueSource.GetValue(PartSysParamId.part_accel_Y, out value)) { y += accelIntegrationFactor * value; velY += timeToSimulateSecs * value; } if (valueSource.GetValue(PartSysParamId.part_accel_Z, out value)) { z += accelIntegrationFactor * value; velZ += timeToSimulateSecs * value; } /* * Apply Velocity Var */ if (spec.GetParticleVelocityCoordSys() == PartSysCoordSys.Polar) { if (spec.GetParticlePosCoordSys() != PartSysCoordSys.Polar) { // Velocity is polar, positions are not . convert velocity var azimuth = emitter.GetParamValue(PartSysParamId.part_velVariation_X, particleIdx, particleAge); var inclination = emitter.GetParamValue(PartSysParamId.part_velVariation_Y, particleIdx, particleAge); var radius = emitter.GetParamValue(PartSysParamId.part_velVariation_Z, particleIdx, particleAge); var cartesianVel = SphericalDegToCartesian(azimuth, inclination, radius); x += cartesianVel.X * timeToSimulateSecs; y += cartesianVel.Y * timeToSimulateSecs; z += cartesianVel.Z * timeToSimulateSecs; } else { // Modify the spherical coordinates of the particle directly if (valueSource.GetValue(PartSysParamId.part_velVariation_X, out value)) { ref var azimuth = ref state.GetStatePtr(ParticleStateField.PSF_POS_AZIMUTH, particleIdx); azimuth += value * timeToSimulateSecs; } if (valueSource.GetValue(PartSysParamId.part_velVariation_Y, out value)) { ref var inclination = ref state.GetStatePtr(ParticleStateField.PSF_POS_INCLINATION, particleIdx); inclination += value * timeToSimulateSecs; } if (valueSource.GetValue(PartSysParamId.part_velVariation_Z, out value)) { ref var radius = ref state.GetStatePtr(ParticleStateField.PSF_POS_RADIUS, particleIdx); radius += value * timeToSimulateSecs; } }