Changing particle movement code?
by Tyler Slabinski · in Torque Game Builder · 08/14/2010 (3:47 am) · 33 replies
I've been using a formula in TorqueScript to create a gravitational 'force' towards an object. This 'force' currently only works on objects in the scene, but I want to expand it a bit more.
I am not good at changing the engine code, which is what I am trying to learn at the moment. I am trying to make certain particles (if they have an option turned on) to be attracted to the objects just like normal. I know C++, but I don't know how the particles work in the source code. I know I am being vague right now, but I am trying to think of a way to explain what I need. This is my script for the gravity:
I am not good at changing the engine code, which is what I am trying to learn at the moment. I am trying to make certain particles (if they have an option turned on) to be attracted to the objects just like normal. I know C++, but I don't know how the particles work in the source code. I know I am being vague right now, but I am trying to think of a way to explain what I need. This is my script for the gravity:
new SimSet(StarList);
//For each star in the scene, add it to the SimSet created above.
function starClass::onLevelLoaded(%this, %scenegraph)
{
StarList.add(%this);
}
//Update a callback every frame for the planet (%this)
function planetClass::onLevelLoaded(%this, %scenegraph)
{
%this.enableUpdateCallBack();
}
function planetClass::onUpdate(%this)
{
%cStars = StarList.getCount();
for( %i = 0; %i < %cStars; %i++ )
{
%star = StarList.getObject(%i);
%pastX = %this.getLinearVelocityX();
%pastY = %this.getLinearVelocityY();
%distance = t2dVectorDistance(%star.getPosition(), %this.getPosition());
%x = %star.getPositionX() - %this.getPositionX();
%y = %star.getPositionY() - %this.getPositionY();
%sum = mAbs(%x) + mAbs(%y);
%powerX = castGravityX(%sum, %x, %distance);
%powerY = castGravityY(%sum, %y, %distance);
%this.setLinearVelocity(%powerX + %pastX, %powerY + %pastY);
}
}
//Get the gravitational force in the X direction.
function castGravityX(%sum, %x, %distance)
{
%x = %x / %sum;
return (%x / %distance) * 300;
}
//Get the gravitation force in the Y direction.
function castGravityY(%sum, %y, %distance)
{
%y = %y / %sum;
return (%y / %distance) * 300;
}About the author
Working on prototype.
#22
It still shows the usage as "(<x y>)", not "(<x y>, <mass>)", which comes directly from the last string in the ConsoleMethod.
If the code is definitely in, make sure you are getting no compile errors and that you are running the correct executable.
I'm being insanely lazy with the Point3F. It encodes the position of the body into the x- and y-components and the mass into the z-component. If I were to make this "official" in some kind of resource, I'd make a struct with a t2dVector and a F32, but I have specific rules:
* When you create it, make it work.
* When you use it again, clean up the code.
* When you use it a third time, make a design.
Finally, you don't have to match parameter names in the ".h" and the ".cc", so it makes sense that it wouldn't change anything. It's more clear if you change the ".h" to posAndMass, though, so what you did is good.
08/19/2010 (6:54 pm)
The reason I'm certain it's the ConsoleMethod is because of the error message:Quote:
t2dParticleEmitter::addBody - wrong number of arguments.
usage: (<x y>)
It still shows the usage as "(<x y>)", not "(<x y>, <mass>)", which comes directly from the last string in the ConsoleMethod.
If the code is definitely in, make sure you are getting no compile errors and that you are running the correct executable.
I'm being insanely lazy with the Point3F. It encodes the position of the body into the x- and y-components and the mass into the z-component. If I were to make this "official" in some kind of resource, I'd make a struct with a t2dVector and a F32, but I have specific rules:
* When you create it, make it work.
* When you use it again, clean up the code.
* When you use it a third time, make a design.
Finally, you don't have to match parameter names in the ".h" and the ".cc", so it makes sense that it wouldn't change anything. It's more clear if you change the ".h" to posAndMass, though, so what you did is good.
#23
Works perfectly! I am surprised at how fast it runs. I can have thousands of particles onscreen and still get upwards of 40 frames...
08/20/2010 (6:37 pm)
Okay, it's starting to work now (don't know why, I didn't change anything).Works perfectly! I am surprised at how fast it runs. I can have thousands of particles onscreen and still get upwards of 40 frames...
#24
08/20/2010 (6:55 pm)
Nice! I'll be curious what kind of framerate you get on the iPhone (or whatever device you put it on).
#25
Now I need to figure out a way to do the same thing except with a t2dSceneObject...
EDIT: I think I've got it, but I need to find a place in t2dSceneObject.cc that has a function similar to integrateParticle().
EDIT2: Found it: void t2dSceneObject::integrateObject()
I should figure it out soon.
08/20/2010 (10:19 pm)
Well I just found out that the core gameplay can't use the particles (particle collisions can't get source object).Now I need to figure out a way to do the same thing except with a t2dSceneObject...
EDIT: I think I've got it, but I need to find a place in t2dSceneObject.cc that has a function similar to integrateParticle().
EDIT2: Found it: void t2dSceneObject::integrateObject()
I should figure it out soon.
#26
t2dSceneObject.cc
In void t2dSceneObject::integrateObject()
t2dSceneObject constructor
Console methods
I doubt this will work, but I am hoping it will. I've run into a compiler error though. In the loop, I replaced the pParticleNode with just "object", because I couldn't find out what to replace it with. What would I replace that with to get the compiler error to go away?
EDIT: Forgot the header file:
class t2dSceneObject : public BehaviorComponent
In public
08/22/2010 (1:27 am)
I pretty much copied and pasted the code changes you made for the particle effect into the t2dSceneObject files. This is what I've done:t2dSceneObject.cc
In void t2dSceneObject::integrateObject()
if( mGrav )
{
for( S32 i = 0; i < mGravBodies.size(); ++i )
{
const Point3F& star = mGravBodies[i];
t2dVector starPos( star.x, star.y );
F32 starMass = star.z;
t2dVector dir = starPos - object->mPosition;
F32 distance = dir.len();
if( distance == 0 ) continue;
if( distance < 1 ) distance = 1;
t2dVector deltaVel = dir / mPow(distance, 2.1f) * starMass;
object->mVelocity += deltaVel * elapsedTime;
}
}t2dSceneObject constructor
mGrav(false)
Console methods
void t2dSceneObject::setGravity( bool status )
{
mGrav = status;
}
void t2dSceneObject::clearBodies()
{
mGravBodies.clear();
}
void t2dSceneObject::addBody( const Point3F& posAndMass )
{
mGravBodies.push_back( posAndMass );
}
ConsoleMethod( t2dSceneObject, addBody, void, 4, 4, "<x y>, <mass>" )
{
Point3F pos;
dSscanf( argv[2], "%g %g", &pos.x, &pos.y );
dSscanf( argv[3], "%g", &pos.z );
object->addBody( pos );
}
ConsoleMethod( t2dSceneObject, setGravity, void, 3, 3, "(status)" )
{
object->setGravity( dAtob( argv[2] ) );
}
ConsoleMethod( t2dSceneObject, clearBodies, void, 2, 2, "()" )
{
object->clearBodies();
}I doubt this will work, but I am hoping it will. I've run into a compiler error though. In the loop, I replaced the pParticleNode with just "object", because I couldn't find out what to replace it with. What would I replace that with to get the compiler error to go away?
EDIT: Forgot the header file:
class t2dSceneObject : public BehaviorComponent
In public
// Gravitational Bodies bool mGrav; Vector<Point3F> mGravBodies;
//Particle Gravity
void setGravity( bool status );
void clearBodies();
void addBody( const Point3F& posAndMass );
#27
Let me know if it works. I'm very curious!
08/22/2010 (3:07 am)
In this case, you'll want to do something like this:setLinearVelocity( getLinearVelocity() + deltaVel * elapsedTime );
Let me know if it works. I'm very curious!
#28
In the loop, I need to replace 'object' with something else, but I don't know what I need to replace it with.
EDIT: Nevermind, I just realized I didn't need the 'object'. It compiles fine, but I get an error ingame saying "unknown command 'setGravity'".
EDIT2: I also get the same error with addBody() and clearBodies() when I try to execute them too.
08/22/2010 (4:00 am)
I keep getting the error "'object' was not declared in this scope".In the loop, I need to replace 'object' with something else, but I don't know what I need to replace it with.
EDIT: Nevermind, I just realized I didn't need the 'object'. It compiles fine, but I get an error ingame saying "unknown command 'setGravity'".
EDIT2: I also get the same error with addBody() and clearBodies() when I try to execute them too.
#29
08/22/2010 (4:40 am)
That means that you are either using the wrong executable or that you don't have the ConsoleMethods. I always double check that the time on the executable matches the computer's time after I build just to make sure that I didn't overlook an error in the compiler.
#30
08/22/2010 (4:04 pm)
Okay, I fixed it. I don't get any errors in the console, but it just doesn't do anything...
#31
Do the calculation up to the deltaVel line and call "objPhysics.addNetLinearForce()" with that deltaVel value.
If I get a few moments later this week, I'll do a quick test with it.
Later!
08/23/2010 (2:18 am)
I don't have time to test something right now, but I would try putting the force calculation into t2dSceneObject::updateConstantForce.Do the calculation up to the deltaVel line and call "objPhysics.addNetLinearForce()" with that deltaVel value.
If I get a few moments later this week, I'll do a quick test with it.
Later!
#32
08/23/2010 (2:32 am)
Nope, that doesn't seem to do anything. I don't get any errors in the console either, so I don't really know what's going on during runtime...
#33
I am trying to actually get the sprites to be attracted to every other sprite in the game, but I don't even know what to do anymore...
10/30/2010 (12:38 am)
Well I finished alot of my prototype, but I still don't know how to get this to work.I am trying to actually get the sprites to be attracted to every other sprite in the game, but I don't even know what to do anymore...
Torque Owner Tyler Slabinski
void t2dParticleEmitter::setGravity( bool status ) { mGrav = status; } void t2dParticleEmitter::clearBodies() { mGravBodies.clear(); } void t2dParticleEmitter::addBody( const Point3F& posAndMass ) { mGravBodies.push_back( posAndMass ); } ConsoleMethod( t2dParticleEmitter, addBody, void, 4, 4, "(<x y>, <mass>)" ) { Point3F pos; dSscanf( argv[2], "%g %g", &pos.x, &pos.y ); dSscanf( argv[3], "%g", &pos.z ); object->addBody( pos ); } ConsoleMethod( t2dParticleEmitter, setGravity, void, 3, 3, "(status)" ) { object->setGravity( dAtob( argv[2] ) ); } ConsoleMethod( t2dParticleEmitter, clearBodies, void, 2, 2, "()" ) { object->clearBodies(); }Is there something to this line in the header file I need to make?
Because it looks like it's just getting a constant for position, and not anything for mass. I changed the 'pos' with 'posAndMass' (like in the .cc file), but it doesn't look like that really did anything...