Game Development Community

TGB C++ code - Pool Ball Physics?

by Tom Biagioni · in Torque Game Builder · 03/03/2009 (10:31 am) · 26 replies

Can you add C++ to the TGB engine? The reason i am asking is that i have code written out in C++ for pool ball physics, and collisions, but i dont know how to add it with torque script. How does this all work? Should i just try and write it all out in script, or can i build my project the C++ code?
Page «Previous 1 2
#1
03/03/2009 (10:47 am)
You can add your pool balls to the C++ or just your math for them. As it stands, you should still have a lot of stuff to do in script for things like GUIs, loading, unloading, scene management, etc.
#2
03/03/2009 (11:03 am)
Yeah all i really want is the math and physics aspecs. Im just not sure how to integrate my algorithms to work with my pool balls. Like i have the balls running in Visual studio, using OpenGL, but i wanna make this in TGB, and apply the physics.
#3
03/03/2009 (11:04 am)
Oh, then you'll add new commands. It's covered in the TDN, but for the sake of comparison, you might want to look at the implementation of the math commands what they return. Then on collision, you'd call that and then apply the resulting vector to the balls.
#4
03/03/2009 (11:07 am)
AH i see what you mean. So i can just compare the math commands in TDN to what i have in C++? I know that TGB has its own built in math, im just not familiar enough with it to know if it can handle what i have. My setup is really simple too. You control the ball with the arrow keys, and when it collides with a ball they bounce int he appropriate direction.
#5
03/03/2009 (11:18 am)
Well, it's easy to make a new console command the math ones seem to be the most likely match to what you want to do in that numbers go in and numbers come out.
#6
03/03/2009 (11:38 am)
Cool thanks, im checking out the console fucntions right now.
#7
03/03/2009 (12:07 pm)
Tom, you might also be interested in this thread.
Michael Woerister also provided a very well-written PDF describing how he integrated Box2D with TGB, which seems pretty similar to what you'd like to do.
#8
03/03/2009 (12:32 pm)
Wow thats really freakin cool. Im readin the pdf now, that would be awesome if i could integrate this engine. I was looking at the TDN and the math functions, and TGB looks like it has most of the basics needed for collisions as well.

Quik noob question though, so to apply whatever physics to the balls, i would put the math functions in the OnCollision method of the object?
#9
03/03/2009 (12:45 pm)
> to apply whatever physics to the balls, i would put the math functions in the OnCollision method of the object?

i do not know, but it sounds reasonable. give it a try!
#10
03/04/2009 (8:52 am)
So im just gonna continue off this thread in regards to pool. I was thinking about the pool cue stick, and how it would work in a game. Somehow the stick has to be attached to the outside of the white ball, and also should have the ability to rotate around the ball with the mouse movement.

So i was thinking what if I had the stick spawn to a linkpoint on the ball? Then when the stick hits the ball, i would destroy it, and set it to respawn back at the link point lets say, 5 seconds later. Would this work, or is there a better way?
#11
03/04/2009 (6:13 pm)
May7be someone could help me on this. Im havin a hard time getting this code to work. Maybe i have the calls all wrong for the two objects. heres the code.

if (!isObject(BallBounceBehavior))
{
  %template = new BehaviorTemplate(BallBounceBehavior);

  %template.friendlyName = "Ball Bounce";
  %template.behaviorType = "Physics";
  %template.description = "balls that collide bounce off each other";

}

  function BallBounceBehavior::onAddToScene(%this, %scenegraph)
  {
     %this.owner.setCollisionResponse("RIGID");
  }

  

  function BallBounceBehavior::findBounce(%this)
  {
    
  //Initialize soem variables
  %mass1 = 0.15;
  %mass2 = 0.15;
  %radius1 = 2.25
  %radius2 = 2.25;
  %acos = mAcos(-1.0E0);
  %distance = VectorDist(%dstObj.getPosition(),%srcObj.getPosition());
  %x1 = %dstObj.getPositionX();
  %y1 = %dstObj.getPositionY();
  %x2 = %srcObj.getPositionX();
  %y2 = %srcObj.getPositionY();

  %vx1 = %dstObj.getLinearVelocityX();
  %vy1 = %dstObj.getLinearVelocityY();
  %vx2 = %srcObj.getLinearVelocityX();
  %vy2 = %srcObj.getLinearVelocityY();


  %pi2 = 2 * %acos;
  %r12 = radius1 + radius2;
  %m21 = mass1 / mass2;
  %x21 = %x2 - %x1;
  %y21 = %y2 - %y1;
  %vx21 = %vx2 - %vx1;
  %vy21 = %vy2 - %vy1;

  //*** calculate relative velocity angle
  
  %gammav = getLinearVelocityPolar(-%vy21,-%vx21);

  
  //*** calculate relative position angle and normalized impact parameter ***
  %gammaxy = getLinearVelocityPolar(%y21,%x21);
  %dgamma = %gammaxy - %gammav;

  if (%dgamma > 3.14 * 2) {dgamma = dgamma - 3.14 * 2;}
    else if (dgamma < -3.14 * 2) {dgamma = dgamma + 3.14 * 2;}

  %dr = %distance * mSin(%dgamma)/%r12;

  //     **** calculate impact angle
  %alpha = mAsin(%dr);



  //     **** calculate time to collision ***
  %dc = %distance * mCos(%dgamma);
  if (%dc > 0) {%sqs= 1.0;} else {%sqs = -1.0;}
  %t = (%dc - %sqs * %r12 * mSqrt(1-%dr*%dr))/mSqrt(%vx21*%vx21+%vy21*%vy21);
  // **** Update Positions
  %x1 = %dstObj.setPositionX(%x1+%vx1*t);
  %y1 = %dstObj.setPositionY(%y1+%vy1*t);
  %x2 = %srcObj.setPositionX(%x2+%vx2*t);
  %y2 = %srcObj.setPositionY(%y2+%vy2*t);



  // ****update velocities

  %a = mTan(%gammav + %alpha);

  %dvx2 = -2*(%vx21 + %a*%vy21) / ((1 + %a*%a)*(1+%m21));

  %vx2 = %srcObj.setLinearVelocityX(%vx2+%dvx2);
  %vy2 = %srcObj.setLinearVelocityY(%vy2+%a*%dvx2);
  %vx1 = %dstObj.setLinearVelocityX(%vx1-%m21*%dvx2);
  %vy1 = %dstObj.setLinearVelocityY(%vy1-%a*%m21*%dvx2);
  
  return;
  }
    

  function BallBounceBehavior::onCollision(%srcObj, %dstObj, %srcRef,   %dstRef, %time, %normal,%contactCount, %contacts)
  {
    %srcObj.findBounce();
    %dstObj.findBounce();

  }
#12
03/05/2009 (7:39 am)
Tom, would kindly give us a pseudo-code rundown of what you hope your code to do? That would really help.
#13
03/05/2009 (9:09 am)
yes no problem.

//Initialize the variables

We need both mass's for the objects that are colliding, as well as thei radius'.

%mass1
%mass2
%radius1
%radius2

Then we need to find the VectorDist() between the two objects with:
%distance = VectorDist(%dstObj.getPosition(),%srcObj.getPosition());


Im assuming that the two objects are represented as %dstObj, and %srcObj in OnCollision(), this may be where im going wrong though. As you can see in the code, i got the x and y coordinates for both of them, as well as their velocites when they collide. I then calculate both objects velocity angles, and impact angles (or the angle of the objects relative to their positions.)

Basically what this code does is it checks each object to see if they are going to collide based on their positions, and velocities. It then calculates the time to impact. After impact the code then sets the objects with a new velocity and direction.

I then call the findBounce method from the onCollision method, but im thinking that this will not work.
#14
03/05/2009 (10:01 am)
Does torque have a method to get the radius of an object? Or even the mass for that matter?

Like getRadius() and getMass()?

cant seem to find it in TDN
#15
03/05/2009 (10:42 am)
Ok i re did the onCollision code, but i am not entirly sure the math function should be in onCollision? basically i just want this stuff to run when the ball hits another ball. Heres the code:

function BallBounceBehavior::onCollision(%srcObj, %dstObj, %srcRef,   %dstRef, %time, %normal,%contactCount, %contacts)
{

  //Initialize variables

  %x1 = %dstObj.getPositionX();    //object coordinates
  %y1 = %dstObj.getPositionY();
  %x2 = %srcObj.getPositionX();
  %y2 = %srcObj.getPositionY();

  %r1 = 2.25;
  %r2 = 2.25;

  %dx = %x2 - %x1;
  %dy = %y2 - %y1;

  %d = mSqrt(%dx*%dx + %dy*%dy);   //distance

  while (%d <= %r1 +%r2)

  {
    %vx1 = %dstObj.getLinearVelocityX();
    %vy1 = %dstObj.getLinearVelocityY();
    %vx2 = %srcObj.getLinearVelocityX();
    %vy2 = %srcObj.getLinearVelocityY();

    %mass1 = 0.15;
    %mass2 = 0.15;

    //velocity in the direction of (dx, dy)
    
    %vp1 = (%vx1*dx + %vy1*%dy) / %d;
    %vp2 = (%vx2*dx + %vy2*%dy) / %d;
 
    //collision should of happened dt before

    %dt = (%r1 + %r2 - %d) / (%vp1 - %vp2);

    //move the circles backward in time
    %x1 -= %vx1 * %dt;
    %y1 -= %vy1 * %dt;
    %x2 -= %vx2 * %dt;
    %y2 -= %vy2 * %dt;

    //new collision calculations at impact

    %dx = %x2 - %x1;
    %dy = %y2 - %y1;
    %d = mSqrt(%dx*%dx + %dy*%dy);   //distance

    //unit vector is direction of collision
    %ax = %dx/%d;
    %ay = %dy/%d;

    //projection of the velocites int he axis
 
    %va1 = %vx1*%ax + %vy1*%ay;
    %vb1 = -%vx1*%ay + %vy1*%ax;
    %va2 = %vx2*%ax + %vy2*%ay;
    %vb2 = -%vx2*%ay + %vy2*%ax;

    //calculate new velocity after collision

    %ed = 1;
    %vaP1 = %va1 + (1 + %ed) * (%va2 - %va1) / (1 + %mass1/%mass2);
    %vaP2 = %va2 + (1 + %ed) * (%va1 - %va2) / (1 + %mass2/%mass1);
    
    //undo projections

    %vx += %vx1 * %dt;
    %y1 += %vy1 * %dt;
    %x2 += %vx2 * %dt;
    %y2 += %vy2 * %dt;

    //Update positions and velocities

    %dstObj.setPositionX(%x1);
    %dstObj.setPositionY(%y1);
    %srcObj.setPositionX(%x2);
    %srcObj.setPositionY(%y2);

    %dstObj.setLinearVelocityX(%vx1);
    %dstObj.setLinearVelocityY(%vy1);
    %srcObj.setLinearVelocityX(%vx2);
    %srcObj.setLinearVelocityY(%vy2);
  }
}
#16
03/05/2009 (11:33 am)
Don't the balls have a fixed mass?

Also, I don't think you should put the math in the onCollision, rather just refactor it can call the collisions.

The radius would be half of the size if the object goes all the way out to the edge of its sprite.

What I don't understand is if you're trying to predict a collision or if you're trusting the engine to find the collisions and then recalculating from that.
#17
03/05/2009 (11:48 am)
Im using actual dimensions for a pool ball. Mass is 0.15kg and radius is 0.15. Sorry for the confusion hehe. What im trying to do is have the engine find the collisions, and then recalculate from that. So when the engine detects the collision between the balls, id like it to use my math function to apply the appropriate velocites.

So should i make a new function in my behavior that does the math, and at the end of the function call on collision?
#18
03/05/2009 (12:15 pm)
Yes, new collision which passes the objects to it at the end of the onCallision callback would make sense. If this were C++, we'd pass them by reference and update their new directions and velocities, right? So, we would probably want to do something like that here. What's important though is that each collision is only handled one time. If every ball sends and recieves a collision, you could end up having onCollision called twice.

The engine has some built-in capability for collisions and physics already and I would recommend scaling back to that to start with just two object balls on the table. Then, you should be able to see how often each collision is handled to make sure you avoid duplicate processing of a single collision.

Also, make sure you're using collision circles, but you probably already have that.
#19
03/05/2009 (12:16 pm)
My point being that let's just start at the beginning.

You have collisions, right? The problem is just down now to when to call the actual math and when to update their physics?
#20
03/05/2009 (12:52 pm)
Yes correct the balls do collide when i have them set to "Rigid" I just need to figure out a way to call the math so that they adjust their physics.

Im thinking about what you wrote (Post#18) and ive kinda got an idea. So we would some how need to make a call to the math function when onCollision. We also need to have references to %dstObj and %srcObj (since these represent the objs that collide). Maybe they could be referenced as %c1 and %c2, and i would reference those in my math function. Im not sure however how i would go about referencing %srcObj and %dstObj. Heres some ideas.

function BallBounceBehavior::onCollision(%srcObj, %dstObj, %srcRef,   %dstRef, %time, %normal,%contactCount, %contacts)
{
  %dstObj.findBounce();
  echo( "COLLISION: " @ %srcObj @ " hit by " @ %dstObj );  //echo collide

}

I also noticed some people used datablocks for their ball objects, im just note sureif that would be the right way to go here.

Page «Previous 1 2