I have asked this, already, but not at this forum...

BlitzPlus Forums/BlitzPlus Programming/I have asked this, already, but not at this forum...

3DBuzzFan(Posted 2003) [#1]
Sorry for the multiple posts (you´ll find this at the "advanced 3d" forums, too).
But Ross C just pointed that this could be the right place to ask this.
If I don´t get an asnwer here, I will not post it again --- promisse :^)

Quick question:

Can I rely on normals for backface-culling, on a software-only 3d rendering system?
I ask that because I wrote a small piece of B+ code, and it is not working properly.
Actualy, it DOES, when I rotate around the y and/or z axis.
But,when I rotate around the x axis, the normals don´t seem to rotate right.
Yeah, I already know that Euler angles are evil --- and am aware of gimbal lock, but that doesn´t seem to be the case here, ´cause when I rotate around the y AND z axis, simultaneously, the backface culling works fine.
But, when I rotate around the X axis (alone), it doesn´t work, no matter what.
Maybe I am mssing something, and one should not use the normals for backface culling, because that might be the wrong way to do it.
But it just makes perfect sense to me.
Can you help me out?
Thanks,

BTW: Here´s the code, just in case you or someone else would like to help me...
(Remember: it is Blitz Plus, NOT Blitz 3D --- this is a study code, and is not meant to be used to create any fancy 3d engine hehe... I am just trying to get into the maths of 3d, before starting using the 3d stuff that is available on B3d; You know... do just what you did... learn how it works before using it)


Dim x#(16, 9)
Dim y#(16, 9)
Dim z#(16, 9)
;
Dim rx#(16, 9)
Dim ry#(16, 9)
Dim rz#(16, 9)
;
Dim nx#(16, 9)
Dim ny#(16, 9)
Dim nz#(16, 9)
;
Dim rnx#(16, 9)
Dim rny#(16, 9)
Dim rnz#(16, 9)
;
Global a# = 0.00
Global b# = 0.00
Global g# = 0.00



Graphics 1024, 768, 16, 0



For i% = 0 To 15
For j% = 0 To 8
r# = Sin#(22.50 * j%)
x#(i%, j%) = Cos#(22.50 * i%) * r#
y#(i%, j%) = Cos#(22.50 * j%)
z#(i%, j%) = -Sin#(22.50 * i%) * r#
Next
Next



For i% = 0 To 15
For j% = 0 To 8
x0# = +x#(i%, j%)
y0# = -y#(i%, j%)
z0# = +z#(i%, j%)
x1# = +x#((i% + 1) Mod 16, j%)
y1# = -y#((i% + 1) Mod 16, j%)
z1# = +z#((i% + 1) Mod 16, j%)
x2# = +x#((i% + 1) Mod 16, (j% + 1) Mod 9)
y2# = -y#((i% + 1) Mod 16, (j% + 1) Mod 9)
z2# = +z#((i% + 1) Mod 16, (j% + 1) Mod 9)
x3# = +x#(i%, (j% + 1) Mod 9)
y3# = -y#(i%, (j% + 1) Mod 9)
z3# = +z#(i%, (j% + 1) Mod 9)
If Abs(x2# - x3#) < 0.001 Then
dx1# = x2# - x0#
dy1# = y2# - y0#
dz1# = z2# - z0#
dx2# = x2# - x1#
dy2# = y2# - y1#
dz2# = z2# - z1#
Else
dx1# = x3# - x1#
dy1# = y3# - y1#
dz1# = z3# - z1#
dx2# = x3# - x2#
dy2# = y3# - y2#
dz2# = z3# - z2#
EndIf
nx#(i%, j%) = (dy1# * dz2#) - (dz1# * dy2#)
ny#(i%, j%) = (dz1# * dx2#) - (dx1# * dz2#)
nz#(i%, j%) = (dx1# * dy2#) - (dy1# * dx2#)
l# = Sqr#((nx#(i%, j%) * nx#(i%, j%)) + (ny#(i%, j%) * ny#(i%, j%)) + (nz#(i%, j%) * nz#(i%, j%)))
nx#(i%, j%) = nx#(i%, j%) / l#
ny#(i%, j%) = ny#(i%, j%) / l#
nz#(i%, j%) = nz#(i%, j%) / l#
Next
Next



Repeat
Cls()
rotateVertices(a#, b#, g#)
rotateNormals(a#, b#, g#)
drawSphere()
Flip()
If KeyDown(30) Then
a# = a# + 1.00
While a# > 360.00
a# = a# - 360.00
Wend
EndIf
If KeyDown(44) Then
a# = a# - 1.00
While a# < 0.00
a# = a# + 360.00
Wend
EndIf
If KeyDown(31) Then
b# = b# + 1.00
While b# > 360.00
b# = b# - 360.00
Wend
EndIf
If KeyDown(45) Then
b# = b# - 1.00
While b# < 0.00
b# = b# + 360.00
Wend
EndIf
If KeyDown(32) Then
g# = g# + 1.00
While g# > 360.00
g# = g# - 360.00
Wend
EndIf
If KeyDown(46) Then
g# = g# - 1.00
While g# < 0.00
g# = g# + 360.00
Wend
EndIf
Until KeyHit(1)
End



Function rotateVertices(alpha#, betha#, gamma#)
For i% = 0 To 15
For j% = 0 To 8
xl0# = x#(i%, j%)
yl0# = y#(i%, j%)
zl0# = z#(i%, j%)
xl1# = (Sin#(betha#) * zl0#) + (Cos#(betha#) * xl0#)
yl1# = yl0#
zl1# = (Cos#(betha#) * zl0#) - (Sin#(betha#) * xl0#)
xl2# = xl1#
yl2# = yl1# * Cos#(alpha#) - zl1# * Sin#(alpha#)
zl2# = yl1# * Sin#(alpha#) + zl1# * Cos#(alpha#)
rx#(i%, j%) = yl2# * Sin#(gamma#) + xl2# * Cos#(gamma#)
ry#(i%, j%) = yl2# * Cos#(gamma#) - xl2# * Sin#(gamma#)
rz#(i%, j%) = zl2#
Next
Next
End Function



Function rotateNormals(alpha#, betha#, gamma#)
For i% = 0 To 15
For j% = 0 To 8
xl0# = nx#(i%, j%)
yl0# = ny#(i%, j%)
zl0# = nz#(i%, j%)
xl1# = zl0# * Sin#(betha#) + xl0# * Cos#(betha#)
yl1# = yl0#
zl1# = zl0# * Cos#(betha#) - xl0# * Sin#(betha#)
xl2# = xl1#
yl2# = yl1# * Cos#(alpha#) - zl1# * Sin#(alpha#)
zl2# = yl1# * Sin#(alpha#) + zl1# * Cos#(alpha#)
rnx#(i%, j%) = yl2# * Sin#(gamma#) + xl2# * Cos#(gamma#)
rny#(i%, j%) = yl2# * Cos#(gamma#) - xl2# * Sin#(gamma#)
rnz#(i%, j%) = zl2#
Color 255, 255, 255
Text 100 + 100 * j%, 100 + 20 * i%, rnz#(i%, j%)
Next
Next
End Function



Function drawSphere()
For i% = 0 To 15
For j% = 0 To 7
x0# = +rx#(i%, j%) * 100.00 + 512.00
y0# = -ry#(i%, j%) * 100.00 + 384.00
x1# = +rx#((i% + 1) Mod 16, j%) * 100.00 + 512.00
y1# = -ry#((i% + 1) Mod 16, j%) * 100.00 + 384.00
x2# = +rx#((i% + 1) Mod 16, (j% + 1) Mod 9) * 100.00 + 512.00
y2# = -ry#((i% + 1) Mod 16, (j% + 1) Mod 9) * 100.00 + 384.00
x3# = +rx#(i%, (j% + 1) Mod 9) * 100.00 + 512.00
y3# = -ry#(i%, (j% + 1) Mod 9) * 100.00 + 384.00
; If Abs(x2# - x3#) < 0.01 Then
; dx1# = x2# - x0#
; dy1# = y2# - y0#
; dx2# = x2# - x1#
; dy2# = y2# - y1#
; Else
; dx1# = x3# - x1#
; dy1# = y3# - y1#
; dx2# = x3# - x2#
; dy2# = y3# - y2#
; EndIf
; bf# = (dx1# * (dy2# - dy1#)) - ((dx2# - dx1#) * dy1#)


bf# = rnz#(i%, j%)

If bf# > 0.00 Then
If (j And 1) Then
Color 255, 0, 0
Else
Color 0, 255, 0
EndIf
Line x0#, y0#, x1#, y1#
Line x1#, y1#, x2#, y2#
Line x2#, y2#, x3#, y3#
Line x3#, y3#, x0#, y0#
EndIf
Next
Next
End Function


skidracer(Posted 2003) [#2]
I'm not sure where you got your rotation algorithm from but to transform a point around 3 axis of rotation is a little more complicated than 12 mulitplies.

To set up a 3x3 matrix to represent a rotational transformation matrix you need something like this (a,b,c are your alpha, beta, gamma). The following has been optimized with temps holding common subexpressions, on paper you need to work out a 3x3 matix that represents just rotx then roty then rotz then multiply all 3 matrix together (yes order is important).

	t1 = cos(b)
	t2 = cos(a)
	t4 = sin(c)
	t5 = sin(b)
	t6 = (t4*t5)
	t8 = cos(c)
	t9 = sin(a)
	t12 =(t8*t5)
	
	m[0][0] = (t1*t2)
	m[0][1] = (-t6*t2-t8*t9)
	m[0][2] = (-t12*t2+t4*t9)
	m[1][0] = (t1*t9)
	m[1][1] = (-t6*t9+t8*t2)
	m[1][2] = (-t12*t9-t4*t2)
	m[2][0] = t5
	m[2][1] = (t4*t1)
	m[2][2] = (t8*t1)


then you need to multiply each point through the matrix to acheive the transformation:

	tx=x*m[0][0]+y*m[0][1]+z*m[0][2]
	ty=x*m[1][0]+y*m[1][1]+z*m[1][2]
	tz=x*m[2][0]+y*m[2][1]+z*m[2][2]