Explorar o código

Target Particles

-Particles can now target a point in the world.
-AngleToy setup to be a test environement for the target particles
marauder2k7 %!s(int64=5) %!d(string=hai) anos
pai
achega
aa944452e2

+ 6 - 0
engine/source/2d/assets/ParticleAssetEmitter.cc

@@ -183,6 +183,8 @@ ParticleAssetEmitter::ParticleAssetEmitter() :
                             mOwner( NULL ),
                             mEmitterType( POINT_EMITTER ),
                             mEmitterOffset( 0.0f, 0.0f),
+                            mTargetParticle(false),
+                            mTargetPosition(0.0f, 0.0f),
                             mEmitterAngle( 0.0f ),
                             mEmitterSize( 10.0f, 10.0f ),
                             mFixedAspect( true ),
@@ -274,6 +276,10 @@ void ParticleAssetEmitter::initPersistFields()
     addProtectedField("EmitterName", TypeString, Offset(mEmitterName, ParticleAssetEmitter), &setEmitterName, &defaultProtectedGetFn, &defaultProtectedWriteFn, "");
     addProtectedField("EmitterType", TypeEnum, Offset(mEmitterType, ParticleAssetEmitter), &setEmitterType, &defaultProtectedGetFn, &writeEmitterType, 1, &EmitterTypeTable);
     addProtectedField("EmitterOffset", TypeVector2, Offset(mEmitterOffset, ParticleAssetEmitter), &setEmitterOffset, &defaultProtectedGetFn, &writeEmitterOffset, "");
+    //Target Particle
+    addProtectedField("TargetParticle", TypeBool, Offset(mTargetParticle, ParticleAssetEmitter), &setTargetParticle, &defaultProtectedGetFn, &writeTargetParticle, "");
+    addProtectedField("TargetPosition", TypeVector2, Offset(mTargetPosition, ParticleAssetEmitter), &setTargetPosition, &defaultProtectedGetFn, &writeTargetPosition, "");
+    //Target Particle end---
     addProtectedField("EmitterAngle", TypeF32, Offset(mEmitterAngle, ParticleAssetEmitter), &setEmitterAngle, &defaultProtectedGetFn, &writeEmitterAngle, "");
     addProtectedField("EmitterSize", TypeVector2, Offset(mEmitterSize, ParticleAssetEmitter), &setEmitterSize, &defaultProtectedGetFn, &writeEmitterSize, "");
     addProtectedField("FixedAspect", TypeBool, Offset(mFixedAspect, ParticleAssetEmitter), &setFixedAspect, &defaultProtectedGetFn, &writeFixedAspect, "");

+ 16 - 1
engine/source/2d/assets/ParticleAssetEmitter.h

@@ -115,7 +115,10 @@ private:
     PhysicsParticleType                     mPhysicsParticleType;
     bool                                    mPhysicsParticles;
     //Physics Particles end---
-
+    //Particle Target
+    bool                                    mTargetParticle;
+    Vector2                                 mTargetPosition;
+    //Particle Target end---
     bool                                    mLinkEmissionRotation;
     bool                                    mIntenseParticles;
     bool                                    mSingleParticle;
@@ -187,6 +190,12 @@ public:
     inline void setPhysicsParticles(const bool physicsPaticle) { mPhysicsParticles = physicsPaticle; refreshAsset(); }
     inline bool getPhysicsParticles(void) const { return mPhysicsParticles; }
     //Phyiscs particles end---
+    //Particle Target
+    inline void setTargetPosition(const Vector2& targetPos) { mTargetPosition = targetPos; }
+    inline const Vector2& getTargetPosition(void) const { return mTargetPosition; }
+    inline void setTargetParticle(const bool targetParticle) { mTargetParticle = targetParticle; refreshAsset(); }
+    inline bool getTargetParticle(void) const { return mTargetParticle; }
+    //Particle Target end---
     inline void setKeepAligned( const bool keepAligned ) { mKeepAligned = keepAligned; refreshAsset(); }
     inline bool getKeepAligned( void ) const { return mKeepAligned; }
     inline void setAlignedAngleOffset( const F32 angleOffset ) { mAlignedAngleOffset = angleOffset; refreshAsset(); }
@@ -304,6 +313,12 @@ protected:
     static bool     writeEmitterType( void* obj, StringTableEntry pFieldName )          { return static_cast<ParticleAssetEmitter*>(obj)->getEmitterType() != POINT_EMITTER; }
     static bool     setEmitterOffset(void* obj, const char* data)                       { static_cast<ParticleAssetEmitter*>(obj)->setEmitterOffset(Vector2(data)); return false; }
     static bool     writeEmitterOffset( void* obj, StringTableEntry pFieldName )        { return static_cast<ParticleAssetEmitter*>(obj)->getEmitterOffset().notZero(); }
+
+    static bool     setTargetParticle(void* obj, const char* data)                      { static_cast<ParticleAssetEmitter*>(obj)->setTargetParticle(dAtob(data)); return false; }
+    static bool     writeTargetParticle(void* obj, StringTableEntry pFieldName)         { return static_cast<ParticleAssetEmitter*>(obj)->getTargetParticle() == false; }
+    static bool     setTargetPosition(void* obj, const char* data)                      { static_cast<ParticleAssetEmitter*>(obj)->setTargetPosition(Vector2(data)); return false; }
+    static bool     writeTargetPosition(void* obj, StringTableEntry pFieldName)         { return static_cast<ParticleAssetEmitter*>(obj)->getTargetPosition().notZero(); }
+
     static bool     setEmitterAngle(void* obj, const char* data)                        { static_cast<ParticleAssetEmitter*>(obj)->setEmitterAngle(dAtof(data)); return false; }
     static bool     writeEmitterAngle( void* obj, StringTableEntry pFieldName )         { return mNotZero(static_cast<ParticleAssetEmitter*>(obj)->getEmitterAngle()); }
     static bool     setEmitterSize(void* obj, const char* data)                         { static_cast<ParticleAssetEmitter*>(obj)->setEmitterSize(Vector2(data)); return false; }

+ 50 - 0
engine/source/2d/assets/ParticleAssetEmitter_ScriptBinding.h

@@ -123,6 +123,56 @@ ConsoleMethodWithDocs(ParticleAssetEmitter, getEmitterOffset, ConsoleString, 2,
     return object->getEmitterOffset().scriptThis();
 }
 
+ConsoleMethodWithDocs(ParticleAssetEmitter, setTargetParticle, ConsoleVoid, 3, 3, (targetParticle))
+{
+   object->setTargetParticle(dAtob(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets whether the emitter targets a point.
+    @return Whether the emitter uses a target for particles.
+*/
+ConsoleMethodWithDocs(ParticleAssetEmitter, getTargetParticle, ConsoleBool, 2, 2, ())
+{
+   return object->getTargetParticle();
+}
+
+
+ConsoleMethodWithDocs(ParticleAssetEmitter, setTargetPosition, ConsoleVoid, 3, 4, (float X / float Y))
+{
+   // Grab the element count.
+   U32 elementCount = Utility::mGetStringElementCount(argv[2]);
+
+   // ("positionX positionY")
+   if ((elementCount == 2) && (argc < 4))
+   {
+      object->setTargetPosition(Vector2(argv[2]));
+      return;
+   }
+
+   // (positionX, positionY)
+   if ((elementCount == 1) && (argc > 3))
+   {
+      object->setTargetPosition(Vector2(dAtof(argv[2]), dAtof(argv[3])));
+      return;
+   }
+
+   // Warn.
+   Con::warnf("ParticleAssetEmitter::setTargetPosition() - Invalid number of parameters!");
+}
+
+//------------------------------------------------------------------------------
+
+/*! Gets the emitter target position.
+    @return (float x/float y) The position of the target of the emitter.
+*/
+ConsoleMethodWithDocs(ParticleAssetEmitter, getTargetPosition, ConsoleString, 2, 2, ())
+{
+   return object->getTargetPosition().scriptThis();
+}
+
+
 //------------------------------------------------------------------------------
 
 /*! Sets the emitter size.

+ 17 - 4
engine/source/2d/sceneobject/ParticlePlayer.cc

@@ -1147,11 +1147,24 @@ void ParticlePlayer::configureParticle( EmitterNode* pEmitterNode, ParticleSyste
                                                                 pParticleAssetEmitter->getEmissionForceVariationField(),
                                                                 particlePlayerAge) * getForceScale();
 
-        // Calculate Emission Angle.
-        emissionAngle = ParticleAssetField::calculateFieldBV(   pParticleAssetEmitter->getEmissionAngleBaseField(),
-                                                                pParticleAssetEmitter->getEmissionAngleVariationField(),
-                                                                particlePlayerAge );
+        if (pParticleAssetEmitter->getTargetParticle())
+        {
+           Vector2 tPos = pParticleAssetEmitter->getTargetPosition();
+           Vector2 pPos = pParticleNode->mPosition;
+           Vector2 subVec = tPos - pPos;
+           //Vector2 subVecF = subVec.getUnitDirection();
+           F32 vecN = mAtan(subVec.x, subVec.y);
+           F32 vecDeg = mRadToDeg(vecN);
+           emissionAngle = vecDeg;
+        }
+        else
+        {
 
+           // Calculate Emission Angle.
+           emissionAngle = ParticleAssetField::calculateFieldBV(  pParticleAssetEmitter->getEmissionAngleBaseField(),
+                                                                  pParticleAssetEmitter->getEmissionAngleVariationField(),
+                                                                  particlePlayerAge);
+        }
         // Calculate Emission Arc.
         // NOTE:-   We're actually interested in half the emission arc!
         emissionArc = ParticleAssetField::calculateFieldBV( pParticleAssetEmitter->getEmissionArcBaseField(),

+ 11 - 8
modules/AngleToy/1/main.cs

@@ -130,6 +130,11 @@ function AngleToy::createTargets( %this )
     
     %emitter = %effect.createEmitter();
     AngleToy.EmitterParameters = %emitter;
+	%emitter.setEmitterType("ELLIPSE");
+	//%emitter.setAttachPositionToEmitter(false);
+	%emitter.setEmitterSize("40 40");
+	%emitter.TargetParticle = true;
+	%emitter.setTargetPosition("0.0 0.0");
     %emitter.EmitterName = "AngledParticles";
     %emitter.setKeepAligned( true );
     %emitter.setOrientationType( ALIGNED );
@@ -140,13 +145,12 @@ function AngleToy::createTargets( %this )
     %emitter.addDataKey( 0, 250 );
     %emitter.selectField( "Speed" );
     %emitter.addDataKey( 0, 4 );
-    %emitter.selectField( "EmissionAngle" );
-    %emitter.addDataKey( 0, 0 );
     %emitter.selectField( "EmissionArc" );
     %emitter.addDataKey( 0, 0 );
     %emitter.selectField( "EmissionForceVariation" );
     %emitter.addDataKey( 0, 0 );
     %emitter.deselectField();
+	%emitter.dump();
     
     %assetId = AssetDatabase.addPrivateAsset( %effect );
     
@@ -221,9 +225,7 @@ function AngleToy::onTouchDown(%this, %touchID, %worldPosition)
     %angle = mAtan( %worldPosition );
     
     // "Point" particles towards cursor
-    AngleToy.EmitterParameters.selectField( "EmissionAngle" );
-    AngleToy.EmitterParameters.addDataKey( 0, %angle );
-    AngleToy.EmitterParameters.deselectField();
+    AngleToy.EmitterParameters.setTargetPosition(%worldPosition);
     
     // Show Sin, Cos, Tan
     %sin = mSin( %angle );
@@ -266,9 +268,10 @@ function AngleToy::onTouchDragged(%this, %touchID, %worldPosition)
     %angle = mAtan( %worldPosition );
     
     // "Point" particles towards cursor
-    AngleToy.EmitterParameters.selectField( "EmissionAngle" );
-    AngleToy.EmitterParameters.addDataKey( 0, %angle );
-    AngleToy.EmitterParameters.deselectField();
+    //AngleToy.EmitterParameters.selectField( "EmissionAngle" );
+    //AngleToy.EmitterParameters.addDataKey( 0, %angle );
+    //AngleToy.EmitterParameters.deselectField();
+	AngleToy.EmitterParameters.setTargetPosition(%worldPosition);
     
     // Show Sin, Cos, Tan
     %sin = mSin( %angle );