RF and physics

Programming Reality Factory and Genesis3D.
User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico »

@ hike
To obtain a first person driver we need to attach the camera to some joint inside body of the car. The problem is the render distance of the engine so actually, inside the body, the chasssis is transparent. However we can try.

________

NEW CAR DEMO.
DOWNLOAD: http://realityfactory.altervista.org/do ... t_Room.zip

There are new arising problems but new steps beyond done.

a) Test Room and rigid car..
b) Mechanic suspension test.

a) Test Room 1. Drive the car in a empty driving school square. Note that the 2 front wheels are auto-aligned and the force is applied long the actual driving wheel rotation axis. This is possible in virtue of a script that calculate the relative absolute rotation of the wheels and turns that variable in a relative fraction to be applied to the Torque_Force generated by the (virtual) motor.

this is the pawn script:
debug("Torque Direction - Debug");
debug(self.key_pressed);
debug("Torque on Z Axis :" # A_PERC # " %");
debug("Torque on X Axis :" # B_PERC # " %");
debug("Overrall steer Wheel: " # OVERRALL_STEER # " %");
debug("Overrall steer Chassis: " # OVERRALL_STEER_CHASSIS # " %");
debug("Left Wheel steer: " # LEFT_STEER # " %");
debug("Right Wheel steer: " # RIGHT_STEER # " %");
debug("Left Mouse Button = accelerate");
debug("Right Mouse Button = decelerate / retro");
debug("Keyboard Arrows = Left/Right");
debug("8 = Change Camera");
debug("J = Apply an Upward Impulse");
debug("SPACE = HANDBRAKE");


//calculemus 1 - For the torque forcfe applied on Z axis on the motor wheel
MY_YAW = Integer(LEFT_WHEEL_ATTACH.current_yaw / 0.0174532925199433);
MY_YAW_CHASSIS = Integer(self.current_yaw / 0.0174532925199433);

if((MY_YAW > 0)and(MY_YAW <= 90))
{
B_PERC = Integer(100 /(90/(MY_YAW)));
A_PERC = Integer(100 - B_PERC);
}
if((MY_YAW > 90)and(MY_YAW <= 180))
{
A_PERC = -(Integer(100 /(90/(MY_YAW-90))));
B_PERC = Integer(100 + A_PERC);
}

if((MY_YAW > 180)and(MY_YAW <= 270))
{
B_PERC = -(Integer(100 /(90/(MY_YAW-180))));
A_PERC = -(Integer(100 + B_PERC));
}
if((MY_YAW > 270)and(MY_YAW <= 360))
{
A_PERC = Integer(100 /(90/(MY_YAW-270)));
B_PERC = -(Integer(100 - A_PERC));
}

if(MY_YAW = 0)
{
B_PERC=0;
A_PERC=100;
}
to have patial percentual output of the torque (X Z axis).
the result in the Physics Script will be:
SetTorque(Body[3], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);
SetTorque(Body[4], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);


Z_PERC = GetGlobal(1, "Int");
X_PERC = GetGlobal(2, "Int");


if(((self.leftmousekey_pressed=true)and((self.key_pressed=46)=false)and((self.key_pressed=33)=false))and(((self.key_pressed=58)=true)or((self.key_pressed=58)=false))and(((self.key_pressed=57)=true)or((self.key_pressed=57)=false)))
{
TORQUE_REAR=240;
X_FINAL_TORQUE = TORQUE_REAR*(X_PERC/100);
Z_FINAL_TORQUE = TORQUE_REAR*(Z_PERC/100);
}
else
{
X_FINAL_TORQUE = -TORQUE_REAR*(X_PERC/100);
Z_FINAL_TORQUE = -TORQUE_REAR*(Z_PERC/100);
if(((self.rightmousekey_pressed)and((self.key_pressed=46)=false)and((self.key_pressed=33)=false))and(((self.key_pressed=58)=true)or((self.key_pressed=58)=false))and(((self.key_pressed=57)=true)or((self.key_pressed=57)=false)))
{
TORQUE_REAR=240;
}
else
{
TORQUE_REAR=1;
}
Now i'm trying to migrate it inside the PhysicsScript of the car but something doesn't work good.

The auto-alignement script is obtained in a similar way, calculating the difference between the wheels alignement.

You can turn on stencil shadows and see them in action on the Car Body. This will show up the limit of the script because the left wheel will lose his capability to auto-align properly. Too much scripts at the same time and too much pawn entities to track the physic object (attached using PositionTPAwn). So Nout, some help is welcome to put all the script in one and track object yaw without pawn entities.

Brake and Handbrake are scripted in a brutal wa, don't think about it. In the same way I had to use a simpliied torque increasing method to test the torque/rotation alignement but an acceleration/gear system has to be scripted to have different gear ratio and torque responses.
Probaly there is better way to have the front wheels aligned. Can Nout explain in a detailed way, wich methos has been used in the Vehicle Entity (sensor and callbacks? but what exactly are "sensor and callbacks"? please teach me!)

I think that the behavious of the car is, all things considered, quite good. The problem is stability.

b) Little example to have "mechanic suspension" using only joint and force trying to simulate the suspension real mechanic. The result is a quite interesting interesing as case study.

There are additional bodies jointed between the chassis and the wheels. These bodies create am hinge the chassis and the wheels in the Z axis. This joint have a llittle up/down limit so the chassis can move up and down in respect the wheels. A constant force in applied to these bodies to partially invert the gravity such a suspension that force up a body. This isn't probably a good method to create a suspension but is interesting to see that it can be done.

DOWNLOAD: http://realityfactory.altervista.org/do ... t_Room.zip

Probably you have to wait some day to have the last Nout executables...
Attachments
screen000.JPG
Suspension Car
(57.06 KiB) Downloaded 76 times
Simple car
Simple car
screen006.jpg (9.96 KiB) Viewed 1887 times
Simple car
Simple car
screen008.jpg (10.41 KiB) Viewed 1887 times
Last edited by federico on Mon Oct 24, 2005 2:26 pm, edited 2 times in total.
User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico »

NEW CAR DEMO UPDATE.
DOWNLOAD:http://realityfactory.altervista.org/do ... pdate1.zip

Put the script in the scripts folder and the levels in the media/levels folder the actors in the media/actors folder.

Now the car script contains inside all the instruction to match the torque direction and wheel steer. The wheel alignement script now works only if wheels are unalligned and no steer command is executed by the driver.
All the calls for external variables are direct, no more SetGlobal GetGLobal commands. There is an issue on wheel roation so I have to find a way to multiply the force applied to reset alignement depending on gap alignement (but sometimes this is greater than 100 and the car fly away). Anyway we need to solve this because sometimes the Mass force applied on suspension or steer of the car is greater than the twist force applied to the hinge steerl. In the "rigid" car all works much better now, and faster.

Nout, is this script convertible to c++ code? But a question arises, is this an improvement respect of the Vehicle entity? If it is, it would be nice to put togheter the "motor" and steer of the scripted car and the suspension of the vehicle entity. What do you think about?

Two levels with static and dinamic obstacles.
if you want to turn on the static obstacle in the "rigid car" demo, uncomment these lines:

for i=1 to 10
{
Cone = CreateStaticBody("Cyl"#i, "box_centered.act",1,0.2,10, 255, (PosX-400)-((Dx*2)*i), -720, PosZ, 0,0,0, 0,0,0 , false, 200, "Box 0", 0, 0,0,0,0, Mass/2);

}

you will see that the car can't go over the static obstacles.

this is the main script of the rigid car:
{

PosX [0]
PosY [0]
PosZ [0]
Dx [0]
Dy [0]
Dz [0]

Dx_hinge [0]
Dy_hinge [0]
Dz_hinge [0]

Dx_hinge2 [0]
Dy_hinge2 [0]
Dz_hinge2 [0]

Mass [1]
Scale [1]
ALPHA [255]
MyBodyId [-1]
SenId1 [-1]
RocketId [-1]
KeyReleased [true]
Depth [0.0]
TORQUE_REAR [0]
TORQUE_FRONT [0]
TORQUE_FRONT_L [0]
CODE [0]
MAX_STEAR_ANGLE [33]
TORQUE_LATERAL [0]
TORQUE_FORCE [340]

X_PERC [0]
Z_PERC [0]
X_FINAL_TORQUE [0]
Z_FINAL_TORQUE [0]

X_FINAL_TORQUE_HANDBRAKE [0]
Z_FINAL_TORQUE_HANDBRAKE [0]

MIX_STEER_GLOBAL [0]
MIX_STEER_LOCAL [0]

TIME [0]
FOLLOWSPEED[0]
MY_YAW [0]
MY_YAW_CHASSIS [0]
ANOTHER_YAW [0]
A_PERC [0]
B_PERC [0]

OVERRALL_STEER [0]
OVERRALL_STEER_CHASSIS [0]

LEFT_STEER [0]
RIGHT_STEER [0]
MIX_STEER [0]
FINAL_STEER [0]
LEFT_WHEEL_LOCAL [0]
RIGHT_WHEEL_LOCAL [0]

Body
{
Body0 [0]
Body1 [0]
Body2 [0]
Body3 [0]
Body4 [0]
Body5 [0]
Body6 [0]
Body7 [0]
Body8 [0]
Body9 [0]
Body10 [0]
Body11 [0]
Body12 [0]
Body13 [0]
Body14 [0]
Body15 [0]
Body16 [0]
Body17 [0]
Body18 [0]
Body19 [0]
Body20 [0]
Body21 [0]
Body22 [0]
Body23 [0]
Body24 [0]
Body25 [0]
Body26 [0]
Body27 [0]
Body28 [0]
Body29 [0]
Body30 [0]
Body31 [0]
Body32 [0]
Body33 [0]
Body34 [0]
Body35 [0]
Body36 [0]
Body37 [0]
Body38 [0]
Body39 [0]
Body40 [0]
}

Cone
{
Cone0 [0]
Cone1 [0]
Cone2 [0]
Cone3 [0]
Cone4 [0]
Cone5 [0]
Cone6 [0]
Cone7 [0]
Cone8 [0]
Cone9 [0]
Cone10 [0]
Cone11 [0]
Cone12 [0]
Cone13 [0]
Cone14 [0]
Cone15 [0]
Cone16 [0]
Cone17 [0]
Cone18 [0]
Cone19 [0]
Cone20 [0]
Cone21 [0]
Cone22 [0]
Cone23 [0]
Cone24 [0]
Cone25 [0]
Cone26 [0]
Cone27 [0]
Cone28 [0]
Cone29 [0]
Cone30 [0]
Cone31 [0]
Cone32 [0]
Cone33 [0]
Cone34 [0]
Cone35 [0]
Cone36 [0]
Cone37 [0]
Cone38 [0]
Cone39 [0]
Cone40 [0]
}

Actor
{
Actor0 [box0.act]
Actor1 [box1.act]
Actor2 [box2.act]
Actor3 [box3.act]
Actor4 [box4.act]
Actor5 [box5.act]
}

s [0]
i [0]
j [0]

Dx_box [0]
Dy_box [0]
Dz_box [0]

Init[ () //Is excecuted only once.
{
Console(true);
PosX = 0;
PosY = -340;
PosZ = 0;

DefineMaterial(1, 3, 0.3);
DefineMaterial(2, 1, 0.3);
Body[0] = CreateRigidBody("Body0", "CHASSIS",8,8,8, 255, PosX, PosY, PosZ, 0,0,0, 0,0,0 , false, ALPHA, "Box 133 20 74", 2, 0,0,0,0, Mass*8);
ExtendRigidBody(Body[0], "Body0ext1", "box_centered.act" ,1,1,1, 0, PosX, PosY, PosZ, 2,25,0, 0,0,0 , false, 0, "Box 45 12 50", 2, 0,0,0,0, Mass*8);
ExtendRigidBody(Body[0], "Body0ext2", "box_centered.act" ,1,1,1, 0, PosX, PosY, PosZ, 25,15,0, 0,0,0 , false, 0, "Box 45 12 50", 2, 0,0,0,0, Mass*8);
ExtendRigidBody(Body[0], "Body0ext3", "box_centered.act" ,1,1,1, 0, PosX, PosY, PosZ, -55,5,0, 0,0,0 , false, 0, "Box 45 12 50", 2, 0,0,0,0, Mass*4);

Dx = GetBodyBBox(Body[0], 0);
Dy = GetBodyBBox(Body[0], 1);
Dz = GetBodyBBox(Body[0], 2);

Dx_Dummy = GetBodyBBox(Body[5], 0);
Dy_Dummy = GetBodyBBox(Body[5], 1);
Dz_Dummy = GetBodyBBox(Body[5], 2);

Body[1] = CreateRigidBody("Body1", "rear_tyre.act", 9,9,9, 255, PosX+Dx*0.24, PosY-Dy*0.60, PosZ+Dz*0.47,0,0,0, 0,0,0, false, 120, "Sphere 0", 1, 0,0,0,0, Mass*1.5);
Body[2] = CreateRigidBody("Body2", "rear_tyre.act", 9,9,9, 255, PosX+Dx*0.24, PosY-Dy*0.60, PosZ-Dz*0.47,0,0,0, 0,0,0, false, 120, "Sphere 0", 1, 0,0,0,0, Mass*1.5);

CreateHingeJoint(Body[0], Body[1], PosX+Dx*0.24, PosY-Dy*0.60, PosZ+Dz*0.47, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);
CreateHingeJoint(Body[0], Body[2], PosX+Dx*0.24, PosY-Dy*0.60, PosZ-Dz*0.47, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);


Body[5] = CreateRigidBody("Dummy1", "box0.act",1,1,1, 0, PosX-Dx*0.45, PosY-Dy*0.60, PosZ+Dz*0.40, 0,0,0, 0,0,0 , false, 200, "Box 0", 1, 0,0,0,0, Mass);
Body[6] = CreateRigidBody("Dummy2", "box0.act",1,1,1, 0, PosX-Dx*0.45, PosY-Dy*0.60, PosZ-Dz*0.40, 0,0,0, 0,0,0 , false, 200, "Box 0", 1, 0,0,0,0, Mass);
CreateHingeJoint(Body[0], Body[5], PosX-Dx*0.45, PosY-Dy*0.60, PosZ+Dz*0.40, 0,0,0, -MAX_STEAR_ANGLE, MAX_STEAR_ANGLE, -MAX_STEAR_ANGLE, MAX_STEAR_ANGLE, Dz*0.35, -1, 0, 0);
CreateHingeJoint(Body[0], Body[6], PosX-Dx*0.45, PosY-Dy*0.60, PosZ-Dz*0.40, 0,0,0, -MAX_STEAR_ANGLE, MAX_STEAR_ANGLE, -MAX_STEAR_ANGLE, MAX_STEAR_ANGLE, Dz*0.35, -1, 0, 0);


Body[3] = CreateRigidBody("Body3", "front_tyre.act", 8,8,8, 255, PosX-Dx*0.45, PosY-Dy*0.60, PosZ+Dz*0.40, 0,0,0, 0,0,0, false, 120, "Sphere 0", 1, 0,0,0,0, Mass);
Body[4] = CreateRigidBody("Body4", "front_tyre.act", 8,8,8, 255, PosX-Dx*0.45, PosY-Dy*0.60, PosZ-Dz*0.40, 0,0,0, 0,0,0, false, 120, "Sphere 0", 1, 0,0,0,0, Mass);

CreateHingeJoint(Body[5], Body[3], PosX-Dx*0.45, PosY-Dy*0.60, PosZ+Dz*0.40, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);
CreateHingeJoint(Body[6], Body[4], PosX-Dx*0.45, PosY-Dy*0.60, PosZ-Dz*0.40, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);

/*
for i=1 to 10
{
Cone = CreateStaticBody("Cyl"#i, "box_centered.act",1,0.2,10, 255, (PosX-400)-((Dx*2)*i), -720, PosZ, 0,0,0, 0,0,0 , false, 200, "Box 0", 0, 0,0,0,0, Mass/2);

}
*/

Dx_box = GetBodyBBox("Body0ext1", 0);
Dy_box = GetBodyBBox("Body0ext1", 1);
Dz_box = GetBodyBBox("Body0ext1", 2);

for i=0 to 4 //unlike expected this for loop is not executed for i = 5!!
{
for j=0 to 6 //unlike expected this for loop is not executed for i = 5!!
{
s = ((i*5) + j);
Body = CreateRigidBody("domino"#s, "crate.act", 5, 5, 5, 255, PosX-2850, (-650)+((Dy_box*5)*i), ((PosZ-(Dz_box*4))*2.5)+((Dz_box*4)*j), 0,0,0, 0,0,0, false, 200, "Box 0", 0, 0,0,0,0,Mass/4);
}
}

} ]

Start[ ()
{
ShowPhysicsBBox(false);
Dx = GetBodyBBox(Body[0], 0);
Dy = GetBodyBBox(Body[0], 1);
Dz = GetBodyBBox(Body[0], 2);
TORQUE_FORCE = 340;

SetTorque(Body[3], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);
SetTorque(Body[4], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);
//SetTorque(Body[1], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);
//SetTorque(Body[2], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);




if(((self.leftmousekey_pressed=true)and((self.key_pressed=46)=false)and((self.key_pressed=33)=false))and(((self.key_pressed=58)=true)or((self.key_pressed=58)=false))and(((self.key_pressed=57)=true)or((self.key_pressed=57)=false)))
{
TORQUE_REAR=240;
X_FINAL_TORQUE = TORQUE_REAR*(B_PERC/100);
Z_FINAL_TORQUE = TORQUE_REAR*(A_PERC/100);
}
else
{
X_FINAL_TORQUE = -TORQUE_REAR*(B_PERC/100);
Z_FINAL_TORQUE = -TORQUE_REAR*(A_PERC/100);
if(((self.rightmousekey_pressed)and((self.key_pressed=46)=false)and((self.key_pressed=33)=false))and(((self.key_pressed=58)=true)or((self.key_pressed=58)=false))and(((self.key_pressed=57)=true)or((self.key_pressed=57)=false)))
{
TORQUE_REAR=240;
}
else
{
TORQUE_REAR=1;
}
}

if((self.key_pressed=57)=true)
{
TORQUE_FRONT = 80;
TORQUE_FRONT_L = 80;
}
else
{
if((self.key_pressed=58)=true)
{
TORQUE_FRONT = -80;
TORQUE_FRONT_L = -80;
}
else
{
TORQUE_FRONT = 0;
}
}


ApplyTwist(Body[5], 0, TORQUE_FRONT_L, 0, true);
ApplyTwist(Body[6], 0, TORQUE_FRONT, 0, true);



if((((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) < 0)and((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) > -100)) or((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) > 100))
{
TORQUE_FRONT_L = TORQUE_FRONT + 5;
}
else
{
if((((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) > 0)and((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) < 100)) or ((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) < -100))
{
TORQUE_FRONT_L = TORQUE_FRONT - 5;
}
if(RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL = 0)
{
TORQUE_FRONT_L = 0;
}
}


if(self.key_pressed=32)
{
ApplyImpulse(Body[0], 0, 30, 0, true);
}
if((self.key_pressed=46)=true)
{
ApplyTwist(Body[1], X_FINAL_TORQUE*4, 0, Z_FINAL_TORQUE*4, false);
ApplyTwist(Body[2], X_FINAL_TORQUE*4, 0, Z_FINAL_TORQUE*4, false);
//ApplyTwist(Body[3], X_FINAL_TORQUE*2, 0, Z_FINAL_TORQUE*4, false);
//ApplyTwist(Body[4], X_FINAL_TORQUE*2, 0, Z_FINAL_TORQUE*4, false);

if(X_FINAL_TORQUE > 0)
{
X_FINAL_TORQUE = -X_FINAL_TORQUE;
}
else
{
if(X_FINAL_TORQUE < 0)
{
X_FINAL_TORQUE = -X_FINAL_TORQUE;
}
else
{
X_FINAL_TORQUE = 0;
}
}

if(Z_FINAL_TORQUE > 0)
{
Z_FINAL_TORQUE = -Z_FINAL_TORQUE;
}
else
{
if(Z_FINAL_TORQUE < 0)
{
Z_FINAL_TORQUE = -Z_FINAL_TORQUE;
}
else
{
Z_FINAL_TORQUE = 0;
}
}

}
if(((self.key_pressed=33)=true)and((self.leftmousekey_pressed=true)or(self.leftmousekey_pressed=false)))
{
ApplyTwist(Body[3], X_FINAL_TORQUE*2, 0, Z_FINAL_TORQUE*2, false);
ApplyTwist(Body[4], X_FINAL_TORQUE*2, 0, Z_FINAL_TORQUE*2, false);
if(X_FINAL_TORQUE > 0)
{
X_FINAL_TORQUE = -X_FINAL_TORQUE;
}
else
{
if(X_FINAL_TORQUE < 0)
{
X_FINAL_TORQUE = -X_FINAL_TORQUE;
}
else
{
X_FINAL_TORQUE = 0;
}
}

if(Z_FINAL_TORQUE > 0)
{
Z_FINAL_TORQUE = -Z_FINAL_TORQUE;
}
else
{
if(Z_FINAL_TORQUE < 0)
{
Z_FINAL_TORQUE = -Z_FINAL_TORQUE;
}
else
{
Z_FINAL_TORQUE = 0;
}
}
}



debug("Torque Direction - Debug");
//debug(self.key_pressed);
debug("Torque on Z Axis :" # A_PERC # " %");
debug("Torque on X Axis :" # B_PERC # " %");
debug("Overrall steer Wheel: " # OVERRALL_STEER # " %");
debug("Overrall steer Chassis: " # OVERRALL_STEER_CHASSIS # " %");
debug("Left Wheel steer: " # LEFT_STEER # " %");
debug("Right Wheel steer: " # RIGHT_STEER # " %");
debug("Left/Right Wheels Gap: " # Integer(RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL));
debug("Left Mouse Button = accelerate");
debug("Right Mouse Button = decelerate / retro");
debug("Keyboard Arrows = Left/Right");
debug("8 = Change Camera");
debug("J = Apply an Upward Impulse");
debug("SPACE = HANDBRAKE");


//calculemus 1 - For the torque forcfe applied on Z axis on the motor wheel

MY_YAW = Integer(LEFT_WHEEL_ATTACH.current_yaw / 0.0174532925199433);
MY_YAW_CHASSIS = Integer(CHASSIS_ATTACH.current_yaw / 0.0174532925199433);
LEFT_WHEEL_LOCAL = Integer(LEFT_WHEEL_ATTACH.current_yaw / 0.0174532925199433);
RIGHT_WHEEL_LOCAL = Integer(RIGHT_WHEEL_ATTACH.current_yaw / 0.0174532925199433);

if((MY_YAW > 0)and(MY_YAW <= 90))
{
B_PERC = Integer(100 /(90/(MY_YAW)));
A_PERC = Integer(100 - B_PERC);
}
if((MY_YAW > 90)and(MY_YAW <= 180))
{
A_PERC = -(Integer(100 /(90/(MY_YAW-90))));
B_PERC = Integer(100 + A_PERC);
}

if((MY_YAW > 180)and(MY_YAW <= 270))
{
B_PERC = -(Integer(100 /(90/(MY_YAW-180))));
A_PERC = -(Integer(100 + B_PERC));
}
if((MY_YAW > 270)and(MY_YAW <= 360))
{
A_PERC = Integer(100 /(90/(MY_YAW-270)));
B_PERC = -(Integer(100 - A_PERC));
}

if(MY_YAW = 0)
{
B_PERC=0;
A_PERC=100;
}




//calculemus 2 - For the Twist to be applied on Y axis on the steering wheel

MIX_STEER_LOCAL = OVERRALL_STEER_CHASSIS - OVERRALL_STEER;

if(MY_YAW>0)
{
OVERRALL_STEER = Integer(100 /(360/(MY_YAW)));
}
else
{
OVERRALL_STEER = 0;
}

if(MY_YAW_CHASSIS>0)
{
OVERRALL_STEER_CHASSIS = Integer(100 /(360/(MY_YAW_CHASSIS)));
}
else
{
OVERRALL_STEER_CHASSIS = 0;
}

if((RIGHT_WHEEL_LOCAL) > 0)
{
RIGHT_STEER = Integer(100 / (360/(RIGHT_WHEEL_LOCAL)));
}
else
{
RIGHT_STEER = 0;
}

if((LEFT_WHEEL_LOCAL) > 0)
{
LEFT_STEER = Integer(100 / (360/(LEFT_WHEEL_LOCAL)));
}
else
{
LEFT_STEER = 0;
}

MIX_STEER = (RIGHT_STEER - LEFT_STEER);


if((MIX_STEER > -25)or(MIX_STEER < 25))
{
MIX_STEER_GLOBAL = (MIX_STEER);
}

if(MIX_STEER < -75)
{
MIX_STEER_GLOBAL = (100+MIX_STEER);
}
if(MIX_STEER > 75)
{
MIX_STEER_GLOBAL = (100-MIX_STEER);
}


} ]

}


You can see that the script calls tw external variables. RIGHT_WHEEL_ATTACH.current_yaw and LEFT_WHEEL_ATTACH.current_yaw. There are two entities, named LEFT_WHEEL_ATTACH and RIGHT_WHEEL_ATTACH attached to the Body[3] and Body[4] of the car. This is the pawn script:

{

Spawn[()
{
Console(false);
LowLevel("GO");
}]

GO[()
{
PositionToPawn("Body4", 0,0 ,0, true);
PawnRender(false);
//debug(self.current_yaw/ 0.0174532925199433);
}]

}


if we can make this computation by code we can easily also exclude this entities.

DOWNLOAD:http://realityfactory.altervista.org/do ... pdate1.zip
Nout
Posts: 136
Joined: Tue Jul 05, 2005 5:14 pm

Post by Nout »

Whoo man, you fast learn too use these goodies ;-)
Great!!
Can Nout explain in a detailed way, wich methos has been used in the Vehicle Entity (sensor and callbacks? but what exactly are "sensor and callbacks"? please teach me!)
A sensor is a vitual line that you cn connect to a rigidbody. This line has a lenght and orientation. Anyhting that intersects with the line is detectable and you can ask things like what you intersect, how far the line intersects etc... I use this sensor to make the suspension in a call-back. The nice thing of a call back is that you can completely overrule the "normal physics" the physics engine calculates and customize it like you want, also with conditions, non-linearity etc... I've still some issues with the sensors myself and I'm also learning. I will write a little document that sumarizes what I know. Give me a day.
Nout, is this script convertible to c++ code? But a question arises, is this an improvement respect of the Vehicle entity? If it is, it would be nice to put togheter the "motor" and steer of the scripted car and the suspension of the vehicle entity. What do you think about?
I will look to it in detail and come back with an answer on Tuesday. PRincipally I see no limitation to put whatever in C++ that was put in a script (and it will be a lot faster :-)

See you soon, hopefully with a new Vehicle entity !
Nout
Posts: 136
Joined: Tue Jul 05, 2005 5:14 pm

Post by Nout »

Frederico,

Rather then reading the yaw via pawn scripting, you can try to use the new command which is available in the exe you have:

AngleXYZ = GetAngleBetweenBodies(BodyId1, BodyId2, , AngleXYZnr)
This command reads the actual angle between 2 bodies
If AngleXYZnr=0, AngleX is returned
If AngleXYZnr=1, AngleY is returned
If AngleXYZnr=2, AngleZ is returned

Looked to the script and sounds like all things can be implemented
Using geometry and a callback, I think I can even further optimize it and avoid using any hinges
I will put focus on this now and delay the next release a few days to get it still in. This is too nice to leave it out !
User avatar
jonas
Posts: 779
Joined: Tue Jul 05, 2005 5:43 pm
Location: Texas, USA
Contact:

Post by jonas »

wow frederico! You have to be a scripting expert! I can't wait till you guys are finished!
Jonas

Focused, hard work is the real key to success. Keep your eyes on the goal, and just keep taking the next step towards completing it. If you aren't sure which way to do something, do it both ways and see which works better. - John Carmack
User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico »

thanks jonas. The most deserved compliment is for Nout (the real programmer). :wink:

______

A mix between the 2 car type. Smart as the "rigid car" but with suspension.
{

PosX [0]
PosY [0]
PosZ [0]
Dx [0]
Dy [0]
Dz [0]

Dx_hinge [0]
Dy_hinge [0]
Dz_hinge [0]

Dx_hinge2 [0]
Dy_hinge2 [0]
Dz_hinge2 [0]

Mass [1]
Scale [1]
ALPHA [255]
MyBodyId [-1]
SenId1 [-1]
RocketId [-1]
KeyReleased [true]
Depth [0.0]
TORQUE_REAR [0]
TORQUE_FRONT [0]
TORQUE_FRONT_L [0]
CODE [0]
MAX_STEAR_ANGLE [33]
TORQUE_LATERAL [0]
TORQUE_FORCE [340]

X_PERC [0]
Z_PERC [0]
X_FINAL_TORQUE [0]
Z_FINAL_TORQUE [0]

X_FINAL_TORQUE_HANDBRAKE [0]
Z_FINAL_TORQUE_HANDBRAKE [0]

MIX_STEER_GLOBAL [0]
MIX_STEER_LOCAL [0]

TIME [0]
FOLLOWSPEED[0]
MY_YAW [0]
MY_YAW_CHASSIS [0]
ANOTHER_YAW [0]
A_PERC [0]
B_PERC [0]

OVERRALL_STEER [0]
OVERRALL_STEER_CHASSIS [0]

LEFT_STEER [0]
RIGHT_STEER [0]
MIX_STEER [0]
FINAL_STEER [0]
LEFT_WHEEL_LOCAL [0]
RIGHT_WHEEL_LOCAL [0]

Body
{
Body0 [0]
Body1 [0]
Body2 [0]
Body3 [0]
Body4 [0]
Body5 [0]
Body6 [0]
Body7 [0]
Body8 [0]
Body9 [0]
Body10 [0]
Body11 [0]
Body12 [0]
Body13 [0]
Body14 [0]
Body15 [0]
Body16 [0]
Body17 [0]
Body18 [0]
Body19 [0]
Body20 [0]
Body21 [0]
Body22 [0]
Body23 [0]
Body24 [0]
Body25 [0]
Body26 [0]
Body27 [0]
Body28 [0]
Body29 [0]
Body30 [0]
Body31 [0]
Body32 [0]
Body33 [0]
Body34 [0]
Body35 [0]
Body36 [0]
Body37 [0]
Body38 [0]
Body39 [0]
Body40 [0]
}

Cone
{
Cone0 [0]
Cone1 [0]
Cone2 [0]
Cone3 [0]
Cone4 [0]
Cone5 [0]
Cone6 [0]
Cone7 [0]
Cone8 [0]
Cone9 [0]
Cone10 [0]
Cone11 [0]
Cone12 [0]
Cone13 [0]
Cone14 [0]
Cone15 [0]
Cone16 [0]
Cone17 [0]
Cone18 [0]
Cone19 [0]
Cone20 [0]
Cone21 [0]
Cone22 [0]
Cone23 [0]
Cone24 [0]
Cone25 [0]
Cone26 [0]
Cone27 [0]
Cone28 [0]
Cone29 [0]
Cone30 [0]
Cone31 [0]
Cone32 [0]
Cone33 [0]
Cone34 [0]
Cone35 [0]
Cone36 [0]
Cone37 [0]
Cone38 [0]
Cone39 [0]
Cone40 [0]
}

Actor
{
Actor0 [box0.act]
Actor1 [box1.act]
Actor2 [box2.act]
Actor3 [box3.act]
Actor4 [box4.act]
Actor5 [box5.act]
}

s [0]
i [0]
j [0]

Dx_box [0]
Dy_box [0]
Dz_box [0]

Init[ () //Is excecuted only once.
{
Console(false);
PosX = 0;
PosY = -340;
PosZ = 0;

DefineMaterial(1, 8, 0.3);
DefineMaterial(2, 1, 0.3);
Body[0] = CreateRigidBody("Body0", "CHASSIS",8,8,8, 255, PosX, PosY, PosZ, 0,0,0, 0,0,0 , false, ALPHA, "Box 133 20 74", 2, 0,0,0,0, Mass*8);
ExtendRigidBody(Body[0], "Body0ext1", "box_centered.act" ,1,1,1, 0, PosX, PosY, PosZ, 2,25,0, 0,0,0 , false, 0, "Box 45 12 50", 2, 0,0,0,0, Mass*8);
ExtendRigidBody(Body[0], "Body0ext2", "box_centered.act" ,1,1,1, 0, PosX, PosY, PosZ, 25,15,0, 0,0,0 , false, 0, "Box 45 12 50", 2, 0,0,0,0, Mass*8);
ExtendRigidBody(Body[0], "Body0ext3", "box_centered.act" ,1,1,1, 0, PosX, PosY, PosZ, -55,5,0, 0,0,0 , false, 0, "Box 45 12 50", 2, 0,0,0,0, Mass*4);

Dx = GetBodyBBox(Body[0], 0);
Dy = GetBodyBBox(Body[0], 1);
Dz = GetBodyBBox(Body[0], 2);

Dx_Dummy = GetBodyBBox(Body[5], 0);
Dy_Dummy = GetBodyBBox(Body[5], 1);
Dz_Dummy = GetBodyBBox(Body[5], 2);

Body[1] = CreateRigidBody("Body1", "rear_tyre.act", 9,9,9, 255, PosX+Dx*0.24, PosY-Dy*0.60, PosZ+Dz*0.47,0,0,0, 0,0,0, false, 120, "Sphere 0", 1, 0,0,0,0, Mass*1.5);
Body[2] = CreateRigidBody("Body2", "rear_tyre.act", 9,9,9, 255, PosX+Dx*0.24, PosY-Dy*0.60, PosZ-Dz*0.47,0,0,0, 0,0,0, false, 120, "Sphere 0", 1, 0,0,0,0, Mass*1.5);


Body[7] = CreateRigidBody("Dummy3", "box0.act",0.5,0.5,0.5, 255, PosX+Dx*0.24, PosY-Dy*0.6, PosZ+Dz*0.27, 0,0,0, 0,0,0 , false, 200, "Box 0", 0, 0,0,0,0, Mass/4);
Body[8] = CreateRigidBody("Dummy4", "box0.act",0.5,0.5,0.5, 255, PosX+Dx*0.24, PosY-Dy*0.6, PosZ-Dz*0.27, 0,0,0, 0,0,0 , false, 200, "Box 0", 0, 0,0,0,0, Mass/4);
CreateHingeJoint(Body[0], Body[7], PosX+Dx*0.24, PosY-Dy*0.6, PosZ+Dz*0.27, 0,0,90, -5, 0, -5, 0, Dz*1, -1, 0, 0);
CreateHingeJoint(Body[0], Body[8], PosX+Dx*0.24, PosY-Dy*0.6, PosZ-Dz*0.27, 0,0,90, 0, 5, 0, 5, Dz*1, -1, 0, 0);

CreateHingeJoint(Body[7], Body[1], PosX+Dx*0.24, PosY-Dy*0.6, PosZ+Dz*0.47, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);
CreateHingeJoint(Body[8], Body[2], PosX+Dx*0.24, PosY-Dy*0.6, PosZ-Dz*0.47, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);

//CreateHingeJoint(Body[0], Body[1], PosX+Dx*0.24, PosY-Dy*0.60, PosZ+Dz*0.47, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);
//CreateHingeJoint(Body[0], Body[2], PosX+Dx*0.24, PosY-Dy*0.60, PosZ-Dz*0.47, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);

Body[9] = CreateRigidBody("Dummy5", "box0.act",0.5,0.5,0.5, 255, PosX-Dx*0.45, PosY-Dy*0.6, PosZ+Dz*0.27, 0,0,0, 0,0,0 , false, 200, "Box 0", 0, 0,0,0,0, Mass);
Body[10] = CreateRigidBody("Dummy6", "box0.act",0.5,0.5,0.5, 255, PosX-Dx*0.45, PosY-Dy*0.6, PosZ-Dz*0.27, 0,0,0, 0,0,0 , false, 200, "Box 0", 0, 0,0,0,0, Mass);
CreateHingeJoint(Body[0], Body[9], PosX-Dx*0.45, PosY-Dy*0.6, PosZ+Dz*0.27, 0,0,90, -5, 0, -5, 0, Dz*1, -1, 0, 0);
CreateHingeJoint(Body[0], Body[10], PosX-Dx*0.45, PosY-Dy*0.6, PosZ-Dz*0.27, 0,0,90, 0, 5, 0, 5, Dz*1, -1, 0, 0);

//CreateHingeJoint(Body[9], Body[5], PosX-Dx*0.45, PosY-Dy*0.6, PosZ+Dz*0.40, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);
//CreateHingeJoint(Body[10], Body[6], PosX-Dx*0.45, PosY-Dy*0.6, PosZ-Dz*0.40, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);

Body[5] = CreateRigidBody("Dummy1", "box0.act",1,1,1, 0, PosX-Dx*0.45, PosY-Dy*0.60, PosZ+Dz*0.40, 0,0,0, 0,0,0 , false, 200, "Box 0", 1, 0,0,0,0, Mass);
Body[6] = CreateRigidBody("Dummy2", "box0.act",1,1,1, 0, PosX-Dx*0.45, PosY-Dy*0.60, PosZ-Dz*0.40, 0,0,0, 0,0,0 , false, 200, "Box 0", 1, 0,0,0,0, Mass);
CreateHingeJoint(Body[9], Body[5], PosX-Dx*0.45, PosY-Dy*0.60, PosZ+Dz*0.40, 0,0,0, -MAX_STEAR_ANGLE, MAX_STEAR_ANGLE, -MAX_STEAR_ANGLE, MAX_STEAR_ANGLE, Dz*0.35, -1, 0, 0);
CreateHingeJoint(Body[10], Body[6], PosX-Dx*0.45, PosY-Dy*0.60, PosZ-Dz*0.40, 0,0,0, -MAX_STEAR_ANGLE, MAX_STEAR_ANGLE, -MAX_STEAR_ANGLE, MAX_STEAR_ANGLE, Dz*0.35, -1, 0, 0);


Body[3] = CreateRigidBody("Body3", "front_tyre.act", 8,8,8, 255, PosX-Dx*0.45, PosY-Dy*0.60, PosZ+Dz*0.40, 0,0,0, 0,0,0, false, 120, "Sphere 0", 1, 0,0,0,0, Mass);
Body[4] = CreateRigidBody("Body4", "front_tyre.act", 8,8,8, 255, PosX-Dx*0.45, PosY-Dy*0.60, PosZ-Dz*0.40, 0,0,0, 0,0,0, false, 120, "Sphere 0", 1, 0,0,0,0, Mass);

CreateHingeJoint(Body[5], Body[3], PosX-Dx*0.45, PosY-Dy*0.60, PosZ+Dz*0.40, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);
CreateHingeJoint(Body[6], Body[4], PosX-Dx*0.45, PosY-Dy*0.60, PosZ-Dz*0.40, 90,0,0, -180, 180,-180, 180, Dz*0.34, -1, 0, 0);



/*

Body[13] = CreateRigidBody("PortLeft", "port_left.act",7,7,7, 255, PosX-Dx*0.28, PosY, PosZ+Dz*0.38, 0,0,0, 0,0,0 , false, 200, "Box 0", 1, 0,0,0,0, Mass);
CreateHingeJoint(Body[0], Body[13], PosX-Dx*0.28, PosY, PosZ+Dz*0.38, 0,0,0, -86, -10, -86, -10, Dz*0.35, -1, 0, 0);

Body[14] = CreateRigidBody("PortRight", "port_right.act",7,7,7, 255, PosX-Dx*0.28, PosY, PosZ-Dz*0.38, 0,0,0, 0,0,0 , false, 200, "Box 0", 1, 0,0,0,0, Mass);
CreateHingeJoint(Body[0], Body[14], PosX-Dx*0.28, PosY, PosZ-Dz*0.38, 0,0,0, 10, 86, 10, 86, Dz*0.35, -1, 0, 0);
*/


for i=1 to 10
{
Cone = CreateStaticBody("Cyl"#i, "box_centered.act",1,0.2,10, 255, (PosX-400)-((Dx*2)*i), -742, PosZ, 0,0,0, 0,0,0 , true, 200, "Box 0", 0, 0,0,0,0, Mass/2);

}


Dx_box = GetBodyBBox("Body0ext1", 0);
Dy_box = GetBodyBBox("Body0ext1", 1);
Dz_box = GetBodyBBox("Body0ext1", 2);

for i=0 to 4 //unlike expected this for loop is not executed for i = 5!!
{
for j=0 to 6 //unlike expected this for loop is not executed for i = 5!!
{
s = ((i*5) + j);
Body = CreateRigidBody("domino"#s, "crate.act", 5, 5, 5, 255, PosX-2850, (-650)+((Dy_box*5)*i), ((PosZ-(Dz_box*4))*2.5)+((Dz_box*4)*j), 0,0,0, 0,0,0, false, 200, "Box 0", 0, 0,0,0,0,Mass/4);
}
}

} ]

Start[ ()
{
ShowPhysicsBBox(false);
Dx = GetBodyBBox(Body[0], 0);
Dy = GetBodyBBox(Body[0], 1);
Dz = GetBodyBBox(Body[0], 2);
TORQUE_FORCE = 340;


ApplyForce(Body[7], 0, 16, 0, true);
ApplyForce(Body[8], 0, 16, 0, true);
ApplyForce(Body[9], 0, 16, 0, true);
ApplyForce(Body[10], 0, 16, 0, true);
/*
ApplyForce(Body[7], 0, 10, 0, false);
ApplyForce(Body[8], 0, 10, 0, false);
ApplyForce(Body[9], 0, 10, 0, false);
ApplyForce(Body[10], 0, 14, 0, false);
*/
SetTorque(Body[3], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);
SetTorque(Body[4], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);
//SetTorque(Body[1], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);
//SetTorque(Body[2], X_FINAL_TORQUE, 0, Z_FINAL_TORQUE, true);




if(((self.leftmousekey_pressed=true)and((self.key_pressed=46)=false)and((self.key_pressed=33)=false))and(((self.key_pressed=58)=true)or((self.key_pressed=58)=false))and(((self.key_pressed=57)=true)or((self.key_pressed=57)=false)))
{
TORQUE_REAR=240;
X_FINAL_TORQUE = TORQUE_REAR*(B_PERC/100);
Z_FINAL_TORQUE = TORQUE_REAR*(A_PERC/100);
}
else
{
X_FINAL_TORQUE = -TORQUE_REAR*(B_PERC/100);
Z_FINAL_TORQUE = -TORQUE_REAR*(A_PERC/100);
if(((self.rightmousekey_pressed)and((self.key_pressed=46)=false)and((self.key_pressed=33)=false))and(((self.key_pressed=58)=true)or((self.key_pressed=58)=false))and(((self.key_pressed=57)=true)or((self.key_pressed=57)=false)))
{
TORQUE_REAR=240;
}
else
{
TORQUE_REAR=TORQUE_REAR*0.4;
if(TORQUE_REAR<2)
{
TORQUE_REAR=1;
}
}
}

if((self.key_pressed=57)=true)
{
TORQUE_FRONT = 80;
TORQUE_FRONT_L = 80;
}
else
{
if((self.key_pressed=58)=true)
{
TORQUE_FRONT = -80;
TORQUE_FRONT_L = -80;
}
else
{
TORQUE_FRONT = 0;
}
}


ApplyTwist(Body[5], 0, TORQUE_FRONT_L, 0, true);
ApplyTwist(Body[6], 0, TORQUE_FRONT, 0, true);



if((((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) < 0)and((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) > -100)) or((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) > 100))
{
TORQUE_FRONT_L = TORQUE_FRONT + 5;
}
else
{
if((((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) > 0)and((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) < 100)) or ((RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL) < -100))
{
TORQUE_FRONT_L = TORQUE_FRONT - 5;
}
if(RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL = 0)
{
TORQUE_FRONT_L = 0;
}
}


if(self.key_pressed=32)
{
ApplyImpulse(Body[0], -3, 30, -3, true);
}
if((self.key_pressed=46)=true)
{
ApplyTwist(Body[1], X_FINAL_TORQUE*4, 0, Z_FINAL_TORQUE*4, false);
ApplyTwist(Body[2], X_FINAL_TORQUE*4, 0, Z_FINAL_TORQUE*4, false);
//ApplyTwist(Body[3], X_FINAL_TORQUE*2, 0, Z_FINAL_TORQUE*4, false);
//ApplyTwist(Body[4], X_FINAL_TORQUE*2, 0, Z_FINAL_TORQUE*4, false);

if(X_FINAL_TORQUE > 0)
{
X_FINAL_TORQUE = -X_FINAL_TORQUE;
}
else
{
if(X_FINAL_TORQUE < 0)
{
X_FINAL_TORQUE = -X_FINAL_TORQUE;
}
else
{
X_FINAL_TORQUE = 0;
}
}

if(Z_FINAL_TORQUE > 0)
{
Z_FINAL_TORQUE = -Z_FINAL_TORQUE;
}
else
{
if(Z_FINAL_TORQUE < 0)
{
Z_FINAL_TORQUE = -Z_FINAL_TORQUE;
}
else
{
Z_FINAL_TORQUE = 0;
}
}

}
if(((self.key_pressed=33)=true)and((self.leftmousekey_pressed=true)or(self.leftmousekey_pressed=false)))
{
ApplyTwist(Body[3], X_FINAL_TORQUE*2, 0, Z_FINAL_TORQUE*2, false);
ApplyTwist(Body[4], X_FINAL_TORQUE*2, 0, Z_FINAL_TORQUE*2, false);
if(X_FINAL_TORQUE > 0)
{
X_FINAL_TORQUE = -X_FINAL_TORQUE;
}
else
{
if(X_FINAL_TORQUE < 0)
{
X_FINAL_TORQUE = -X_FINAL_TORQUE;
}
else
{
X_FINAL_TORQUE = 0;
}
}

if(Z_FINAL_TORQUE > 0)
{
Z_FINAL_TORQUE = -Z_FINAL_TORQUE;
}
else
{
if(Z_FINAL_TORQUE < 0)
{
Z_FINAL_TORQUE = -Z_FINAL_TORQUE;
}
else
{
Z_FINAL_TORQUE = 0;
}
}
}


/*
debug("Torque Direction - Debug");
//debug(self.key_pressed);
debug("Torque on Z Axis :" # A_PERC # " %");
debug("Torque on X Axis :" # B_PERC # " %");
debug("Overrall steer Wheel: " # OVERRALL_STEER # " %");
debug("Overrall steer Chassis: " # OVERRALL_STEER_CHASSIS # " %");
debug("Left Wheel steer: " # LEFT_STEER # " %");
debug("Right Wheel steer: " # RIGHT_STEER # " %");
debug("Left/Right Wheels Gap: " # Integer(RIGHT_WHEEL_LOCAL-LEFT_WHEEL_LOCAL));
debug("Left Mouse Button = accelerate");
debug("Right Mouse Button = decelerate / retro");
debug("Keyboard Arrows = Left/Right");
debug("8 = Change Camera");
debug("J = Apply an Upward Impulse");
debug("SPACE = HANDBRAKE");
*/

//calculemus 1 - For the torque forcfe applied on Z axis on the motor wheel

MY_YAW = Integer(LEFT_WHEEL_ATTACH.current_yaw / 0.0174532925199433);
MY_YAW_CHASSIS = Integer(CHASSIS_ATTACH.current_yaw / 0.0174532925199433);
LEFT_WHEEL_LOCAL = Integer(LEFT_WHEEL_ATTACH.current_yaw / 0.0174532925199433);
RIGHT_WHEEL_LOCAL = Integer(RIGHT_WHEEL_ATTACH.current_yaw / 0.0174532925199433);

if((MY_YAW > 0)and(MY_YAW <= 90))
{
B_PERC = Integer(100 /(90/(MY_YAW)));
A_PERC = Integer(100 - B_PERC);
}
if((MY_YAW > 90)and(MY_YAW <= 180))
{
A_PERC = -(Integer(100 /(90/(MY_YAW-90))));
B_PERC = Integer(100 + A_PERC);
}

if((MY_YAW > 180)and(MY_YAW <= 270))
{
B_PERC = -(Integer(100 /(90/(MY_YAW-180))));
A_PERC = -(Integer(100 + B_PERC));
}
if((MY_YAW > 270)and(MY_YAW <= 360))
{
A_PERC = Integer(100 /(90/(MY_YAW-270)));
B_PERC = -(Integer(100 - A_PERC));
}

if(MY_YAW = 0)
{
B_PERC=0;
A_PERC=100;
}

//calculemus 2 - For the Twist to be applied on Y axis on the steering wheel

MIX_STEER_LOCAL = OVERRALL_STEER_CHASSIS - OVERRALL_STEER;

if(MY_YAW>0)
{
OVERRALL_STEER = Integer(100 /(360/(MY_YAW)));
}
else
{
OVERRALL_STEER = 0;
}

if(MY_YAW_CHASSIS>0)
{
OVERRALL_STEER_CHASSIS = Integer(100 /(360/(MY_YAW_CHASSIS)));
}
else
{
OVERRALL_STEER_CHASSIS = 0;
}

if((RIGHT_WHEEL_LOCAL) > 0)
{
RIGHT_STEER = Integer(100 / (360/(RIGHT_WHEEL_LOCAL)));
}
else
{
RIGHT_STEER = 0;
}

if((LEFT_WHEEL_LOCAL) > 0)
{
LEFT_STEER = Integer(100 / (360/(LEFT_WHEEL_LOCAL)));
}
else
{
LEFT_STEER = 0;
}

MIX_STEER = (RIGHT_STEER - LEFT_STEER);


if((MIX_STEER > -25)or(MIX_STEER < 25))
{
MIX_STEER_GLOBAL = (MIX_STEER);
}

if(MIX_STEER < -75)
{
MIX_STEER_GLOBAL = (100+MIX_STEER);
}
if(MIX_STEER > 75)
{
MIX_STEER_GLOBAL = (100-MIX_STEER);
}


} ]

}
User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico »

Nout, now again my complain is not being able to compile the RF with physics source and check the following ideas by myself. Navigating the source and I ask mysel if itis possible to have an internal yaw detection for physic object (and nevermore use the pawn attached to the wheels PhysicsBody. Isn't possible to replicate in pawn script the current_yaw variable?
Pratically, adding to this:

Code: Select all

bool PhysicsControllerObject::getValue(const skString& fieldName, const skString& attribute, skRValue& value)
, this:
else if (fieldName == "current_yaw")
{
GetAngles(true);
value = actoryaw;
return true;
}
and somewhere you know:

Code: Select all

void ScriptedObject::GetAngles(bool flag)
{
	geVec3d Pos, Orient, Play;

	Play = LastTargetPoint;
	CCD->ActorManager()->GetPosition(Actor, &Pos);
	geVec3d_Subtract(&Play, &Pos, &Orient);
	float l = geVec3d_Length(&Orient);
	if(l > 0.0f) 
	{
		float x = Orient.X;
		Orient.X = (float)( GE_PI*0.5 ) - 
			(float)acos(Orient.Y / l);
		Orient.Y = (float)atan2(x , Orient.Z ) + GE_PI;
		CCD->ActorManager()->GetRotate(Actor, &Pos);
		while(Pos.Y<0.0f)
		{
			Pos.Y+=(GE_PI*2);
		}
		while(Pos.Y>=(GE_PI*2))
		{
			Pos.Y-=(GE_PI*2);
		} 
		while(Pos.X<0.0f)
		{
			Pos.X+=(GE_PI*2);
		}
		while(Pos.X>=(GE_PI*2))
		{
			Pos.X-=(GE_PI*2);
		}
	}
	actoryaw = Pos.Y;
	targetyaw = Orient.Y;
	actorpitch = Pos.X;
	targetpitch = -Orient.X;
}
(probably void PhysicsControllerObject)
Now there are EntityName problems calling that command, should this add solve them or the problem is that completely lacks the scripted instrucion for current_yaw? And furthermore will the Genesis GetAngles function works with Tokamak? ....
________
User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico »

Ah, before I forgot...
1)GetAngleBetweenBodies works good with object that don't move but it seems that the result for objects rotating and moving isn't what we are looking for.
2) when i said that it would be easier see the joints like scriptpath I was referring to the ai path finding features of RF. To make it easy, you can turn on the "See ScriptPath" button in the inieditor.exe and you can see the scriptpoint in the level, otherwise invisible, marked as red dots and blu lines drawing the actual alignement and connection between them. Now I have a little experiene on this, but at the beginning it was an headache to think about how (and where) to place correctly the joint in respect of the connected body. At the beginning it would be much more simple to see it graphically. I think that this feature could come later, and we can help you to implement it. you don't have to do ALL alone ALL the work... :wink:
Nout
Posts: 136
Joined: Tue Jul 05, 2005 5:14 pm

Post by Nout »

Nout, now again my complain is not being able to compile the RF with physics source
In the next release I'll put the complete source directory with libs etc...
Navigating the source and I ask mysel if itis possible to have an internal yaw detection for physic object (and nevermore use the pawn attached to the wheels PhysicsBody.
This is what is done in the source code. I'm not using a hinge, but geometry fixed attached to a body. The nice thing is that is call backs, you can change the orientation etc... of 1 geometry, without touching the body. I'm working on a script command that allows the same (I hope it will not interfere with Tokamak).
Isn't possible to replicate in pawn script the current_yaw variable?
It's easy to add the yaw-code into the physics script language, but it will read the orientation from the actor, not from the geometry. In theory this should be the same, so I will add the code, and we can test it.
Now there are EntityName problems calling that command, should this add solve them or the problem is that completely lacks the scripted instrucion for current_yaw?
I've added a few new script command by which you can retrieve the actor connected to a body or the other way around. This makes it easier to link pawns to physics.
And furthermore will the Genesis GetAngles function works with Tokamak? ....
Tokamak offers similar rotation functions and they can be converted and exchanged with Genesis.

In RF, I'm planning to convert your car script into a coded car that uses geometry, rather then a hinge to do the stearing. For the wheels, hinges are easier, as they immediately support the rotation in a correct way, even when the car crashed upside down and the wheel is still rolling. With geometry, you have to "code" the rotation, so it's never so realistic as the hinge. The idea is to replace your double hinge for the front wheels by a geometry + hinge and keep a hinge for the rear wheels. The geometry will also immediately handle the suspension part.
the nice thing, it that I most likely can convert this part also in a new script command (a hinge + geometry + spring in 1 command) that can be used for self-scripted cars. Another thing I'd like to make is a double geometry that works as a spring + again offer it as a script command. These 2 things sounds like great added value?
User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico »

not really a modelers corner topic nor a programming topic...

anyway, playing with the physic and ansiouslywaiting for the new release prepared some cars to test it.
I found a way to convert the gta3 car in RF and use it with my car script. (Spyrewolf is probably going crazy at this moment...)
You need Zmodeler 1.8 ( the old versoin that you can find in the Zmodeler site, ViceTXD (http://www.grandtheftauto.fr/fichiers/5/13.php) to convert the texture, a paint program to flip horizontaly the image (yes, you need it), Milkshape and another 3d modeler/browser to re-convert the 3ds files.
first convert the texture (bitmap+alpha--> TGA-->Normal). then import the dff car in the zmodeler and then export it to 3ds. Now import and re-export the 3ds in another 3d modeler or browser (I use Deep Exploration) because Milkshape don't read the exported mesh properly. Use a paint program to convert the textures to bmp format and filp them horizontally. now they should fit the model. Export bdy etc..etc..
GTA models:
http://www.polycount.com
http://gtacomplex.com

P.S. look at the car doors... they are connected by hinges.
______
@ Nout
Yeah!!!!! :wink:
Now I slowly begin to understand callbacks (theorically). Good work to you again, master...
Attachments
screen006.jpg
screen006.jpg (7.58 KiB) Viewed 1797 times
screen002.jpg
screen002.jpg (8.5 KiB) Viewed 1798 times
User avatar
Spyrewolf
Posts: 450
Joined: Tue Jul 05, 2005 4:53 am
Location: Wellington::New Zealand

Post by Spyrewolf »

(Spyrewolf is probably going crazy at this moment...)
You Bet! :o
Federico this is AMAZING!, with both of these elements in place this is gonna open up so many possibilities, having a car which we can pop in to a game is gona be a huge time saver!

federico, are we allowed to place these scripts in our games?(with the proper credit of course!) for me this is invaluable asset which i need for my game!

my thanks goes out to both nout and federico for contributing so MUCH!, and our games are gonna be so much better because of which!

BIG UPS GUYS!!!!!!
User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico »

An old refrain sings that justice is to give everyone its due, but it would be paradoxal if you can't use a script wrote for an open-source engine... :wink:
Sure, you can use it giving the proper credits (most of all to Nout) but you don't need to ask it...what a well-mannered guy :lol: !
naturally you better may wait for the coded implementation by Nout, and I can say you that is not the whole story, probably we have to make the character "jump" in the car and drive. Now I'm thinking about how to have car ai and I have some preliminar idea...
Nout
Posts: 136
Joined: Tue Jul 05, 2005 5:14 pm

Post by Nout »

Frederico,

About CAR_AI:
In your thoughts. consider that with some tricks, we most likely can reuse AI that is available to Pawns.
Guest

Post by Guest »

naturally. I'm thinking to use the standard pathfinding but I want to have the standard car behaviour so I fiink to have a "double-face" script that works with the player/driver and the ai/driver.
Some thing like:
if(((self.key_pressed=55)=true)or(AI_ACCELERATE=true))
{
// accellerate
}
if(((self.key_pressed=56)=true)or(AI_DECELERATE=true))
{
// decellerate*BRAKE_FORCE
}
if(((self.key_pressed=46)=true)or(AI_BRAKE_AND_STOP=true))
{
// stop
}

for every drivng action and then activate the actions for correctly navigate the scriptpath. Besides that I'm thinking to oganize the scriptpath depending on type. for example:
1) all the scriptpoints name in a straight way begins with "A_",
2) all the scriptpoints name in front of a curve begins with "B" followed by 5 numbers as types of curve strictness,
3) all the scriptpoints name in brake point begins with "C",

so the AI can "read" the road and apply the correct behaviour.
if(LeftCopy(self.point_name, 2)="A_)
{
ACCELERATE=TRUE;
}
if(LeftCopy(self.point_name, 1)="B")
{
switch(LeftCopy(self.point_name, 2)="B1")
{
case("B1")
{
DECELERATE=TRUE;
BRAKE_FORCE=1;
}
case("B2")
{
DECELERATE=TRUE;
BRAKE_FORCE=2;
}
etc..etc...
}
}
if(LeftCopy(self.point_name, 2)="C_)
{
BRAKE_AND_STOP=TRUE;
}

}
naturally i'm an optimist... :wink:
@Nout
Have you receibed my car?
Now I understand you when you are talking about geometry and hinges. In this case we will have hinges for the wheel rotation but programmed geometry for suspension and steer. In this way the weaker part of the script , that is the auto-alignement routine of the non-driven wheel, is no more a problem. Am I right?
User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico »

not logged in, sorry
Post Reply