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); } }
protected override void FillVertex(PartSysEmitter emitter, int particleIdx, Span <SpriteVertex> vertices, int vertexIdx) { // Calculate the particle scale (default is 1) var scale = 1.0f; var scaleParam = emitter.GetParamState(PartSysParamId.part_scale_X); if (scaleParam != null) { scale = scaleParam.GetValue(emitter, particleIdx, emitter.GetParticleAge(particleIdx)); } Vector4 halfPartHeightX; Vector4 halfPartHeightY; var rotationParam = emitter.GetParamState(PartSysParamId.part_yaw); if (rotationParam != null) { var rotation = rotationParam.GetValue( emitter, particleIdx, emitter.GetParticleAge(particleIdx)); rotation += emitter.GetParticleState().GetState(ParticleStateField.PSF_ROTATION, particleIdx); rotation = Angles.ToRadians(rotation); var cosRot = MathF.Cos(rotation) * scale; var sinRot = MathF.Sin(rotation) * scale; halfPartHeightX = screenSpaceUnitX * cosRot - screenSpaceUnitY * sinRot; halfPartHeightY = screenSpaceUnitY * cosRot + screenSpaceUnitX * sinRot; } else { halfPartHeightX = screenSpaceUnitX * scale; halfPartHeightY = screenSpaceUnitY * scale; } var partPos = new Vector4( emitter.GetParticleState().GetState(ParticleStateField.PSF_POS_VAR_X, particleIdx), emitter.GetParticleState().GetState(ParticleStateField.PSF_POS_VAR_Y, particleIdx), emitter.GetParticleState().GetState(ParticleStateField.PSF_POS_VAR_Z, particleIdx), 1 ); // Upper left corner vertices[vertexIdx + 0].pos = partPos - halfPartHeightX + halfPartHeightY; // Upper right corner vertices[vertexIdx + 1].pos = partPos + halfPartHeightX + halfPartHeightY; // Lower right corner vertices[vertexIdx + 2].pos = partPos + halfPartHeightX - halfPartHeightY; // Lower left corner vertices[vertexIdx + 3].pos = partPos - halfPartHeightX - halfPartHeightY; // Set the diffuse color for all corners var diffuse = GeneralEmitterRenderState.GetParticleColor(emitter, particleIdx); vertices[vertexIdx + 0].diffuse = diffuse; vertices[vertexIdx + 1].diffuse = diffuse; vertices[vertexIdx + 2].diffuse = diffuse; vertices[vertexIdx + 3].diffuse = diffuse; // Set UV coordinates for the sprite. We need to do this every frame // because we're using DISCARD for locking vertices[vertexIdx + 0].u = 0; vertices[vertexIdx + 0].v = 1; vertices[vertexIdx + 1].u = 1; vertices[vertexIdx + 1].v = 1; vertices[vertexIdx + 2].u = 1; vertices[vertexIdx + 2].v = 0; vertices[vertexIdx + 3].u = 0; vertices[vertexIdx + 3].v = 0; }