#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2009 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#endregion
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Nuclex.Graphics.Batching;
namespace Nuclex.Graphics.SpecialEffects.Particles.HighLevel {
#if false
/// Renders particles as CPU-calculates billboards
/// Data type of the particles
///
///
/// This default implementation of a particle renderer assumes that your particle
/// structure and your particle vertex are one and the same. This is in no way
/// a requirement, but has the advantage that the renderer is not required to
/// touch each and every particle to produce a vertex for it.
///
///
/// Particles are rendered as point sprites, so your effect should be capable
/// of processing vertices as such.
///
///
public class BillBoardParticleRenderer : IParticleRenderer
where ParticleType : struct {
/// Initializes a new point particle renderer
/// Effect that will be used to render the particle
public BillBoardParticleRenderer(Effect effect) :
this(new EffectDrawContext(effect)) { }
/// Initializes a new point particle renderer
///
/// Draw context controlling the rendering of the particles
///
public BillBoardParticleRenderer(DrawContext drawContext) {
if(drawContext == null) {
throw new ArgumentException("Invalid draw context", "drawContext");
}
this.drawContext = drawContext;
}
/// Renders a series of particles
/// Particles that will be rendered
///
/// Primitive batch that will receive the vertices generated by the particles
///
public void Render(
ArraySegment particles,
PrimitiveBatch primitiveBatch
) {
Vector3 cameraPosition = this.Camera.Translation;
Vector3 cameraUp = this.Camera.Up;
Vector3 cameraForward = this.Camera.Forward;
Matrix billboard;
ParticleType tl, tr, bl, br;
int end = particles.Offset + particles.Count;
for(int index = particles.Offset; index < end; ++index) {
tl = particles.Array[index];
tr = tl;
bl = tl;
br = tl;
Vector3 position;
this.accessor.GetPosition(ref tl, out position);
Matrix.CreateBillboard(
ref position, ref cameraPosition, ref cameraUp, cameraForward, out billboard
);
Vector3 corner;
corner.X = position.X + billboard.M11 + billboard.M21;
corner.Y = position.Y + billboard.M12 + billboard.M22;
corner.Z = position.Z + billboard.M13 + billboard.M23;
this.accessor.SetPosition(ref tl, ref corner);
corner.X = position.X - billboard.M11 + billboard.M21;
corner.Y = position.Y - billboard.M12 + billboard.M22;
corner.Z = position.Z - billboard.M13 + billboard.M23;
this.accessor.SetPosition(ref tr, ref corner);
corner.X = position.X + billboard.M11 - billboard.M21;
corner.Y = position.Y + billboard.M12 - billboard.M22;
corner.Z = position.Z + billboard.M13 - billboard.M23;
this.accessor.SetPosition(ref bl, ref corner);
corner.X = position.X - billboard.M11 - billboard.M21;
corner.Y = position.Y - billboard.M12 - billboard.M22;
corner.Z = position.Z - billboard.M13 - billboard.M23;
this.accessor.SetPosition(ref br, ref corner);
}
primitiveBatch.Draw(
particles.Array, particles.Offset, particles.Count,
PrimitiveType.PointList,
this.drawContext
);
}
public Matrix Camera;
/// Draw context controlling the rendering of the particles
private DrawContext drawContext;
private IParticleAccessor accessor;
}
#endif
} // namespace Nuclex.Graphics.SpecialEffects.Particles.HighLevel