/* Sparx * Copyright August Zinsser 2007 * This program is distributed under the terms of the GNU General Public License */ using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; namespace Pina3D.Particles { public class Vortex : Force { private Emitter mCenter; private Vector3 mCentralDisplacement; private bool mClockwise; public Emitter Center { set { mCenter = value; } get { return mCenter; } } /// /// Displaces the center of rotation from the central object by this amount /// public Vector3 CentralDisplacement { set { mCentralDisplacement = value; } get { return mCentralDisplacement; } } public bool Clockwise { set { mClockwise = value; } get { return mClockwise; } } public Vortex(string name, float lifeSpan, float delay, Emitter center, Vector3 centralDisplacement, float magnitude, bool clockwise) : base(name, lifeSpan, delay) { mCenter = center; mMagnitude = magnitude; mCentralDisplacement = centralDisplacement; mClockwise = clockwise; } public override Object Clone() { Vortex retFo = new Vortex(mName + "_clone", mAge, mDelay, mCenter, mCentralDisplacement, mMagnitude, mClockwise); return retFo; } public override void Update(Emission emission) { if (mCenter != null && emission.Age > mDelay && emission.Age < mLifeExpectancy + mDelay) { RecalculateForceVector(emission); emission.Velocity3D += Vector3.Multiply(mForceVector, Pina.ElapsedSeconds); } } /// /// Makes a force vector that is perpindicular to the center-thispoint vector, and adds that to regular angular acceleration /// /// private void RecalculateForceVector(Emission newCenter) { // TODO: this function in 3D //Vector3 toCenter = mCenter.Position3D + mCentralDisplacement - newCenter.Position3D; //float r2 = (float)toCenter.LengthSquared(); //// For clockwise rotation, cross this vector with a +z vector //Vector3 zVec = mClockwise ? new Vector3(0, 0, -mMagnitude) : new Vector3(0, 0, mMagnitude); //Vector3 fVec = new Vector3(toCenter.X, toCenter.Y, 0); //Vector3 rVec = Vector3.Cross(zVec, fVec); //mForceVector = new Vector3(rVec.X, rVec.Y); //// Add a centripetal force //toCenter.Normalize(); //mForceVector += Vector2.Multiply(toCenter, r2); } } }