Hiya!
I've made some progress on a subdivided / segmented cube that's made out of the idea of a segmented quad to form the sides. But the texture on the left side doesn't look right. I've compared this with a regular cube, and I believe the u's or v's need rotating 90 degrees to the right.
As far as I know the for loops are fine and don't need dabbling with. I've mucked about with al-sorts of ordering of the u and v positions in the addvertex parts, though not much luck.
Hopefully it's a case of altering the stuff to do with the pos_u0# and pos_v0#.
;=================================
; Sub Divided Cube V9.9
; Created By Clyde^GVY 20/05/2012
;=================================
Graphics3D 800,600,32,2
SetBuffer BackBuffer()
Dim textures(2)
Global camera
Global light
Global seg_cube
Global texture_image
Global texture_file$="media\this way up.bmp"
init()
main()
Function init()
camera=CreateCamera()
PositionEntity ( camera, 0.0, 0.0, -10.0 )
light=CreateLight( camera )
texture_image =LoadImage ( texture_file$ )
textures(0) =LoadTexture ( texture_file$ )
textures(1) =create_texture ( 1, 1, $f0f0f0 )
seg_cube =create_segmented_cube ( 4, 2, 3, 10.0, 10.0, 10.0 )
PositionEntity ( seg_cube, 0.0, 0.0, 50.0 )
EntityTexture ( seg_cube, textures(0) )
End Function
Function main()
Local rx#= -45.0
Local ry#= 45.0
Local rz#= 0.0
Local wire_mode%=0
While Not KeyHit(1)
WireFrame( wire_mode% )
EntityTexture( seg_cube, textures( wire_mode% ) )
RotateEntity( seg_cube, rx#, ry#, rz# )
;==================
; a = turn z axis.
;==================
If KeyDown(30) Then rz#=rz#-0.25
;==================
; d = turn z axis.
;==================
If KeyDown(32) Then rz#=rz#+0.25
;=================
; cursor up = up.
;=================
If KeyDown(200) Then rx#=rx#+0.25
;=====================
; cursor down = down.
;=====================
If KeyDown(208) Then rx#=rx#-0.25
;=====================
; cursor left = left.
;=====================
If KeyDown(203) Then ry#=ry#-0.25
;=======================
; cursor right = right.
;=======================
If KeyDown(205) Then ry#=ry#+0.25
;=======================
; w = toggle wireframe.
;=======================
If KeyHit(17) Then wire_mode%=Not wire_mode%
RenderWorld()
DrawImage( texture_image, 0, 0 )
Flip
Wend
End Function
Function create_segmented_cube( segs_x%, segs_y%, segs_z%, scale_x#, scale_y#, scale_z# )
Local entity=CreateMesh()
Local cube =CreateSurface(entity)
;=========
; floats.
;=========
Local pos_x0#=0.0, pos_y0#=0.0, pos_z0#=0.0
Local pos_x1#=0.0, pos_y1#=0.0, pos_z1#=0.0
Local pos_u0#=0.0, pos_v0#=0.0
Local pos_u1#=0.0, pos_v1#=0.0
Local div_u#=0.0
Local div_v#=0.0
Local xx#=0.0, yy#=0.0, zz#=0.0
Local segs_xx#=Float(segs_x%)
Local segs_yy#=Float(segs_y%)
Local segs_zz#=Float(segs_z%)
;===========
; integers.
;===========
Local x%=0, y%=0, z%=0
Local v0%=0, v1%=0, v2%=0, v3%=0
;============
; centering.
;============
Local cent_x#=-(( segs_xx# * scale_x# ) / 2.0 )
Local cent_y#=-(( segs_yy# * scale_y# ) / 2.0 )
Local cent_z#=-(( segs_zz# * scale_z# ) / 2.0 )
Local left_side% =1
Local front_side% =1
Local top_side% =1
;============
; left side.
;============
If ( left_side%=1 ) Then
div_u#= ( 1.0 / segs_yy# )
div_v#= ( 1.0 / segs_zz# )
For z%=0 To segs_z%-1
zz#=Float(z%)
For y%=0 To segs_y%-1
yy#=Float(y%)
pos_y0#=cent_y# + ( yy# * scale_y# )
pos_z0#=cent_z# + ( zz# * scale_z# )
pos_y1#=cent_y# + (( yy# + 1.0 ) * scale_y# )
pos_z1#=cent_z# + (( zz# + 1.0 ) * scale_z# )
pos_u0#=div_u# * yy#
pos_v0#=div_v# * zz#
pos_u1#=div_u# * ( yy# + 1.0 )
pos_v1#=div_v# * ( zz# + 1.0 )
v0%=AddVertex( cube, cent_x#, -pos_y1#, pos_z0#, -pos_u1#, -pos_v0# )
v1%=AddVertex( cube, cent_x#, -pos_y0#, pos_z0#, -pos_u0#, -pos_v0# )
v2%=AddVertex( cube, cent_x#, -pos_y0#, pos_z1#, -pos_u0#, -pos_v1# )
v3%=AddVertex( cube, cent_x#, -pos_y1#, pos_z1#, -pos_u1#, -pos_v1# )
AddTriangle( cube, v2%, v1%, v0% )
AddTriangle( cube, v3%, v2%, v0% )
Next
Next
End If
;============
; front side.
;============
If ( front_side%=1 ) Then
div_u#=( 1.0 / segs_xx# )
div_v#=( 1.0 / segs_yy# )
For y%=0 To segs_y%-1
yy#=Float(y%)
For x%=0 To segs_x%-1
xx#=Float(x%)
pos_x0#=cent_x#+ ( xx# * scale_x# )
pos_y0#=cent_y#+ ( yy# * scale_y# )
pos_x1#=cent_x#+(( xx#+1.0 ) * scale_x# )
pos_y1#=cent_y#+(( yy#+1.0 ) * scale_y# )
pos_u0#=div_u# * xx#
pos_v0#=div_v# * yy#
pos_u1#=div_u# * (xx#+1.0)
pos_v1#=div_v# * (yy#+1.0)
v0=AddVertex( cube, -pos_x0, -pos_y1, cent_z, -pos_u0, pos_v1 )
v1=AddVertex( cube, -pos_x0, -pos_y0, cent_z, -pos_u0, pos_v0 )
v2=AddVertex( cube, -pos_x1, -pos_y0, cent_z, -pos_u1, pos_v0 )
v3=AddVertex( cube, -pos_x1, -pos_y1, cent_z, -pos_u1, pos_v1 )
AddTriangle( cube, v2%, v1%, v0% )
AddTriangle( cube, v3%, v2%, v0% )
Next
Next
End If
;===========
; top side.
;===========
If ( top_side%=1 ) Then
div_u#=( 1.0 / segs_xx# )
div_v#=( 1.0 / segs_zz# )
For z%=0 To segs_z%-1
zz#=Float(z%)
For x%=0 To segs_x%-1
xx#=Float(x%)
pos_x0#=cent_x#+( xx# * scale_x# )
pos_z0#=cent_z#+( zz# * scale_z# )
pos_x1#=cent_x#+(( xx#+1.0 ) * scale_x# )
pos_z1#=cent_z#+(( zz#+1.0 ) * scale_z# )
pos_u0#=div_u# * xx#
pos_v0#=div_v# * zz#
pos_u1#=div_u# * (xx#+1.0)
pos_v1#=div_v# * (zz#+1.0)
v0%=AddVertex( cube, pos_x1#, -cent_y#, pos_z0#, pos_u1#, -pos_v0# )
v1%=AddVertex( cube, pos_x0#, -cent_y#, pos_z0#, pos_u0#, -pos_v0# )
v2%=AddVertex( cube, pos_x0#, -cent_y#, pos_z1#, pos_u0#, -pos_v1# )
v3%=AddVertex( cube, pos_x1#, -cent_y#, pos_z1#, pos_u1#, -pos_v1# )
AddTriangle( cube, v0%, v1%, v2% )
AddTriangle( cube, v0%, v2%, v3% )
Next
Next
End If
UpdateNormals( entity )
Return ( entity )
End Function
Function create_texture( wwidth%, height%, colour% )
Local x%=0, y%=0
Local texture=CreateTexture( wwidth%, height% )
SetBuffer TextureBuffer( texture )
LockBuffer TextureBuffer( texture )
For y%=0 To height%-1
For x%=0 To wwidth%-1
WritePixelFast( x%,y%, colour%, TextureBuffer( texture ) )
Next
Next
UnlockBuffer TextureBuffer( texture )
SetBuffer BackBuffer()
Return texture
End Function
I know I've used b3d to illustrate the problem, but I shall be converting this over into a different language once sussed, so please no inbuilt b3d commands.
Cheers For The Help - Much Appreciated!!! :D
Clyde.
If you just use 8 vertices and 8 uvs and try to link them up it can't work. Try using 4 vertices per face.
Jim
So simple looking 3D Cube on Small code of Blitz 3D as show how simple it is :)
I don't quite follow. Surely if I use less verts, I'll have missing adjacent triangles?
I also need to do my own rotate verts routine ( rather than the built in blitz command ) as I hope to use this in another lingo, but not sure on doing that. And it will make creating the segmented quads / subdivided cube easier.
Thanks in advance.
You need more vertices, not less. A cube has 8 corners and you can join these up using triangles to make all the faces. What you can't do with only 8 vertices is get the uvs right on all faces at the same time. Some will be jumbled up and I thought this was probably your problem.
To get the uvs right, you need 4 vertices per cube face, i.e. 24 vertices. Each corner then has 3 vertices at exactly the same location, but now they have the possibility of having distinct uv coordinates.
Jim
I think he's already generating an NxM grid for each side of the cube.
And the problem is the orientation of the grids (which is easy to fix with a bit of effort).
Just had a rough look over the code, though, so I can be totally wrong...
I think that sounds promising & thanks.
Is any part of if near to what you'd usually do for this type of object?
I'd really love a hand or two in pulling this off!!
Cheers and respect,
Clyde.
Just to get it right, you're trying to create this kind of thing?
You can only get the uvs for four neighbouring sides right.
The top and bottom face can't match, no matter how you rotate them.