Wireframe not working with rotated objects?

Previous topic - Next topic

bigsofty

Hi,

I am trying to create a simple 2D vector view of a 3D GLB scene, so I took X_GETFACE and combined it with X_WORLD2SCREEN(see below) and used it to draw some 2D lines but I've hit a problem. Probably a deal breaker too. You can rotate the scene using the camera and this is reflected in the wireframe view BUT you cant rotate the wireframe object independently of the camera. Even if you rotate the original 3D object.

The modified GLB demo below kinda shows the problem, both wire-frame view and cell shaded view should be in sync but they are not.

Is there a way around it?

Code (glbasic) Select
// Animation Demo
// Start: Friday, March 22, 2002
GLOBAL dtime,fps,delay,phi,permil,ply_x,ply_y,ply_dir,fps_draw

X_LOADOBJ  "moon.ddd", 1
LOADSPRITE "moon.bmp", 1
LOCAL face[]
LOCAL count
LOCAL n=0
LOCAL x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,z
X_CULLMODE 1
WHILE TRUE
X_MAKE3D 1, 1200, 45
X_CAMERA COS(n)*10, SIN(n)*100, SIN(n)*100+50, 0, 0, 0
X_SPOT_LT -2, RGB(255,255,255), 0,50,100,0,10,100,180

phi=phi+GETTIMER()/100
permil=permil+GETTIMER()/20000; IF permil>=1 THEN permil=0
n=GETTIMERALL()/100
// X_ROTATION 270, 1,0,0
X_ROTATION phi, 0,-1,0

X_SETTEXTURE 1,-1
// X_DRAWANIM 1, 0, 128, permil, TRUE

X_DRAWOBJ 1, 2
X_MAKE2D
count = X_NUMFACES(1)
FOR i=0 TO count-1 STEP 2
      X_GETFACE 1, 2, i, face[]
      X_WORLD2SCREEN face[0][0], face[0][1], face[0][2],x1,y1,z
      X_WORLD2SCREEN face[1][0], face[1][1], face[1][2],x2,y2,z
      X_WORLD2SCREEN face[2][0], face[2][1], face[2][2],x3,y3,z
      X_WORLD2SCREEN face[1][0], face[1][1], face[1][2],x4,y4,z
      X_WORLD2SCREEN face[0][0], face[0][1], face[0][2],x5,y5,z
      X_WORLD2SCREEN face[2][0], face[2][1], face[2][2],x6,y6,z
      DRAWLINE x1,y1,x2,y2,RGB(255,0,255)
      DRAWLINE x3,y3,x4,y4,RGB(255,0,255)
      DRAWLINE x5,y5,x6,y6,RGB(255,0,255)
   NEXT

SHOWSCREEN
WEND
Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)

kanonet

You could try using the X_GETMATRIX command and multiply this matrix with your model points, before you use X_World2SCREEN.

Or you just use the OpenGL Wireframe mode: http://www.glbasic.com/forum/index.php?topic=3730.msg27127#msg27127
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Slydog

#2
I didn't actually run your demo, it is looking for a 'moon.ddd' and 'moon.bmp', but I think I understand what you are saying.
The 'X_GETFACE()' command is returning local model coordinates, and not reflected by any current model rotation.
You could take each of these 3 points (for each face) and manually rotate them around the model's center vertex.
(Using COS / SIN on the x,z data since you are rotating around the y axis).
Then take these modified points and continue with the 'X_WORLD2SCREEN' commands.

Or maybe you could 'fake' the model rotation by actually just rotating the camera around the model, not the model around it's center point.  You don't need to display this temporary camera position but just use it for setting up the camera matrix.
(Could it be as simple as if the camera is currently rotated 45 degrees, and the model is rotated 30 degrees, just add (or subtract?) these values for the new temporary camera rotation?)

Somebody more familiar with matrix calculations may offer more advice as it's probably a simple rotation matrix multiplication, not something I've done on purpose (sure I can steal code and apply it if it doesn't need much altering, but coming up the matrix code to begin with is beyond me!)
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

bigsofty

#3
All good points guys, thanks.

I need to render the lines in 2D unfortunately also the 3D OpenGL wire-frame mode is not GLES compatible.

I was hoping to avoid manually transforming all the vertices within the model(from a performance point of view), esp. since its obviously working with the camera transform. I don't actually need the 3D model, so using an inverse of the camera transform and then using the models points could work... I think but I am unsure, a camera transform for every model may be expensive I'll need to check. Also I am pretty sure this would mess up the final perspective transform of a group of models though.

I think X_GETMATRIX+X_MULTMATRIX could work but again though, there would be a real performance hit if the scene/model was complex.

As I said, lots of good points and plenty of food for thought!  ;)

BTW "moon.ddd" is available in your /samples/3d/x_getface GLB demo, this code is just that demo with the wireframe bit stuck in.
Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)

kanonet

If you want it with full matrix (including rotation, movement, scaling), here you go:

Code (glbasic) Select
// Animation Demo
// Start: Friday, March 22, 2002
GLOBAL dtime,fps,delay,phi,permil,ply_x,ply_y,ply_dir,fps_draw

X_LOADOBJ  "moon.ddd", 1
LOADSPRITE "moon.bmp", 1
LOCAL face[]
LOCAL count
LOCAL n=0
LOCAL x1,y1,x2,y2,x3,y3,z1,z2,z3, m[]
X_CULLMODE 1
WHILE TRUE
X_MAKE3D 1, 1200, 45
X_CAMERA COS(n)*10, SIN(n)*100, SIN(n)*100+50, 0, 0, 0
X_SPOT_LT -2, RGB(255,255,255), 0,50,100,0,10,100,180

phi=phi+GETTIMER()/100
permil=permil+GETTIMER()/20000; IF permil>=1 THEN permil=0
n=GETTIMERALL()/100
X_ROTATION 270, 1,0,0
X_ROTATION phi, 0,-1,0

X_SETTEXTURE 1,-1
// X_DRAWANIM 1, 0, 128, permil, TRUE

X_GETMATRIX m[]
X_DRAWOBJ 1, 2
X_MAKE2D
count = X_NUMFACES(1)
LOCAL b12, b13, b14, m0=m[0], m1=m[1], m2=m[2], m4=m[4], m5=m[5], m6=m[6], m8=m[8], m9=m[9], m10=m[10], m12=m[12], m13=m[13], m14=m[14]
FOR i=0 TO count-1 STEP 2
      X_GETFACE 1, 2, i, face[]
b12 = face[0][0]; b13= face[0][1]; b14= face[0][2]
x1 = m0 * b12 + m4 * b13 + m8 * b14 + m12
y1 = m1 * b12 + m5 * b13 + m9 * b14 + m13
z1 = m2 * b12 + m6 * b13 + m10 * b14 + m14
b12 = face[1][0]; b13= face[1][1]; b14= face[1][2]
x2 = m0 * b12 + m4 * b13 + m8 * b14 + m12
y2 = m1 * b12 + m5 * b13 + m9 * b14 + m13
z2 = m2 * b12 + m6 * b13 + m10 * b14 + m14
b12 = face[2][0]; b13= face[2][1]; b14= face[2][2]
x3 = m0 * b12 + m4 * b13 + m8 * b14 + m12
y3 = m1 * b12 + m5 * b13 + m9 * b14 + m13
z3 = m2 * b12 + m6 * b13 + m10 * b14 + m14
      X_WORLD2SCREEN x1,y1,z1, x1,y1,z1
      X_WORLD2SCREEN x2,y2,z2, x2,y2,z2
      X_WORLD2SCREEN x3,y3,z3, x3,y3,z3
      DRAWLINE x1,y1,x2,y2,RGB(255,0,255)
      DRAWLINE x3,y3,x2,y2,RGB(255,0,255)
      DRAWLINE x1,y1,x3,y3,RGB(255,0,255)
   NEXT

SHOWSCREEN
WEND

If you dont need full matrix, just one rotation it will be easier and faster to do it manually, but i was to lazy to work this out for you.^^
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

bigsofty

Aha, well done, this looks great and the code is still a lot smaller than I though it would be!   :good:
Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)