Mini-3-D Engine ;)

Started by Isegrim, Fri 05/09/2003 18:50:13

Previous topic - Next topic

Isegrim

hi!

I'm trying to make a knight-game, which climaxes in a tournament. One of the disciplines should be crossbow-shooting.

I'd like to make the shooting range as a rendered image, and then calculate the flying path of the bolt (with gravity and wind) three-dimensionally and transform the coordinates real-time into 2d.
Everything works just fine, but I have no idea how the transformation matrix should look like.
I've tried
(u)    (1/z   0    0)  (x)
(v) = (0    1/z   0)*(y)
(w)   (0      0    0)  (z)
but that didn't really work...

maybe anyone knows the correct matrix? (maybe even one where I can match the fov with the render image?)

P.S. That's why I'm so keen on float numbers  ;)
This post was generated automatically and therefore bears no signature.

Fuzzpilz

I don't really see the necessity to use matrices to look at this issue... it's not useful at all from either a mathematical or a practical viewpoint.

But yes, that's pretty much right... you'd get the x and y coordinates on the screen by dividing through z, but it's centered around the point (0,0), so you need to offset it. Also, depending on how you got the three-dimensional coordinates, you might need to flip the sign on the y as well. If it still doesn't work, try multiplying x and y by, say, 256 before the division, then dividing again. That should improve accuracy without forcing you to use a floating point plugin.

Isegrim

Well, yeah, the divide-by-z thing basically does what I want. My main problem is, how to match the field-of-view angles of the projected flight path and the shooting range.
Can you suggest anything besides the good old "try and error" method?
This post was generated automatically and therefore bears no signature.

Fuzzpilz

As I said, they're centered around (0,0), which on the screen is the top left corner. Add the coordinates of the point you want to be the centre, and that's all, assuming you've made sure it's all scaled properly.

Gilbert

And remember, only integer operations are allowed in AGS, so all the results in divisions are made into integers automatically. So if you need to have divisions in an expression, it's recommended that the operations be arranged so divisions come to the last, or make the divisions like 1/v to become something like 10000/v and scale it back down in the last operation.

Scorpiorus

#5
Quote from: Isegrim on Sat 06/09/2003 11:34:49
Well, yeah, the divide-by-z thing basically does what I want. My main problem is, how to match the field-of-view angles of the projected flight path and the shooting range.
Can you suggest anything besides the good old "try and error" method?
For a left-handed co-ordinate system (x is positive to the right, y is positive going up and z is positive disappearing into the screen) you can use the next formula:

screenX = focal_distance_x * x / z + xSize;
screenY = -focal_distance_y * y / z + ySize;


All above are when the view camera is located at (0,0,0) and directed along z-axis (positive direction).

x,y,z - 3D co-ordinates
focal_distance - represents the distance from the viewer to the screen. It's usually between 80 and 200.

xSize, ySize - resolution (in AGS: 320x200, 320x240, 400x300 because RawDraw* family functions use only these resolutions).

-Cheers

Isegrim

#6
Hooray!

After a long frustrated delay, I resumed work on my tournament game and now I have to thank both Scorpiorus (for the correct maths, although I only figured out what he meant after doing it with the intercept theorems (Strahlensätze) myself, which explains the difference between his code and mine) and Fuzzpilz (for his float plugin), because it works quite nicely...

For anyone interested: This is the code with Fuzz's math plugin:
Quote
// script for room: Repeatedly execute
int x1,y1,z1,x2,y2;
x1=int_to_float(GetGlobalInt(1));  
y1=int_to_float(GetGlobalInt(2));  
z1=int_to_float(GetGlobalInt(3));

x2=fdiv(fmul(x1,int_to_float(320)),fadd(int_to_float(320),z1));
y2=fdiv(fmul(y1,int_to_float(320)),fadd(int_to_float(320),z1));

RawDrawCircle (160+float_to_int(x2), 120+float_to_int(y2), 1);

The three GlobalInts are the coordinates (x,y,-z) in a right-handed coordinate system and are changed in the global script by keypresses. So the above code is some kind of mini-3D paint program with a camera angle of 45°
This post was generated automatically and therefore bears no signature.

Scorpiorus

Hey Isegrim,

Glad you worked it out. Sorry for my poor explanation, but on the other hand you feel the stuff from inside now. :)

I'd like to play your game, can't wait to see how the engine looks.

~Cheers

Isegrim

Hmm... right now it is still at a VERY experimental stage...
But I'm in a quite productive mood right now, so I hope I can put online the tournament section as stand-alone game within this month!

P.S. But don't expect human knights...
That's what my little warriors look like:


This post was generated automatically and therefore bears no signature.

Scorpiorus

Pretty neat. So, the characters are pre-rendered from 3d models.

Isegrim

It sounds as though you are somewhat disappointed...  ;)
The Backgrounds are rendered, too. I use the 3D Calculations just to calculate a crossbow's flight path and the position of a lance's point when jousting. Everything else is done by faking perspective with rendered models and scaling. But still I use the 3D-Position to hide the bolt when it lands behind a wall or the target...

I hope, you are not too disappointed, but I think that AGS would not be the right choice to make much more 3D.

BTW. It was not your explanations that frustrated me, it was rather my laziness  ;D
This post was generated automatically and therefore bears no signature.

Scorpiorus

On the contrary, I really like it. I'm just interested how a prerendered images combined along with a 3d object look like in AGS. Wish you best luck with the project. Hope we'll see a tournament demo soon. ;)

~Cheers

SMF spam blocked by CleanTalk