Toby Opferman
http://www.opferman.net
programming@opferman.net
Beginnning 3D Tutor
To start, everyone knows 2D Screen consists of (X, Y) point.
Well, on a 3D Screen, it consists of (X, Y, Z) point.
Y+ -
| /
| /
| /
- __________|/_____________ X+
/
/|
/ |
+Z |
-
It is the same as 2D, except there is a depth (Z) that comes out of
the screen. Now, 3D points are not integers, they are floats, this
is so we can get more precisie images and rotations. To define
a simple 3D point in Assembly, you would just:
Point3D STRUC
X dd ?
Y dd ?
Z dd ?
Point3D ENDS
P Point3D <10.0, 10.0, 10.0>
Now, P is a 3D Point (10.0, 10.0, 10.0)
The above is what you call "local" coordinates. You rotate Local
Coordinates, you Scale Local Coordinates, but that is all.
To Move the Object on the screen, you use World Coordinates, that is
Where the object is in space.
World (0, 0, 300) This is a good Center (mode 13h)
World Point3D <0.0, 0.0, 300.0>
Now, World is a 3D Point.
NewPoints Point3D <0>
Now, To get the NewPoints, you Add World Coordinates to the Local Coordinates.
; Add X
FLD P.X
FADD World.X
FSTP NewPoints.X
; Add Y
FLD P.Y
FADD World.Y
FSTP NewPoints.Y
; Add Z
FLD P.Z
FADD World.Z
FSTP NewPoints.Z
Now, you do the Camera Coordinates. The Camera View is where you are looking
at the object, what side or angle the person is looking at the object.
For our purposes, let's assume just 0's for angles and perspectives.
So, once we added our world coordinates, we are just looking at the front
of the object and we are ready to Project the point to the screen.
Now, we must project NewPoints to the screen.
The Formula is as follows:
ScreenX = Cx*VIEW/Cz + HalfWidth
ScreenY = HalfHeight - Cy*ASPECT*VIEW/Cz
Cx = Camera X
Cy = Camera Y
Cz = Camera Z
Of course, in our example Camera was 0, so Cx was just LocalX + WorldX and
so on.
HalfWidth = Half Screen Width. In 320x200 it's 160.
HalfHeight = Half Screen Height. In 320x200 it's 100.
ASPECT = Aspect Ratio, this kind of streches the Image up and down. Use 1
for normal.
VIEW = Viewing Distance. In mode 13h, 256 works, but it can be a number from
100-300. In 640x480 600 is a good number.
(There are a lot of variations of this code I have seen and
they all work.)
(For the Assembly Code to Plot a 3D Point, Go to Code Section and D/L
The 3D Wire Frame Demo.)
Now you can just Plot ScreenX and ScreenY.
This is 1 way to do projection.
Rotation.
To rotate a point on any axis, it is not too hard.
What ever point you rotate on, that point does not change.
Here's the Formulas for Rotation.
X Axis:
New_y = cos(Radians)*OldY - sin(Radians)*OldZ
New_z = sin(Radians)*OldY + cos(Radians)*OldZ
OldY = New_y
OldZ = New_z
Y Axis:
New_x = cos(Radians)*OldX - sin(Radians)*OldZ
New_z = sin(Radians)*OldX + cos(Radians)*OldZ
OldX = New_x
OldZ = New_z
Z Axis(2D Rotation):
New_x = cos(Radians)*OldX - sin(Radians)*OldY
New_y = sin(Radians)*OldX + cos(Radians)*OldY
OldY = New_y
OldX = New_x
Radians is the Radians of rotation.