## A question about model.y velocity

All topics about ZGameEditor goes here.

Moderator: Moderators

jinxtengu
Posts: 72
Joined: Wed Oct 14, 2009 2:05 pm
Contact:

### A question about model.y velocity

Hi,
I'm having a bit of difficulty with something,

what I'm trying to do is project a newly spawned model in the direction that the camera is facing, but I can't quite work out the correct formula to do this.

Apologies for asking such a basic question, thing is I still haven't gotten a real handle on calculating directions from velocity, and velocity to directions in 3d space, it's kind of embarrassing but i'm sure I'll get the hang of it eventually.
Anyway, can anyone offer some suggestions on how to sole this problem?

Kjell
Posts: 1695
Joined: Sat Feb 23, 2008 11:15 pm

### Re: A question about model.y velocity

Hi jinxtengu,
jinxtengu wrote:what I'm trying to do is project a newly spawned model in the direction that the camera is facing, but I can't quite work out the correct formula to do this.
Here's a example for a FPS-esque setup ( mouse + WASD ) that uses camera rotation over the X and Y axes. The thing you want to take a look at in the source is the ZExpression in App.OnUpdate ( with comment "Check this out!" ).

Code: Select all

``````<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" CameraPosition="4 0.5 4" FileVersion="2">
<ZExternalLibrary ModuleName="opengl32">
<Source>
<![CDATA[//

void glBegin(int mode){}
void glEnd(){}
void glVertex3i(int x, int y, int z){}]]>
</Source>
</ZExternalLibrary>
<ZExpression>
<Expression>
<![CDATA[//

centerMouse();]]>
</Expression>
</ZExpression>
<OnUpdate>
<Group Comment="Input">
<Children>
<Group Comment="Axis">
<Children>
<Repeat Name="AxisRepeat" Count="2" WhileExp="//">
<OnIteration>
<ZExpression>
<Expression>
<![CDATA[//

int i = AxisRepeat.Iteration;

//

Axis[i] = 0;

//

AxisPositive.CharCode = AxisMap[i,0];
AxisNegative.CharCode = AxisMap[i,1];]]>
</Expression>
</ZExpression>
<KeyPress Name="AxisPositive" CharCode="87">
<OnPressed>
<ZExpression>
<Expression>
<![CDATA[//

Axis[AxisRepeat.Iteration]++;]]>
</Expression>
</ZExpression>
</OnPressed>
</KeyPress>
<KeyPress Name="AxisNegative" CharCode="83">
<OnPressed>
<ZExpression>
<Expression>
<![CDATA[//

Axis[AxisRepeat.Iteration]--;]]>
</Expression>
</ZExpression>
</OnPressed>
</KeyPress>
</OnIteration>
</Repeat>
</Children>
</Group>
<Group Comment="Key">
<Children>
<ZExpression>
<Expression>
<![CDATA[//

Key[1] = Key[0];
Key[0] = 0;]]>
</Expression>
</ZExpression>
<KeyPress Keys="{">
<OnPressed>
<ZExpression>
<Expression>
<![CDATA[//

Key[0]++;]]>
</Expression>
</ZExpression>
</OnPressed>
</KeyPress>
<ZExpression>
<Expression>
<![CDATA[//

Key[2] = Key[0] && !Key[1];]]>
</Expression>
</ZExpression>
</Children>
</Group>
</Children>
</Group>
<ZExpression Comment="Check this out!">
<Expression>
<![CDATA[// Control camera rotation using mouse

App.CameraRotation.X -= App.MousePosition.Y*0.25;
App.CameraRotation.Y += App.MousePosition.X*0.25;

App.CameraRotation.X = clamp(App.CameraRotation.X, -0.25, 0.25);

// Control camera position using WASD

float t, x, y;

t = App.DeltaTime;

x = App.CameraRotation.X*PI*2;
y = App.CameraRotation.Y*PI*2;

App.CameraPosition.X += (Axis[0]*cos(y)+Axis[1]*sin(y))*2*t;
App.CameraPosition.Z += (Axis[0]*sin(y)-Axis[1]*cos(y))*2*t;

// On left-mouse-button down, shoot bullet

if(Key[2])
{
// Set bullet position to camera
Bullet.Position.X = App.CameraPosition.X;
Bullet.Position.Z = App.CameraPosition.Z;

// Set bullet rotation to camera
Bullet.Rotation.X = 0-App.CameraRotation.X;
Bullet.Rotation.Y = 0-App.CameraRotation.Y;

// Set bullet velocity relative to camera rotation
Bullet.Velocity.X =   sin(y)*cos(x);
Bullet.Velocity.Y = 0-       sin(x);
Bullet.Velocity.Z = 0-cos(y)*cos(x);

createModel(Bullet);
}

//

centerMouse();]]>
</Expression>
</ZExpression>
</OnUpdate>
<OnRender>
<ZExpression>
<Expression>
<![CDATA[// Quick & dirty wireframe environment

glBegin(1);

for(int i=0; i<9; i++)
{
glVertex3i(i, 0, 0); glVertex3i(i, 0, 8);
glVertex3i(0, 0, i); glVertex3i(8, 0, i);
}

glEnd();

//

glBegin(2);
glVertex3i(0, 4, 0);
glVertex3i(8, 4, 0);
glVertex3i(8, 4, 8);
glVertex3i(0, 4, 8);
glEnd();

//

glBegin(1);
glVertex3i(0, 0, 0); glVertex3i(0, 4, 0);
glVertex3i(8, 0, 0); glVertex3i(8, 4, 0);
glVertex3i(8, 0, 8); glVertex3i(8, 4, 8);
glVertex3i(0, 0, 8); glVertex3i(0, 4, 8);
glEnd();]]>
</Expression>
</ZExpression>
</OnRender>
<Content>
<Group Comment="Input">
<Children>
<Group Comment="Axis">
<Children>
<Array Name="Axis" SizeDim1="2"/>
<Array Name="AxisMap" Type="4" Dimensions="1" SizeDim1="2" SizeDim2="2" Persistent="255">
<Values>
<![CDATA[78DA73710C0F060002D80130]]>
</Values>
</Array>
</Children>
</Group>
<Group Comment="Key">
<Children>
<Array Name="Key" Type="4" SizeDim1="3"/>
</Children>
</Group>
</Children>
</Group>
<Group Comment="Bullet">
<Children>
<Model Name="Bullet" Position="7.2203 0.5 6.7303" Rotation="0.0542 1.1424 0" Velocity="-0.7352 0.3338 -0.59">
<OnRender>
<RenderMesh Mesh="BulletMesh"/>
</OnRender>
</Model>
<Mesh Name="BulletMesh">
<Producers>
<MeshSphere Scale="0.125 0.125 0.125" ZSamples="3" RadialSamples="16"/>
</Producers>
</Mesh>
</Children>
</Group>
</Content>
</ZApplication>``````
If your situation is different, please explain and i'll try to provide another example
jinxtengu wrote:Apologies for asking such a basic question, thing is I still haven't gotten a real handle on calculating directions from velocity, and velocity to directions in 3d space, it's kind of embarrassing
No worries, it's not as straight-forward as you might expect.

K

VilleK
Posts: 1975
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

### Re: A question about model.y velocity

Nice example Kjell.

jinxtengu
Posts: 72
Joined: Wed Oct 14, 2009 2:05 pm
Contact:

### Re: A question about model.y velocity

Thanks for the code example Kjell.
I tried to follow it, unfortunately I was unable to get it to work in the game.
Here's the zgeproj file of what I was doing so you can take a look. Clicking the mouse spawns a bullet.
http://www.revengeofthesunfish.com/example1.zgeproj

Kjell
Posts: 1695
Joined: Sat Feb 23, 2008 11:15 pm

### Re: A question about model.y velocity

Hi jinxtengu,

You made a couple of mistakes ...

- Always use local variables when possible .. and otherwise never give components names that collide with properties ( in any scope ). So instead of putting 3 Variable components named "x", "y" and "t" in bulletmodel.Definitions, use local variables as i did in my example.
- Use centerMouse after you've processed the mouse input, not before .. otherwise the mouse input will always be zero So call centerMouse after assigning Facing_z and frontView.
- If you're not using a fixed framerate, always incorporate deltaTime into any variables that are time-based. So instead of incrementing bulletlife by 1 each frame, add App.DeltaTime instead.

Here's your project with just those 3 things changed ( i didn't touch anything else ).

Code: Select all

``````<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" LightPosition="0.21 4 1" FileVersion="2">
<SpawnModel Model="Floormodel2" Position="0 -4 0"/>
<SpawnModel Model="Playermodel"/>
<Content>
<Group Name="materials">
<Children>
<Material Name="bulletmaterial" Color="0.9098 0.1765 0.1765 1"/>
<Material Name="floormaterial" Color="0.2863 0.7961 0.3765 1">
<Textures>
<MaterialTexture Texture="floorbmp" TextureScale="222 222 1" TexCoords="1"/>
</Textures>
</Material>
<Bitmap Name="floorbmp" Width="128" Height="128">
<Producers>
<BitmapFromFile Comment="Imported from skin8.bmp">
<BitmapFile>
</BitmapFile>
</BitmapFromFile>
</Producers>
</Bitmap>
</Children>
</Group> <!-- materials -->

<Group Name="meshes">
<Children>
<Mesh Name="boxmesh">
<Producers>
<MeshBox/>
</Producers>
</Mesh>
<Mesh Name="BasicconeMesh0" Comment="Cone">
<Producers>
<MeshImport>
<MeshData>
<![CDATA[78DA854BC10D8020102B7C34BE5C82399C8C4058CC3DD8041ED61EC4F832DEA5BDF6D26E00768C395FE4E341A9400CA4FED974A94C001983E9D1CBA69549D3299BB5524EB462814753DFC1FC1737CEDB7F93C6173B3D6E98A2228E]]>
</MeshData>
</MeshImport>
</Producers>
</Mesh>
</Children>
</Group> <!-- meshes -->

<Group Name="models">
<Children>
<Model Name="bulletmodel">
<Definitions>
<Variable Name="bulletlife"/>
</Definitions>
<OnSpawn>
<ZExpression>
<Expression>
<![CDATA[float t, x, y;

t = App.DeltaTime;

x = App.CameraRotation.X*PI*2;
y = App.CameraRotation.Y*PI*2;

bulletmodel.Rotation.X = 0-App.CameraRotation.X;
bulletmodel.Rotation.Y = 0-App.CameraRotation.Y;

bulletmodel.Velocity.X =   sin(y)*cos(x);
bulletmodel.Velocity.Y = 0-       sin(x);
bulletmodel.Velocity.Z = 0-cos(y)*cos(x);]]>
</Expression>
</ZExpression>
</OnSpawn>
<OnUpdate>
<ZExpression Expression="bulletlife+=App.DeltaTime;"/>
<Condition Expression=" return bulletlife>=43;">
<OnTrue>
<RemoveModel/>
</OnTrue>
</Condition>
</OnUpdate>
<OnRender>
<UseMaterial Material="bulletmaterial"/>
<RenderMesh Mesh="BasicconeMesh0"/>
</OnRender>
</Model>
<Model Name="Playermodel">
<Definitions>
<Variable Name="Facing_z"/>
<Variable Name="frontView"/>
<Variable Name="PlayerViewAngle"/>
</Definitions>
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[// camera
//*
app.cameraPosition.x=currentModel.position.x;
app.cameraPosition.y=currentModel.position.y;
app.cameraPosition.z=currentModel.position.z;
app.cameraRotation.x=currentModel.rotation.x;
app.cameraRotation.y=currentModel.rotation.y;
app.cameraRotation.z=currentModel.rotation.z;
//*
//mouse controls
Facing_z+=clamp(app.mousePosition.x*0.525,-0.01,0.01);
frontView-=clamp(app.mousePosition.y*.515,-0.01,0.01);
centerMouse();
frontView=clamp(frontView,-0.65,0.65); //look limit
app.cameraRotation.y=Facing_z;
app.cameraRotation.x=frontView;
//*/
// friction
currentModel.velocity.x*=.80;
currentModel.velocity.y*=.01;
currentModel.velocity.z*=.80;]]>
</Expression>
</ZExpression>
<ZExpression>
<Expression>
<![CDATA[App.CameraPosition.Z=CurrentModel.Position.Z;
App.CameraPosition.X=CurrentModel.Position.X;
App.CameraPosition.Y=CurrentModel.Position.Y;
PlayerViewAngle=Facing_z;

CurrentModel.Velocity.Z=0;
CurrentModel.Velocity.X=0;

//CurrentModel.Velocity.Y-=5.5*App.DeltaTime;
CurrentModel.Velocity.Y=clamp(CurrentModel.Velocity.Y,-6,5);]]>
</Expression>
</ZExpression>
<KeyPress Keys="{">
<OnPressed>
<SpawnModel Model="bulletmodel" UseSpawnerPosition="255"/>
</OnPressed>
</KeyPress>
</OnUpdate>
</Model>
<Model Name="Floormodel2" Scale="54 0.01 54">
<OnRender>
<UseMaterial Material="floormaterial"/>
<RenderMesh Mesh="boxmesh"/>
</OnRender>
</Model>
</Children>
</Group> <!-- models -->

</Content>
</ZApplication>``````
K

jinxtengu
Posts: 72
Joined: Wed Oct 14, 2009 2:05 pm
Contact:

### Re: A question about model.y velocity

Thanks Kjell. The example works after making those changes, also thank you for pointing out my mistakes. This is very helpful to me as I don't get feedback very often, so I never know if I'm doing things in a smart way or not.

One other thing, how can we adjust the rotational direction (adjust heading) so the bullet model is moving
in relation to it's x,y,z velocity, and also (separately) in relation to the direction the camera is facing?

Kjell
Posts: 1695
Joined: Sat Feb 23, 2008 11:15 pm

### Re: A question about model.y velocity

Hi jinxtengu,
jinxtengu wrote:One other thing, how can we adjust the rotational direction (adjust heading) so the bullet model is moving
in relation to it's x,y,z velocity, and also (separately) in relation to the direction the camera is facing?
It already does that .. but your cone mesh is pointing into the wrong* direction. So, you need to rotate it 90 degrees and export it again

K

jinxtengu
Posts: 72
Joined: Wed Oct 14, 2009 2:05 pm
Contact:

### Re: A question about model.y velocity

Ahah, cool cool. I suspected that was the problem.

jinxtengu
Posts: 72
Joined: Wed Oct 14, 2009 2:05 pm
Contact:

### Re: A question about model.y velocity

Er, I'm still having a bit of an issue directing moving objects.
I find that this works when run on model update:
CurrentModel.Rotation.Y=Atan2(CurrentModel.velocity.x,CurrentModel.velocity.Z)/(PI*2);

But it only sets the direction for objects moving in a circle and not up and down.
How can we set CurrentModel.Rotation.X and Z, to behave in the same manner?

Kjell
Posts: 1695
Joined: Sat Feb 23, 2008 11:15 pm

### Re: A question about model.y velocity

Hi jinxtengu,

Usually you want to do it the other way around by calculating the velocity from the rotation values. Here's another quick demo ..

Code: Select all

``````<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" LightPosition="0 1 0" FileVersion="2">
<ZExternalLibrary ModuleName="opengl32">
<Source>
<![CDATA[//

void glBegin(int mode){}
void glEnd(){}
void glVertex3i(int x, int y, int z){}]]>
</Source>
</ZExternalLibrary>
<ZExpression>
<Expression>
<![CDATA[//

for(int i=0; i<16; i++)
{
Plane.Position.X = random(4, 4);
Plane.Position.Y = random(2, 2);
Plane.Position.Z = random(4, 4);

Plane.Rotation.Y = rnd();

createModel(Plane);
}]]>
</Expression>
</ZExpression>
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[//

App.CameraRotation.X = 0-App.MousePosition.Y*0.125;
App.CameraRotation.Y = App.MousePosition.X*App.ViewportWidth*0.125/App.ViewportHeight;

//

float x, y;

x = App.CameraRotation.X*PI*2;
y = App.CameraRotation.Y*PI*2;

App.CameraPosition.X = 4-cos(x)*sin(y)*16;
App.CameraPosition.Y =   sin(x)       *16;
App.CameraPosition.Z = 4+cos(x)*cos(y)*16;]]>
</Expression>
</ZExpression>
</OnUpdate>
<OnRender>
<ZExpression>
<Expression>
<![CDATA[//

glBegin(1);

for(int i=0; i<=8; i++)
{
glVertex3i(i, 0, 0); glVertex3i(i, 0, 8);
glVertex3i(0, 0, i); glVertex3i(8, 0, i);
}

glEnd();]]>
</Expression>
</ZExpression>
</OnRender>
<Content>
<Model Name="Plane">
<OnUpdate>
<ZExpression Comment="Check this out!">
<Expression>
<![CDATA[// Animate the plane over the x-axis

Plane.Rotation.X = cos(App.Time+Plane.Personality*PI*2)/16;

// Calculate the velocity from the rotation x & y axes

float x, y;

x = Plane.Rotation.X*PI*2;
y = Plane.Rotation.Y*PI*2;

Plane.Velocity.X = 0-cos(x)*sin(y);
Plane.Velocity.Y =          sin(x);
Plane.Velocity.Z = 0-cos(x)*cos(y);]]>
</Expression>
</ZExpression>
</OnUpdate>
<OnRender>
<UseMaterial Material="PlaneMaterial"/>
<RenderMesh Mesh="PlaneMesh"/>
</OnRender>
</Model>
<Mesh Name="PlaneMesh">
<Producers>
<MeshImport>
<MeshData>
</MeshData>
</MeshImport>
</Producers>
</Mesh>
</Content>
</ZApplication>``````
But in case you absolutely want to calculate the rotation from the velocity vector .. here you go

Code: Select all

``````<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" LightPosition="0 1 0" FileVersion="2">
<ZExpression>
<Expression>
<![CDATA[//

for(int i=0; i<64; i++)
{
Plane.Velocity.X = random(0, 2);
Plane.Velocity.Y = random(2, 2);
Plane.Velocity.Z = random(0, 2);

createModel(Plane);
}]]>
</Expression>
</ZExpression>
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[//

App.CameraRotation.Y = App.MousePosition.X*0.5;

//

float y = App.CameraRotation.Y*PI*2;

App.CameraPosition.X = 0-sin(y)*8;
App.CameraPosition.Z =   cos(y)*8;]]>
</Expression>
</ZExpression>
</OnUpdate>
<Content>
<Model Name="Plane" Velocity="3.9249 1.1064 2.2806">
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[// Apply gravity to velocity.y

Plane.Velocity.Y -= App.DeltaTime;

// Calculate rotation from velocity

float s, x, y, z;

x = Plane.Velocity.X;
y = Plane.Velocity.Y;
z = Plane.Velocity.Z;

s = sqrt(x*x+y*y+z*z);

x /= s;
y /= s;
z /= s;

//

Plane.Rotation.X = asin(y)/PI/2;
Plane.Rotation.Y = atan2(0-x, 0-z)/PI/2;]]>
</Expression>
</ZExpression>
</OnUpdate>
<OnRender>
<UseMaterial Material="PlaneMaterial"/>
<RenderMesh Mesh="PlaneMesh"/>
</OnRender>
</Model>
<Mesh Name="PlaneMesh">
<Producers>
<MeshImport>
<MeshData>
</MeshData>
</MeshImport>
</Producers>
</Mesh>
<Material Name="PlaneMaterial" DrawBackFace="255"/>
</Content>
</ZApplication>``````
K

jinxtengu
Posts: 72
Joined: Wed Oct 14, 2009 2:05 pm
Contact:

### Re: A question about model.y velocity

Thank you for the code examples Kjell