slightly better version of the code from above
`3d painter test
`======================
`P.Parkinson
`======================
`Main Source File
sync on
sync rate 60
autocam off
color backdrop 0, 0
set text font "Arial"
set text size 14
set text transparent
set bitmap format 21
position camera 10,80,-80
point camera 0,0,0
custom_cube(1,40,64)
box 0,0,128,128,rgb(255,255,255),rgb(255,255,255),rgb(255,255,255),rgb(255,255,255)
get image 1,0,0,128,128
get image 2,0,0,128,128
get image 3,0,0,128,128
get image 4,0,0,128,128
get image 5,0,0,128,128
get image 6,0,0,128,128
texture limb 1,1,1
texture limb 1,2,2
texture limb 1,3,3
texture limb 1,4,4
texture limb 1,5,5
texture limb 1,6,6
sc_setupobject 1,0,0
sc_allowobjectscaling 1
type hit_data
u as float
v as float
limb as integer
obj as integer
endtype
global hit_point as hit_data
target=100
make object cube target,1
hide object target
marker=101
make object sphere marker,1
color object marker,rgb(255,0,0)
`make paint sprite
for l=1 to 100
dot rnd(16),rnd(16),rgb(0,0,255)
next l
get image 10,0,0,16,16
sprite 1,-100,-100,10
offset sprite 1,8,8
`*******main loop********
cls
do
position object target,camera position x(),camera position y(),camera position z()
set object to camera orientation target
move object target,1000
hit=sc_raycast(0,camera position x(),camera position y(),camera position z(),object position x(target),object position y(target),object position z(target),0)
if hit>0
show object marker
position object marker,sc_getstaticcollisionx(),sc_getstaticcollisiony(),sc_getstaticcollisionz()
lh=limb_hit()
else
hide object marker
endif
if hit>0 and spacekey() and hit_point.u>=0 and hit_point.v>=0
paint2()
endif
if hit>0 and inkey$()="d" and hit_point.u>=0 and hit_point.v>=0
paint()
endif
if leftkey() then yrotate object 1,wrapvalue(object angle y(1))+1:sc_updateobject 1
if rightkey() then yrotate object 1,wrapvalue(object angle y(1))-1:sc_updateobject 1
if upkey() then xrotate object 1,wrapvalue(object angle x(1))+1:sc_updateobject 1
if downkey() then xrotate object 1,wrapvalue(object angle x(1))-1:sc_updateobject 1
MouseControl(1.0)
sync
loop
`*******Functions********
function MouseControl(Speed as float)
xrotate camera camera angle x()+mousemovey()
yrotate camera camera angle y()+mousemovex()
if mouseclick()=1 then move camera Speed
if mouseclick()=2 then move camera (0-Speed)
r=mousemovex()
r=mousemovey()
endfunction
function limb_hit()
l=0
done=-1
face_hit=sc_getfacehit()+1
obj_hit=sc_getobjecthit()
hitx#=sc_getstaticcollisionx()
hity#=sc_getstaticcollisiony()
hitz#=sc_getstaticcollisionz()
while done=-1
old_l=l
lock vertexdata for limb obj_hit,l
i_num=get vertexdata index count()/3
text 0,l*15,str$(i_num)
v_num=get vertexdata vertex count()/3
text 40,l*15,str$(v_num)
`used for index objects
if i_num>0
if face_hit>i_num
inc l
face_hit=face_hit-i_num
endif
endif
`used for triangle list objects
if i_num=0
if face_hit>v_num
inc l
face_hit=face_hit-v_num
endif
endif
if l=old_l
done=l
endif
unlock vertexdata
endwhile
lock vertexdata for limb obj_hit,done
i_num=get vertexdata index count()/3
v_num=get vertexdata vertex count()/3
u#=-1.0
v#=-1.0
if i_num>0
id_num=(face_hit-1)*3
id1=get indexdata(id_num)
id2=get indexdata(id_num+1)
id3=get indexdata(id_num+2)
x1#=get vertexdata position x(id1)
y1#=get vertexdata position y(id1)
z1#=get vertexdata position z(id1)
u1#=get vertexdata u(id1)
v1#=get vertexdata v(id1)
set vertexdata diffuse id1,rgb(255,0,0)
x2#=get vertexdata position x(id2)
y2#=get vertexdata position y(id2)
z2#=get vertexdata position z(id2)
u2#=get vertexdata u(id2)
v2#=get vertexdata v(id2)
set vertexdata diffuse id2,rgb(0,255,0)
x3#=get vertexdata position x(id3)
y3#=get vertexdata position y(id3)
z3#=get vertexdata position z(id3)
u3#=get vertexdata u(id3)
v3#=get vertexdata v(id3)
set vertexdata diffuse id3,rgb(0,0,255)
dist1#=distance3d(hitx#,hity#,hitz#,x1#,y1#,z1#)
dist2#=distance3d(hitx#,hity#,hitz#,x2#,y2#,z2#)
dist3#=distance3d(hitx#,hity#,hitz#,x3#,y3#,z3#)
if dist1#<dist2# and dist1#<dist3# then u#=u1#:v#=v1#
if dist2#<dist1# and dist2#<dist3# then u#=u2#:v#=v2#
if dist3#<dist1# and dist3#<dist2# then u#=u3#:v#=v3#
endif
` if i_num=0
` vt_num=(face_hit-1)*3
` u#=get vertexdata u(vt_num)
` v#=get vertexdata v(vt_num)
` u#=u#+get vertexdata u(vt_num+1)
` v#=v#+get vertexdata v(vt_num+1)
` u#=u#+get vertexdata u(vt_num+2)
` v#=v#+get vertexdata v(vt_num+2)
` u#=u#/3.0
` v#=v#/3.0
` endif
unlock vertexdata
hit_point.u=u#
hit_point.v=v#
hit_point.limb=done
hit_point.obj=obj_hit
text 0,(done+1)*15," object hit "+str$(sc_getobjecthit())+" sparky's face hit "+str$(sc_getfacehit())+" limb face hit "+str$(face_hit)+" limb number "+str$(done)
text 0,(done+2)*15," u "+str$(u#)+" v "+str$(v#)
text 0,(done+3)*15," space to paint"
text 0,(done+4)*15," d to place dot"
text 0,(done+5)*15," mouse to look lmb/rmb zoom in out"
text 0,(done+6)*15," arrows to move cube"
endfunction done
function custom_cube(obj_num,size#,rows#)
make object cube obj_num,0
``size of each square
grid_size#=size#/rows#
offset#=size#/2.0
``step for the uv co ordinates
global ustep as double float
global vstep as double float
ustep=1.0/rows#
vstep=1.0/rows#
``make a memblock big enough to hold the data
memblock_size=rows#*rows#*6
if memblock exist(1) then delete memblock 1
create_memblockobject(1,memblock_size)
`make a mesh and use it to build the 6 sides of the cube
`top
v_num=0
for lz=0 to rows#-1
for lx=0 to rows#-1
create_vertex(1,v_num,lx*grid_size#-offset#,0,lz*grid_size#-offset#,rgb(255,255,255),ustep*lx,vstep*lz)
inc v_num
create_vertex(1,v_num,lx*grid_size#-offset#,0,(lz+1)*grid_size#-offset#,rgb(255,255,255),ustep*lx,vstep*(lz+1))
inc v_num
create_vertex(1,v_num,(lx+1)*grid_size#-offset#,0,lz*grid_size#-offset#,rgb(255,255,255),ustep*(lx+1),vstep*lz)
inc v_num
create_vertex(1,v_num,(lx+1)*grid_size#-offset#,0,lz*grid_size#-offset#,rgb(255,255,255),ustep*(lx+1),vstep*lz)
inc v_num
create_vertex(1,v_num,lx*grid_size#-offset#,0,(lz+1)*grid_size#-offset#,rgb(255,255,255),ustep*lx,vstep*(lz+1))
inc v_num
create_vertex(1,v_num,(lx+1)*grid_size#-offset#,0,(lz+1)*grid_size#-offset#,rgb(255,255,255),ustep*(lx+1),vstep*(lz+1))
inc v_num
next lx
next lz
make mesh from memblock 1,1
add limb obj_num,1,1
offset limb obj_num,1,0,offset#,0
`bottom
add limb obj_num,2,1
rotate limb obj_num,2,180,0,0
offset limb obj_num,2,0,0-offset#,0
`left
add limb obj_num,3,1
rotate limb obj_num,3,0,0,90
offset limb obj_num,3,0-offset#,0,0
`right
add limb obj_num,4,1
rotate limb obj_num,4,0,0,270
offset limb obj_num,4,offset#,0,0
`back
add limb obj_num,5,1
rotate limb obj_num,5,90,0,0
offset limb obj_num,5,0,0,offset#
`front
add limb obj_num,6,1
rotate limb obj_num,6,270,0,0
offset limb obj_num,6,0,0,0-offset#
set object texture obj_num,2,0
set object normals obj_num
endfunction
function create_memblockobject(memnum,v)
make memblock memnum,12+(36*v)
write memblock dword memnum,0,338
write memblock dword memnum,4,36
write memblock dword memnum,8,v
endfunction
function create_vertex(memnum,v,vposx#,vposy#,vposz#,color as dword,u#,v#)
write memblock float memnum,v*36+12,vposx#
write memblock float memnum,v*36+16,vposy#
write memblock float memnum,v*36+20,vposz#
write memblock dword memnum,v*36+36,color
write memblock float memnum,v*36+40,u#
write memblock float memnum,v*36+44,v#
endfunction
function set_normal(memnum,v,normalx#,normaly#,normalz#)
write memblock float memnum,v*36+24,normalx#
write memblock float memnum,v*36+28,normaly#
write memblock float memnum,v*36+32,normalz#
endfunction
function paint()
`get image number
img=limb texture(hit_point.obj,hit_point.limb)
sx#=image width(img)
sy#=image height(img)
px#=sx#*hit_point.u
py#=sy#*hit_point.v
make memblock from image 1,img
mb_size=get memblock size(1)
delete image img
pos=0
pos=((py#*sx#+px#)*4.0)+12.0
text 200,0,str$(img)+" "+str$(pos)
write memblock byte 1,pos,0
write memblock byte 1,pos+1,0
write memblock byte 1,pos+2,255
write memblock byte 1,pos+3,128
pos=0
pos=((py#*sx#+(px#+1))*4.0)+12.0
if pos<=mb_size
write memblock byte 1,pos,0
write memblock byte 1,pos+1,0
write memblock byte 1,pos+2,255
write memblock byte 1,pos+3,128
endif
pos=0
pos=((py#*sx#+(px#-1))*4.0)+12.0
if pos>=12
write memblock byte 1,pos,0
write memblock byte 1,pos+1,0
write memblock byte 1,pos+2,255
write memblock byte 1,pos+3,128
endif
pos=0
pos=(((py#+1)*sx#+px#)*4.0)+12.0
if pos<=mb_size
write memblock byte 1,pos,0
write memblock byte 1,pos+1,0
write memblock byte 1,pos+2,255
write memblock byte 1,pos+3,128
endif
pos=0
pos=(((py#-1)*sx#+px#)*4.0)+12.0
if pos>=12
write memblock byte 1,pos,0
write memblock byte 1,pos+1,0
write memblock byte 1,pos+2,255
write memblock byte 1,pos+3,128
endif
make image from memblock img,1
delete memblock 1
texture limb hit_point.obj,hit_point.limb,img
endfunction
function paint2()
img=limb texture(hit_point.obj,hit_point.limb)
sx#=image width(img)
sy#=image height(img)
px#=sx#*hit_point.u
py#=sy#*hit_point.v
make memblock from image 1,img
delete image img
make bitmap from memblock 1,1
set current bitmap 1
delete memblock 1
paste sprite 1,px#,py#
make memblock from bitmap 1,1
delete bitmap 1
make image from memblock img,1
delete memblock 1
set current bitmap 0
texture limb hit_point.obj,hit_point.limb,img
endfunction
function Distance3D( x1# as float, y1# as float, z1# as float, x2# as float, y2# as float, z2# as float )
distance# = Abs(Sqrt((x1# - x2#) ^ 2 + (y1# - y2#) ^ 2 + (z1# - z2#) ^ 2))
endfunction distance#