I have asked this, already, but not at this forum...
BlitzPlus Forums/BlitzPlus Programming/I have asked this, already, but not at this forum...
| ||
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 |
| ||
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] |