3D rotation and projection in Assembler
Author Message 3D rotation and projection in Assembler

Hi,
O.K - I've coded a small 3d Engine in PC Assembler using the FPU for
everything (works Beautifully - nice and fast).  Only problem is :- my
rotated point number range is all in +10.0000000.......-10.000000000.
I want to project my 3d point to the 2d (320x200 mode 13h) screen.
My old formula for this in fixed point using Pascal  was :
x_plot := 160 + (x shl 8)  div (z - zeye) ; { comment : the  zeye value was
:=  -200 shl 7}
y_plot:= 100 + (y shl 8) div (z-zeye);
If I just ignore z,   and scale(multiply and integer store) my x and y value
by say 10 and plot - I get an OK result (so I know everything should be
working).  Obviously to Perspective Project I'll have to come up with the
Assembler Implementation. Hopefully without adding much extra clock cycles
to the routine. I would deary love my proggie to be superfast (so I can add
shading, textures,  camera's,  lightsourcing............ect.  in the near
future.)
Anybody been thru this ?

Sat, 02 Feb 2002 03:00:00 GMT  3D rotation and projection in Assembler

Quote:
> My old formula for this in fixed point using Pascal  was :
> x_plot := 160 + (x shl 8)  div (z - zeye) ; { comment : the  zeye value was
> :=  -200 shl 7}
> y_plot:= 100 + (y shl 8) div (z-zeye);

Ok, looks like the normal 3D to 2D projection formula:

x2d = (x3d*perspective / (z+perspective)) + 160
y2d = (y3d*perspective / (z+perspective)) + 100

(where +160 and +100 centres the point in 320x200 mode)

Usually perspective is set to 256, thereby avoiding a mul (using shl
instead). By introducing a zoom factor you can position the point on
the z-axis (sort of scaling things):

x2d = (x3d*perspective / (z+perspective+zoom)) + 160
y2d.... same thing.

Quote:
> If I just ignore z,   and scale(multiply and integer store) my x and y value

"Just ignoring" things in the 3D world is never a good thing :-)
During a week of learning the basics I wrote a ca 2000 lines simple
Rotate-A-Cube-With-A-Bit-Of-Light program. Here's the 3Dto2D plotting
routine (which I believe you asked for):

[...]
lea di,Cube2D          ;Address of 2D array (for stosw, ES:DI)
lea si,TmpCube3D       ;Address of 3D array (for lodsw, DS:SI)
mov ecx,8              ;Plotting 8 points.
Call Object3dTo2d
[...]

Object3dTo2d Proc

Convert3d:

xor eax,eax            ;Cleaning eax from leftovers.

lodsw                  ;getting 3dX word.
mov fs,ax              ;Temporary save.
lodsw                  ;getting 3dY word.
mov gs,ax              ;Temporary save.
lodsw                  ;getting 3dZ word.

movsx eax,ax           ;Extending signed value of 3dZ.
add eax,256    ;Adding Perspective (256) + Zoom (0 - ...) to 3dZ.
mov ebx,eax    ;Putting result in ebx (preparing for division).
cmp ebx,0

mov eax,fs             ;Retrieve 3dX word.
movsx eax,ax           ;Extending signed value of 3dX.
shl eax,8                      ;Multiply 3dX by Perspective (256).
cdq                    ;Convert double to quad eax -> edx:eax.
idiv ebx                       ;Signed division edx:eax / ebx.
stosw                  ;Save in 2d array.

mov eax,gs             ;Retrieve 3dY word.
movsx eax,ax           ;Extending signed value of 3dY.
shl eax,8                      ;Multiply 3dY by Perspective (256).
cdq                    ;Convert double to quad eax -> edx:eax.
idiv ebx                       ;Signed division edx:eax / ebx.
stosw                  ;Save in 2d array.

loop Convert3d         ;Loop until ecx = 0.

ret
Object3dTo2d EndP

Not optimized of course... Making things work was my primary
objective.

--

/Homing device: president, bomb, gold, terrorism, cipher...

Sun, 03 Feb 2002 03:00:00 GMT

 Page 1 of 1 [ 2 post ]

Relevant Pages