Game Scripting

All about making tracks for MX Simulator
jlv
Site Admin
Posts: 15016
Joined: Fri Nov 02, 2007 5:39 am
Team: No Frills Racing
Contact:

Re: Game Scripting

Post by jlv »

DJ99X wrote:Does it only look at frills.js? Or should it read any script located in the folder? I guess mx.frame_handler can only be defined once.
It only looks in frills.js. The idea is frills.js will just have cosmetic stuff that doesn't matter for the track checksum. I'm eventually going to add another file for stuff that can physically change things which will have to be part of the checksum.

You can only set mx.frame_handler once. The standard technique to define multiple handlers is to chain them like this:

Code: Select all

function my_frame_handler(seconds) {
   do_stuff();
   previous_frame_handler(seconds);
}
var previous_frame_handler = mx.frame_handler;
mx.frame_handler = my_frame_handler;
Nice script btw! Definitely wouldn't stay in sync online though.
Josh Vanderhoof
Sole Proprietor
jlv@mxsimulator.com
If you email, put "MX Simulator" in the subject to make sure it gets through my spam filter.
DJ99X
Posts: 15523
Joined: Tue Jan 15, 2008 11:36 am
Location: Land Down Under

Re: Game Scripting

Post by DJ99X »

Would the script that will physically change things need to managed by the server to keep things in sync?
jlv
Site Admin
Posts: 15016
Joined: Fri Nov 02, 2007 5:39 am
Team: No Frills Racing
Contact:

Re: Game Scripting

Post by jlv »

Depends on what it's doing. For something simple like moving an object at a specific time it wouldn't need help from the server. For moto-soccer it'd definitely need to communicate through the server.
Josh Vanderhoof
Sole Proprietor
jlv@mxsimulator.com
If you email, put "MX Simulator" in the subject to make sure it gets through my spam filter.
DJ99X
Posts: 15523
Joined: Tue Jan 15, 2008 11:36 am
Location: Land Down Under

Re: Game Scripting

Post by DJ99X »

JLV, how do you handle the rider bones (or 3d rotations in general)?

I've been struggling to come up with a way deal with the rotation. I initially started by converting a euler rotation to a matrix, and tried running the rotations shown in pose mode in blender, but those rotations are with respect to the bones initial orientation, so it never worked. In the end, I struggled to grasp rotations other than rotating around a single axis.

I am now trying quaternions, as I figured it's fundamentally a 3d vector with rotation , but once I had it operational, I then realised if the rotation angle of the quaternion is 0, then it equates to the unit matrix [1 0 0, 0 1 0, 0 0 1] regardless of the xyz vector, which doesn't make sense to me.
jlv
Site Admin
Posts: 15016
Joined: Fri Nov 02, 2007 5:39 am
Team: No Frills Racing
Contact:

Re: Game Scripting

Post by jlv »

A rotation of 0 has to be the identity matrix. It doesn't move the vertices so the matrix can't either.

A matrix is basically just a coordinate system. The first column is the X axis, the second column is the Y axis and the third is the Z axis. If you want to transform a vector from that coordinate system, you scale each axis vector by its corresponding vector element and add them together like this:

V' = X * v0 + Y * v1 + Z * v2

That's the same as a matrix * vector multplication:

V = [ v0, v1, v2]
X = [ m00, m10, m20]
Y = [ m01, m11, m21]
Z = [ m02, m12, m22]

v0' = m00 * v0 + m01 * v1 + m02 * v2
v1' = m10 * v0 + m11 * v1 + m12 * v2
v2' = m20 * v0 + m21 * v1 + m22 * v2

Now say you want to aim the Z axis at the vector P.

First set Z. Since you want it to point at P you set it to P, but since you don't want it to scale, divide by the length of P to get a unit length vector.

Z = P / |P|

Now for Y. Say you want it to generally point up, so we temporarily set it to the global Y. This is going to make it a shear matrix which we don't want, but we'll fix that later.

Y = [ 0, 1, 0 ]

For X you just want it to be perpendicular to Y and Z. So you set it to the cross product:

X = Z x Y

Now fix Y so it's perpendicular to X and Z:

Y = X x Z

Normalize X and Y and you're done.

X = X / |X|
Y = Y / |Y|

Now you should have a square and unit length rotation matrix where Z points at P. I didn't give any thought to the cross product order, so you'll probably have to flip either X or Y to get the right sign.

Since OpenGL stores matrices in column major order, your matrix should look like this:

m = [
x0, x1, x2,
y0, y1, y2,
z0, z1, z2
];

(If you remember the Patriot missile bug, this is related. They continuously concatenated rotation matrices without squaring them up and normalizing them. If the guidance system ran long enough the matrix would turn into a scaling and shearing matrix as the numeric errors accumulated.)
Josh Vanderhoof
Sole Proprietor
jlv@mxsimulator.com
If you email, put "MX Simulator" in the subject to make sure it gets through my spam filter.
jlv
Site Admin
Posts: 15016
Joined: Fri Nov 02, 2007 5:39 am
Team: No Frills Racing
Contact:

Re: Game Scripting

Post by jlv »

Here's an example for you DJ. This will make the green cube look at the leader.

Code: Select all

function dot_product_v3(a, b) {
	return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}

function length_v3(v) {
	return Math.sqrt(dot_product_v3(v, v));
}

function subtract_v3(a, b) {
	var r = [];	

	r[0] = a[0] - b[0];
	r[1] = a[1] - b[1];
	r[2] = a[2] - b[2];

	return r;
}

function scale_v3(v, s) {
	var r = [];

	r[0] = v[0] * s;
	r[1] = v[1] * s;
	r[2] = v[2] * s;

	return r;
}

function cross_product_v3(x, y) {
	var z = [];

	z[0] = x[1] * y[2] - x[2] * y[1];
	z[1] = x[2] * y[0] - x[0] * y[2];
	z[2] = x[0] * y[1] - x[1] * y[0];

	return z;
}

function normalize_v3(v) {
	return scale_v3(v, 1.0 / length_v3(v));
}

function look_at(p) {
	var x, y, z;

	z = scale_v3(p, -1.0 / length_v3(p));
	y = [ 0, 1, 0 ];
	x = cross_product_v3(y, z);
	x = normalize_v3(x);
	y = cross_product_v3(z, x);
	/* y should be unit length since x and z are unit length and perpendicular */

	return [
	 x[0], x[1], x[2],
	 y[0], y[1], y[2],
	 z[0], z[1], z[2]
	];
}

function leader_location() {
	var r;

	r = mx.get_running_order();

	return mx.get_position(r[0].slot);
}

function look_at_leader() {
	var statue_index = 0;
	var bone_count = 2;
	var bone_centers = [ 0, 0, 0, 0, 0, 0 ];
	var bone_positions = [ 0, 0, 0, 0, 0, 0 ];
	var bone_r_0 = [
	 1, 0, 0,
	 0, 1, 0,
	 0, 0, 1,
	];
	var bone_r_1;
	var p = [ 1265, 0, 1065 ];
	var angle = 0;

	bone_r_1 = look_at(subtract_v3(leader_location(), p));
	mx.pose_statue(statue_index, bone_count, bone_centers, bone_positions, bone_r_0.concat(bone_r_1));
	mx.move_statue(statue_index, p[0], p[1], p[2], angle);
}
Josh Vanderhoof
Sole Proprietor
jlv@mxsimulator.com
If you email, put "MX Simulator" in the subject to make sure it gets through my spam filter.
DJ99X
Posts: 15523
Joined: Tue Jan 15, 2008 11:36 am
Location: Land Down Under

Re: Game Scripting

Post by DJ99X »

Thanks JLV, that's all pretty helpful. This has definitely been a mission of extracting some long lost mathematics from deep within my memory. The cross product came in helpful for working out terrain normals

I've got a soccer ball with some good physics going, but I was just neatening up the code, and I must have changed something, because now the ball wants to accelerate up steep vertical terrain :'(
DJ99X
Posts: 15523
Joined: Tue Jan 15, 2008 11:36 am
Location: Land Down Under

Re: Game Scripting

Post by DJ99X »

Here's my soccer ball test. Just some files to chuck into the waterloo folder.

https://ufile.io/k9bad

Image

Generally works pretty well, 2 things I need to fix:

-Handle the y-axis rotation with the bones only, to stop the jerky rotation at slow speeds and the rotation effect of the terrain under the object
-I set the y position to the ground position if it is calculated lower. Unfortunately, the y velocity isn't adjusted to reflect this change when it's rolling, so it ends up a bit mismatched to what the ball is meant to be doing. This generally occurs on steep surfaces where sudden changes in ground height means the y position requires adjustment, so it looks like it accelerates up hills. I tried to predict the ground in front of the ball and adjust the velocity to suit, but it didn't really work out.
Smidly
Crushed Dissenter
Posts: 330
Joined: Wed May 30, 2018 2:56 am
Team: Wildside
Location: JLV's Basement

Re: Game Scripting

Post by Smidly »

DJ99X wrote:Here's my soccer ball test. Just some files to chuck into the waterloo folder.

https://ufile.io/k9bad

Image
That is so fucking cool
jlv
Site Admin
Posts: 15016
Joined: Fri Nov 02, 2007 5:39 am
Team: No Frills Racing
Contact:

Re: Game Scripting

Post by jlv »

I should probably add a move function that lets you set the y position and orientation matrix directly.
Josh Vanderhoof
Sole Proprietor
jlv@mxsimulator.com
If you email, put "MX Simulator" in the subject to make sure it gets through my spam filter.
DJ99X
Posts: 15523
Joined: Tue Jan 15, 2008 11:36 am
Location: Land Down Under

Re: Game Scripting

Post by DJ99X »

Image
wheels1758
Posts: 4132
Joined: Tue Oct 21, 2008 5:20 pm
Location: Washington, USA
Contact:

Re: Game Scripting

Post by wheels1758 »

DJ99X wrote:Image
That's pretty sweet DJ! Now make it randomize with wind :lol:
DJ99X
Posts: 15523
Joined: Tue Jan 15, 2008 11:36 am
Location: Land Down Under

Re: Game Scripting

Post by DJ99X »

It does change directions slightly in that particular gif. But yeah, next thing to try and do is change its behaviour with speed. Just need to work out the best way to collapse it on low wind speed.
wheels1758
Posts: 4132
Joined: Tue Oct 21, 2008 5:20 pm
Location: Washington, USA
Contact:

Re: Game Scripting

Post by wheels1758 »

DJ99X wrote:It does change directions slightly in that particular gif. But yeah, next thing to try and do is change its behaviour with speed. Just need to work out the best way to collapse it on low wind speed.
Is it rows of bones or a single row?
jlv
Site Admin
Posts: 15016
Joined: Fri Nov 02, 2007 5:39 am
Team: No Frills Racing
Contact:

Re: Game Scripting

Post by jlv »

That's pretty neat! How do you have it rigged? Looking at some flag waving videos it looks like the waves tend to run across the flag radially from the inner top corner. So maybe try making the bone influence run across the flag something like this:

44444444
01223333
00112233
00111122

Put the bone centers on the inner top corner and then just rotate the bones to make the waves.
Josh Vanderhoof
Sole Proprietor
jlv@mxsimulator.com
If you email, put "MX Simulator" in the subject to make sure it gets through my spam filter.
Post Reply