Author |
Topic: The 3D editor tool kit: ideas (Read 426 times) |
|
michael
Senior Member
member is offline


Posts: 335
|
 |
The 3D editor tool kit: ideas
« Thread started on: Sep 11th, 2017, 7:23pm » |
|
There are buttons and images showing the directional controls for a whole triangle or corner. I tested the interface for some of the tools already on the 3D render and it will work very nicely.
This is only the tool kit that is going to be adapted to the renderer.
*** If you feel a special tool should be added let me know. I will be adding a tool to rotate the image as you edit it and I also will add the ability to switch between triangles.
NOTE: Every time a move is made the image changes in the file..
I will start with 12 triangles so a person can make a decent 3D piece for their collection.
Use the left mouse button to try out the controls and watch the white box to see the label it has.
I will add keyboard controls WSAD and arrow controls later
Code: PROCgraphics(1100,400):REM this is not the final size
res$=""
res=0
ls= 0
LET rs= 24
counl%=290
counr%=2110
REM setup buttons before use
REM x , y ,size,"fillcolor","command"
res$=FNabutton(100,100,25,"light green","fill"):REM keeping it efficient
res$=FNabutton(125,130,25,"yellow","fill")
res$=FNabutton(300,100,25,"red","fill")
res$=FNabutton(300,130,25,"cyan","fill")
res$=FNabutton(500,100,25,"200,200,190","fill")
res$=FNabutton(470,100,25,"200,190,200","fill")
res$=FNabutton(593,70,75,"000,000,000","fill") :REM select entire triangle
res$=FNabutton(770,90,25,"100,50,100","fill") :REM LL triangle only
res$=FNabutton(905,90,25,"50,100,50","fill"):REM LR triangle only
res$=FNabutton(835,205,25,"200,50,100","fill"):REM TOP triangle only
PROCcolor("f","white")
LINE165,165,200,200:LINE200,200,180,200:LINE 200,200,200,180
LINE 90,90,60,60:LINE 60,60,80,60:LINE 60,60,60,80
LINE 315,170,315,200:LINE 315,200,300,180:LINE 315,200,330,180
LINE 315,85,315,50:LINE 315,50,300,70:LINE 315,50,330,70
LINE 460,115,430,115:LINE 430,115,440,130:LINE 430,115,440,100:LINE 535,115,560,115
LINE 560,115,550,130:LINE 560,115,550,100:LINE 600,100,660,100:LINE 660,100,630,130
LINE 630,130,600,100: LINE 800,100,900,100:LINE 900,100,850,200:LINE 850,200,800,100
PROCcolor("f","black")
REM TRACKING STARTS HERE
REPEAT
res$=""
IF FNabutton(100,100,25,"green","out")="out" THEN res$="out"
IF FNabutton(125,130,25,"blue","in")="in" THEN res$="in"
IF FNabutton(300,100,25,"red","down")="down" THEN res$="down"
IF FNabutton(300,130,25,"orange","up")="up" THEN res$="up"
IF FNabutton(500,100,25,"purple","right")="right" THEN res$="right"
IF FNabutton(470,100,25,"200,190,200","left")="left" THEN res$="left"
IF FNabutton(593,70,75,"000,000,000","all")="all" THEN res$="all"
IF FNabutton(770,90,25,"100,50,100","LL")="LL" THEN res$="LL" :REM LL triangle only
IF FNabutton(905,90,25,"50,100,50","LR")="LR" THEN res$="LR":REM LR triangle only
IF FNabutton(835,205,25,"200,50,100","TOP")="TOP" THEN res$="TOP":REM TOP triangle only
PROCsbox(250,700,2150,600,"15")
MOVE 260,650:PRINT res$
WAIT 10
UNTIL FALSE
END
REM x,y is lower left and c$=fillcolor:com$-command
DEFFNabutton(x,y,size%,c$,com$)
MOUSE mx,my,mb
LOCAL ret$
PROCcolor("f","5")
PROCrect(x,y,x+size%,y+size%)
IF com$="fill" THEN
PROCpaint(x+5,y+5,c$)
ENDIF
IF mx>x AND mx<x+size% AND my>y AND my<y+size% THEN
PROCcolor("f","15"):PROCrect(x,y,x+size%,y+size%)
IF mb=4 THEN ret$=com$
ENDIF
=ret$
DEFPROCarrowu(x,y)
PRIVATE xx,yy
PROCcolor("f","black")
LINE xx,yy,xx-20,yy-20
LINE xx,yy,xx+20,yy-20
PROCcolor("f","15")
LINE x,y,x-20,y-20
LINE x,y,x+20,y-20
xx=x:yy=y
ENDPROC
DEFPROCarrowd(x,y)
PRIVATE hh,vv
PROCcolor("f","000,000,000")
LINE hh,vv,hh-20,vv+20
LINE hh,vv,hh+20,vv+20
PROCcolor("f","15")
LINE x,y,x-20,y+20
LINE x,y,x+20,y+20
hh=x:vv=y
ENDPROC
REM GRAPHICS(x,y)
DEF PROCgraphics(x,y)
VDU 23,22,x;y;8,15,16,1
OFF
VDU 5
ENDPROC
REM SBOX **********************
DEF PROCsbox(x%,y%,w%,h%,c$)
LOCAL ry%,sx%,sy%
sx%=x%:sy%=y%
IF x%>w% THEN x%=w%:w%=sx%
IF y%>h% THEN y%=h%:h%=sy%
ry%=y%
PROCcolor("f",c$)
REPEAT
LINE x%,y%,w%,y%
y%=y%+1
UNTIL y%=h%
y%=ry%
IF c$<>"0" THEN PROCcolor("f","000,000,000") ELSE PROCcolor("f","white")
LINE x%+2,y%+2,w%-2,y%+2
LINE w%-2,y%+2,w%-2,h%-4
LINE w%-2,h%-4,x%+2,h%-4
LINE x%+2,h%-4,x%+2,y%+2
PROCresetrgb
ENDPROC
REM RECT **********************
DEFPROCrect(x%,y%,w%,h%)
LOCAL sx%,sy%
sx%=x%:sy%=y%
IF x%>w% THEN x%=w%:w%=sx%
IF y%>h% THEN y%=h%:h%=sy%
LINE x%,y%,w%,y%
LINE w%,y%,w%,h%
LINE w%,h%,x%,h%
LINE x%,h%,x%,y%
ENDPROC
REM pixel *******************
DEFPROCpixel(x%,y%,c$)
PROCcolor("f",c$)
MOVE x%,y%:DRAW x%,y%
ENDPROC
REM SET c$ can be colors like blue or 1 or a R,G,B color
DEF PROCset(x%,y%,c$)
LOCAL h%
PROCcolor("f",c$)
FOR h%=0 TO 20
LINE x%+h%,y%,x%+h%,y%+20
NEXT
MOVE 0,0
ENDPROC
DEFPROCpaint(x%,y%,co$)
PROCcolor("b","0"):PROCcolor("f",co$)
FILL x%,y%
ENDPROC
REM restore default color palettes
DEFPROCresetrgb
COLOUR 0,0,0,0 :COLOUR 1,200,0,0 :COLOUR 2,000,200,000
COLOUR 3,200,200,000:COLOUR 4,000,000,200:COLOUR 5,200,000,200
COLOUR 6,000,200,200:COLOUR 7,200,200,200:COLOUR 8,056,056,056
COLOUR 9,248,056,056:COLOUR 10,056,248,056:COLOUR 11,248,248,056
COLOUR 12,056,056,248:COLOUR 13,248,056,248:COLOUR 14,056,248,248
COLOUR 15,248,248,248
ENDPROC
DEF PROCcolor(fb$,rgb$)
PRIVATE assemble$,br%,bg%,bb%
IF rgb$="0" OR rgb$="black" THEN rgb$="000,000,000"
IF rgb$="1" OR rgb$="red" THEN rgb$="200,000,000"
IF rgb$="2" OR rgb$="green" THEN rgb$="000,200,000"
IF rgb$="3" OR rgb$="yellow" THEN rgb$="200,200,000"
IF rgb$="4" OR rgb$="blue" THEN rgb$="000,000,200"
IF rgb$="5" OR rgb$="magenta" THEN rgb$="200,000,200"
IF rgb$="6" OR rgb$="cyan" THEN rgb$="000,200,200"
IF rgb$="7" OR rgb$="white" THEN rgb$="200,200,200"
IF rgb$="8" OR rgb$="grey" THEN rgb$="056,056,056"
IF rgb$="9" OR rgb$="light red" THEN rgb$="248,056,056"
IF rgb$="10" OR rgb$="light green" THEN rgb$="056,248,056"
IF rgb$="11" OR rgb$="light yellow" THEN rgb$="248,248,056"
IF rgb$="12" OR rgb$="light blue" THEN rgb$="056,056,248"
IF rgb$="13" OR rgb$="light magenta" THEN rgb$="248,056,248"
IF rgb$="14" OR rgb$="light cyan" THEN rgb$="056,248,248"
IF rgb$="15" OR rgb$="light white" THEN rgb$="248,248,248"
assemble$=rgb$
br%=VAL(MID$(assemble$,1,3)):bg%=VAL(MID$(assemble$,5,3)):bb%=VAL(MID$(assemble$,9,3))
IF fb$="f" OR fb$="F" THEN COLOUR 0,br%,bg%,bb% : GCOL 0
IF fb$="b" OR fb$="B" THEN COLOUR 1,br%,bg%,bb% : GCOL 128+1
ENDPROC
a REM buttonz
DEFFNbuttonz(X,Y,msg$)
LOCAL initialx%,fi%,reduction%,tx,ty,mx%,my%,mb%,ad%,ady%,c$
PRIVATE st$
IF msg$<> "clearitall" THEN
initialx%=LEN(msg$)
LET tx= X+initialx%+25
LET ty= Y:reduction%=0
reduction%=initialx%/2
reduction%=reduction%*6
IF initialx%<20 THEN reduction%=reduction%/2
initialx%=initialx%*22-reduction%
MOUSE mx%,my%,mb%
ad%=initialx%+8:ad%+=X:ady%=Y-28
IF mx% >X AND mx%<ad% AND my%<Y+8 AND my%>ady% THEN
c$="255,255,255"
IF mb%=4 THEN st$=msg$
ELSE c$="200,200,200"
ENDIF
IF FNrgb(X,Y)="000,000,000" THEN c$="200,200,200"
PROCcolor("f",c$)
IF FNrgb(X,Y)<>c$ THEN
FOR fi%=12 TO 48
LINE X-3,Y+20-fi%,X+initialx%+8,Y+20-fi%
NEXT
PROCcolor("f","000,000,000")
MOVE tx,ty
PRINT msg$
ENDIF
ENDIF
IF msg$="clearitall" THEN st$=""
=st$
|
« Last Edit: Sep 11th, 2017, 7:25pm by michael » |
Logged
|
I like making program generators and like reinventing the wheel
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: The 3D editor tool kit: ideas
« Reply #1 on: Sep 12th, 2017, 08:16am » |
|
Hi Michael,
I think the hardest thing about D3D is making the models. I'm currently working on making some "primitives" - cylinder, sphere, box, etc - probably with variants that make only part of it. I'm incorporating the ability to rotate and shift the object in 3D, so it should be possible to generate a more complex object by combining the primitives. I'll include the option to generate surface normals and texture coordinates.
It would be great to have a way to edit single vertices of the objects, or to move them about relative to each other visually - I don't know if Ric is interested in adapting the great work he's done within his own system?
Best wishes,
D
|
|
Logged
|
|
|
|
michael
Senior Member
member is offline


Posts: 335
|
 |
Re: The 3D editor tool kit: ideas
« Reply #2 on: Sep 13th, 2017, 12:42am » |
|
Thankfully, I had just figured out how to get a nice cycle with updates of any changes to the 3D image info.. Now I can merge the two programs together as I had tested and set up a turn based editor. The cycles and WAITs would allow the user to see the render and modify each triangle instantly with the program above.
I would love to try out your version and help create objects.
I will finish my version also, since I know this should work well.
The above program will be adapted to this one and I will make 12 triangles to edit.
Here is the successful cycle of the renderer.. This is so exciting !!
Code: IF INKEY$(-256)="W" INSTALL @lib$+"D3DLIBA" ELSE INSTALL @lib$+"OGLLIB"
PROCcreate3d
MODE 8
DIM l%(0), b%(1), n%(1), f%(1), s%(1), m%(1), t%(1), y(1), p(1), r(1), X(1), Y(1), Z(1), e(2), a(2)
ON CLOSE PROCcleanup:QUIT
ON ERROR PROCcleanup:PRINT REPORT$:END
IF INKEY$(-256)="W" d% = FN_initd3d(@hwnd%, 1, 0) ELSE d% = FN_initgl(@hwnd%, 1, 0)
IF d% = 0 ERROR 100, "Can't initialise Direct3D"
e() = 0, 0, -6
a() = 0, 0, 0
l%()=1
REPEAT
b%(0) = FN_load3d(d%, @dir$+"TRIANGLE.B3D", n%(0), f%(0), s%(0))
IF b%(0) = 0 ERROR 100, "Can't load TRIANGLE.B3D"
REM t%(1) = FN_loadtexture(d%, @dir$+"purple.JPG")
REM IF t%(1) = 0 ERROR 100, "Can't load face.JPG"
y() +=.01:REM yaw (rotations around the Y axis)
REM pitch
p() =0:REM TIME/100 (pitch angles rotations around the X axis)
REM roll
r() = 0:REM TIME/40 (roll angles (rotations around the Z axis)
REM X (right left)
X() = 0:REM SIN(TIME/200)
REM Y() up and down
Y() = 0
REM Z() depth
Z() = 10:REM
REM PROC_render(d%, &FF7F7F7F, 0, l%(), 2, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000)
PROC_render(d%, &FF7F7F7F, 0, l%(), 2, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000, 0) :REM experimental
REM 1 2 3 4 5 6 7 8 9 10 11 yaw pitch roll X Y Z eye0123 18 19 20 ^mcd ^( cam to farplane dist)
REM 1 Val returned from FN_init3D
REM 2 back color 3 #of lights 4 light pointers
REM t%() - holds texture
REM mcd - minimum near cam distance
WAIT 1
UNTIL FALSE
END
DEF PROCcleanup
t%(1) += 0:IF t%(1) PROC_release(t%(1))
b%(0) += 0:IF b%(0) PROC_release(b%(0))
b%(1) += 0:IF b%(1) PROC_release(b%(1))
d% += 0 :IF d% PROC_release(d%)
ENDPROC
DEF PROCcreate3d
F% = OPENOUT"TRIANGLE.B3D"
PROC4(6):REM 3 vertices
PROC4(&100042):REM vertex size &10 and format &42
REM LL x LL y LL z
PROC4(FN_f4(-1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF)
REM LR x LR y LR z
PROC4(FN_f4(1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FF00FF00)
REM PEAK X PEAK Y PEAK Z
PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FFFF0000)
PROC4(FN_f4(-1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FF0000FF)
REM LR x LR y LR z
PROC4(FN_f4(-1)):PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FF00FF00)
REM PEAK X PEAK Y PEAK Z
PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FFFF0000)
CLOSE #F%
ENDPROC
DEF PROC4(A%):BPUT#F%,A%:BPUT#F%,A%>>8:BPUT#F%,A%>>16:BPUT#F%,A%>>24:ENDPROC
|
« Last Edit: Sep 13th, 2017, 12:50am by michael » |
Logged
|
I like making program generators and like reinventing the wheel
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: The 3D editor tool kit: ideas
« Reply #3 on: Sep 14th, 2017, 1:39pm » |
|
Here's my first function, to draw a cylinder, and some supporting functions. It's still a bit up in the air how to handle things, but it works OK. The cylinder needs its normals facing out from the centre, so I've calculated them as the ends of the vector, which can then be moved/rotated/scaled with the vector data, but then it needs converting into proper normals before writing to the file. A bit ugly, but convenient, since my plan is to be able to fit several shapes together, and render it all as one file. For shapes with flat faces,all the normals can be calculated at the end, which will be easier, but spheres will also need this approach. One question to think about is where to put the centre of each shape. Logically it should be the centre (!), but here I've chosen the end, to make positioning of it (especially after scaling) more intuitive. That may or may not be the right answer. Any thoughts?
Best wishes,
D Code:
capped%=TRUE :REM Include ends on the cylinder
nf%=20 :Number of faces
startface%=1 :Include the whole cylinder, or only part of it?
endface%=nf%
IF capped% THEN vpf%=12 ELSE vpf%=6 :REM each face has 2 triangles (6 vertices), +/- 2 more to form the caps
nv%=vpf%*(endface%-startface%+1) :REM number of vertices in the shape (needed to DIM arrays)
REM Coordinates to map a texture to the shape. You might want to use only a small part of a texture
texminu=0
texmaxu=1
texminv=0
texmaxv=1
DIM v(nv%,2),vn(nv%,2),t(nv%,1) :REM hold vertex, normal, and texture data
DIM vr(nv%,2),vnr(nv%,2) :REM These are only needed for the display routine
numverts%=FNMake3D_Cylinder(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv)
PROCDisplay(v(),nv%) :REM Wireframe display, really for diagnostic purposes
vn()=vn()-v() :"Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
PROCNormalise(nv%,vn())
PROCWriteB3D("cylinder",nv%,&152,v(),vn(),t()) :REM File name, number of vertices, required vertex format, and arrays of vertex,normal, and texture data
PRINT "managed to finish"
END
:
DEFFNMake3D_Cylinder(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv)
LOCAL a,pa,vpf%,nv%,l,r,tdu,tdv
IF capped% THEN vpf%=12 ELSE vpf%=6
nv%=vpf%*(endface%-startface%+1)
REM Cylinder lies along X axis, and has centre of left hand end at 0,0,0
REM Initially scale cylinder to 1 long, and radius 1. We can change this later!
l=1
r=1.0
tdu=texmaxu-texminu
tdv=texmaxv-texminv
FOR a=0 TO endface%-startface%
REM Calculate positions of vertices
pa=a+startface%-1
py=r*SIN(pa*2*PI/nf%)
pz=r*COS(pa*2*PI/nf%)
py2=r*SIN((pa+1)*2*PI/nf%)
pz2=r*COS((pa+1)*2*PI/nf%)
REM Fill vertex data
v(a*vpf%,0)=0
v(a*vpf%,1)=py
v(a*vpf%,2)=pz
v(a*vpf%+1,0)=l
v(a*vpf%+1,1)=py2
v(a*vpf%+1,2)=pz2
v(a*vpf%+2,0)=l
v(a*vpf%+2,1)=py
v(a*vpf%+2,2)=pz
v(a*vpf%+3,0)=0
v(a*vpf%+3,1)=py
v(a*vpf%+3,2)=pz
v(a*vpf%+4,0)=0
v(a*vpf%+4,1)=py2
v(a*vpf%+4,2)=pz2
v(a*vpf%+5,0)=l
v(a*vpf%+5,1)=py2
v(a*vpf%+5,2)=pz2
REM Here are normals
ny=(r+1)*SIN(pa*2*PI/nf%)
nz=(r+1)*COS(pa*2*PI/nf%)
ny2=(r+1)*SIN((pa+1)*2*PI/nf%)
nz2=(r+1)*COS((pa+1)*2*PI/nf%)
vn(a*vpf%,0)=0
vn(a*vpf%,1)=ny
vn(a*vpf%,2)=nz
vn(a*vpf%+1,0)=l
vn(a*vpf%+1,1)=ny2
vn(a*vpf%+1,2)=nz2
vn(a*vpf%+2,0)=l
vn(a*vpf%+2,1)=ny
vn(a*vpf%+2,2)=nz
vn(a*vpf%+3,0)=0
vn(a*vpf%+3,1)=ny
vn(a*vpf%+3,2)=nz
vn(a*vpf%+4,0)=0
vn(a*vpf%+4,1)=ny2
vn(a*vpf%+4,2)=nz2
vn(a*vpf%+5,0)=l
vn(a*vpf%+5,1)=ny2
vn(a*vpf%+5,2)=nz2
REM Here are the texture mapping coordinates
t(a*vpf%,0)=texminu
t(a*vpf%,1)=texminv+tdv*pa/nf%
t(a*vpf%+1,0)=texmaxu
t(a*vpf%+1,1)=texminv+tdv*(pa+1)/nf%
t(a*vpf%+2,0)=texmaxu
t(a*vpf%+2,1)=texminv+tdv*pa/nf%
t(a*vpf%+3,0)=texminu
t(a*vpf%+3,1)=texminv+tdv*pa/nf%
t(a*vpf%+4,0)=texminu
t(a*vpf%+4,1)=texminv+tdv*(pa+1)/nf%
t(a*vpf%+5,0)=texmaxu
t(a*vpf%+5,1)=texminv+tdv*(pa+1)/nf%
REM And now for the ends! Vertices first
IF capped% THEN
v(a*vpf%+6,0)=0
v(a*vpf%+6,1)=py
v(a*vpf%+6,2)=pz
v(a*vpf%+7,0)=0
v(a*vpf%+7,1)=0
v(a*vpf%+7,2)=0
v(a*vpf%+8,0)=0
v(a*vpf%+8,1)=py2
v(a*vpf%+8,2)=pz2
v(a*vpf%+9,0)=l
v(a*vpf%+9,1)=py
v(a*vpf%+9,2)=pz
v(a*vpf%+10,0)=l
v(a*vpf%+10,1)=0
v(a*vpf%+10,2)=0
v(a*vpf%+11,0)=l
v(a*vpf%+11,1)=py2
v(a*vpf%+11,2)=pz2
REM And the normals:
vn(a*vpf%+6,0)=-10
vn(a*vpf%+6,1)=py
vn(a*vpf%+6,2)=pz
vn(a*vpf%+7,0)=-10
vn(a*vpf%+7,1)=0
vn(a*vpf%+7,2)=0
vn(a*vpf%+8,0)=-10
vn(a*vpf%+8,1)=py2
vn(a*vpf%+8,2)=pz2
vn(a*vpf%+9,0)=l+10
vn(a*vpf%+9,1)=py
vn(a*vpf%+9,2)=pz
vn(a*vpf%+10,0)=l+10
vn(a*vpf%+10,1)=0
vn(a*vpf%+10,2)=0
vn(a*vpf%+11,0)=l+10
vn(a*vpf%+11,1)=py2
vn(a*vpf%+11,2)=pz2
REM And for the texture - rather arbitrary choice!
t(a*vpf%+6,0)=texminu+tdu*a/nf%
t(a*vpf%+6,1)=texminv
t(a*vpf%+7,0)=texminu+tdu/2
t(a*vpf%+7,1)=texmaxv
t(a*vpf%+8,0)=texminu+tdu*(a+1)/nf%
t(a*vpf%+8,1)=texminv
t(a*vpf%+9,0)=texminu+tdu*a/nf%
t(a*vpf%+9,1)=texminv
t(a*vpf%+10,0)=texminu+tdu/2
t(a*vpf%+10,1)=texmaxv
t(a*vpf%+11,0)=texminu+tdu*(a+1)/nf%
t(a*vpf%+11,1)=texminv
ENDIF
NEXT a
PRINT nv%
=nv%
:
DEFPROCRotate(a(),xa,ya,za)
LOCAL xrm(),yrm(),zrm()
DIM xrm(2,2),yrm(2,2),zrm(2,2)
xrm()=1,0,0,0,COS(xa),-SIN(xa),0,SIN(xa),COS(xa)
yrm()=COS(ya),0,SIN(ya),0,1,0,-SIN(ya),0,COS(ya)
zrm()=COS(za),-SIN(za),0,SIN(za),COS(za),0,0,0,1
REM Rotate around X axis, then Y, then Z. This matters! I find this the easiest order to visualise
xrm()=xrm().yrm()
xrm()=xrm().zrm()
a()=a().xrm()
ENDPROC
:
DEFPROCShift(a(),dx,dy,dz,nv%)
LOCAL x%
FOR x%=0 TO nv%-1
a(x%,0)+=dx
a(x%,1)+=dy
a(x%,2)+=dz
NEXT x%
ENDPROC
:
DEFPROCDisplay(v(),nv%)
LOCAL x%,xoff,yoff,zoff,xr,yr,zr
xoff=1000
yoff=700
zoff=0
xr=0
yr=0
zr=0
*REFRESH OFF
FOR zr=0 TO 2*PI STEP 0.1
yr=zr/2
xr=zr/3
vr()=v()
vr()*=100
PROCRotate(vr(),xr,yr,zr)
PROCShift(vr(),xoff,yoff,0,nv%)
FOR x%=0 TO nv%-2 STEP 3
MOVE vr(x%,0),vr(x%,1)
DRAW vr(x%+1,0),vr(x%+1,1)
DRAW vr(x%+2,0),vr(x%+2,1)
NEXT x%
*REFRESH
WAIT 5
CLS
NEXT zr
*REFRESH ON
ENDPROC
:
DEFPROCWriteB3D(name$,nv%,vf%,vdat(),ndat(),tdat())
LOCAL f%,x%,vs%
vs%=0
IF vf% AND 2 THEN vs%+=12:PRINT"vertices"
IF vf% AND &10 THEN vs%+=12:PRINT "normals"
IF vf% AND &40 THEN vs%+=4:PRINT "ambient colour"
IF vf% AND &80 THEN vs%+=4:PRINT "specular colour"
IF vf% AND &100 THEN vs%+=8:PRINT "Texture data"
REM Create file and fill it with data
f%=OPENOUT(@dir$+name$+".b3d")
PRINT nv%
PROC4(f%,nv%)
PROC4(f%,(vs%<<16)+vf%)
FOR x%=0 TO nv%-1
IF vf% AND 2 THEN PROC4(f%,FN_f4(vdat(x%,0))):PROC4(f%,FN_f4(vdat(x%,1))):PROC4(f%,FN_f4(vdat(x%,2)))
IF vf% AND &10 THEN PROC4(f%,FN_f4(ndat(x%,0))):PROC4(f%,FN_f4(ndat(x%,1))):PROC4(f%,FN_f4(ndat(x%,2)))
IF vf% AND &40 THEN PROC4(f%,&FFFFFFFF)
IF vf% AND &80 THEN PROC4(f%,&FFFFFFFF)
IF vf% AND &100 THEN PROC4(f%,FN_f4(tdat(x%,0))):PROC4(f%,FN_f4(tdat(x%,1)))
NEXT x%
CLOSE #f%
ENDPROC
:
DEFPROCNormalise(nv%,n())
LOCAL x%,l
FOR x%=0 TO nv%-1 STEP 3
l=SQR(n(x%,0)^2 + n(x%,1)^2+n(x%,2)^2)
n(x%,0)/=l
n(x%,1)/=l
n(x%,2)/=l
NEXT x%
ENDPROC
:
REM Stolen from Richard's D3D demo
DEF PROC4(F%, A%)
BPUT#F%,A% : BPUT#F%,A%>>8 : BPUT#F%,A%>>16 : BPUT#F%,A%>>24
ENDPROC
:
REM Convert to 4-byte float
REM Stolen from Richard's D3D library
DEF FN_f4(A#)
LOCAL A%,P%,U#
PRIVATE F%
IF F%=0 THEN
DIM P% 10
[OPT 2
.F%
mov esi,[ebp+2]:mov edi,[ebp+7]
fld qword [esi]:fstp dword [edi]
ret
]
ENDIF
!(^U#+4)=&3FF00000
A#*=U#
CALL F%,A#,A%
=A%
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: The 3D editor tool kit: ideas
« Reply #4 on: Sep 14th, 2017, 1:43pm » |
|
Here's a small viewer, so you can look at the shapes generated. You'll need to amend "house.bmp" to a picture of your choice!
Best wishes,
D Code: REM. Program to demonstrate use of Direct3D in BBC BASIC for Windows
MODE 21
DIM l%(1), b%(0), n%(0), f%(0), s%(0), m%(0), t%(0), y(0), p(0), r(0), X(0), Y(0), Z(0), e(2), a(2)
INSTALL @lib$+"D3DLIB"
PRINT "Loaded D3DLIB"
ON CLOSE PROCcleanup:QUIT
ON ERROR PROCcleanup:PRINT REPORT$:END
DIM D3Dlight8{Type%, Diffuse{r%,g%,b%,a%}, Specular{r%,g%,b%,a%}, \
\ Ambient{r%,g%,b%,a%}, Position{x%,y%,z%}, Direction{x%,y%,z%}, \
\ Range%, Falloff%, Attenuation0%, Attenuation1%, Attenuation2%, \
\ Theta%, Phi% }
D3Dlight8.Type% = 3 : REM directional source
D3Dlight8.Diffuse.r% = FN_f4(1)
D3Dlight8.Diffuse.g% = FN_f4(1)
D3Dlight8.Diffuse.b% = FN_f4(1)
D3Dlight8.Specular.r% = FN_f4(1)
D3Dlight8.Specular.g% = FN_f4(1)
D3Dlight8.Specular.b% = FN_f4(1)
D3Dlight8.Direction.x% = FN_f4(1)
D3Dlight8.Direction.y% = FN_f4(0.5)
D3Dlight8.Direction.z% = FN_f4(0)
l%(0) = D3Dlight8{}
DIM D3Dlight2{}=D3Dlight8{}
D3Dlight2.Type% = 3 : REM directional source
D3Dlight2.Diffuse.r% = FN_f4(1)
D3Dlight2.Diffuse.g% = FN_f4(1)
D3Dlight2.Diffuse.b% = FN_f4(1)
D3Dlight2.Specular.r% = FN_f4(1)
D3Dlight2.Specular.g% = FN_f4(1)
D3Dlight2.Specular.b% = FN_f4(1)
D3Dlight2.Direction.x% = FN_f4(0)
D3Dlight2.Direction.y% = FN_f4(-0.5)
D3Dlight2.Direction.z% = FN_f4(1)
l%(1) = D3Dlight2{}
d% = FN_initd3d(@hwnd%, 1, 1)
IF d% = 0 ERROR 100, "Can't initialise Direct3D"
b%(0) = FN_load3d(d%, @dir$+"cylinder.b3d", n%(0), f%(0), s%(0))
IF b%(0) = 0 ERROR 100, "Can't load B3D"
t%(0) = FN_loadtexture(d%, @dir$+"house.bmp")
IF t%(0) = 0 ERROR 100, "Can't load texture"
e() = 0, 0, -5
a() = 0, 0, 0
REPEAT
p() = TIME/200
r() = TIME/100
X() = SIN(TIME/200)
PROC_render(d%, &FF50507F, 2, l%(), 1, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000)
UNTIL INKEY(1)<>-1
PROCcleanup
END
:
DEF PROCcleanup
t%(0) += 0:IF t%(0) PROC_release(t%(0))
b%(0) += 0:IF b%(0) PROC_release(b%(0))
d% += 0 :IF d% PROC_release(d%)
ENDPROC
|
|
Logged
|
|
|
|
michael
Senior Member
member is offline


Posts: 335
|
 |
Re: The 3D editor tool kit: ideas
« Reply #5 on: Sep 15th, 2017, 01:07am » |
|
Impressive work. I think a secondary window (scratch pad editor) would be effective, even considering Richard wants a cross platform and BBC4W platform, a person would only need to run more than one instance of BBC Basic or create a executable for the interface and then make the renderer in a separate program and edit the image data in the file that the renderer would cycle and update.
The programs would simply be side by side in Windows 10 and could be quite simple.
I would like Hellomike , Ric, David Williams and all the others to visit the forum and perhaps we can each provide a perspective on advancing this. This can be fun for everyone.
I really want to make it so that it has super simple controls and also make it so a person can make 3D pieces from a preset pile of triangles. (12 to start in the beginners sandbox.)
If a person looks at how primitives are made in Second Life (game), that could give some ideas for making it simple,
Perhaps, triangles could be rendered in the 3D world to coordinate some edits.
Here is a link to Second Life 3D creation
https://youtu.be/5NvhL2YoIUY
And Hexagon 3D editor
https://youtu.be/4YsdMIHm_Po
|
« Last Edit: Sep 15th, 2017, 01:18am by michael » |
Logged
|
I like making program generators and like reinventing the wheel
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: The 3D editor tool kit: ideas
« Reply #6 on: Sep 15th, 2017, 11:53am » |
|
Here's where I am on the library: it's too big for one post, so you'll need to copy this plus the next bit, and save it together as one file. You can either put it in your library folder (may need admin permission), and load with INSTALL @lib$+"Make3DLib", or save it in your working directory and install it from there.
Best wishes,
D Code:REM Make3dLib: A set of routines to create, manipulate and combine a range of primitive shapes,
REM which can then be written to a file to be loaded by D3DLib or equivalents
DEFFNGetNumVerts(n$,nf%,startface%,endface%,capped%)
LOCAL nv%
PROCUpcase(n$)
CASE n$ OF
WHEN "CYLINDER","PRISM","TRUNCCONE":
IF capped% THEN vpf%=12 ELSE vpf%=6
nv%=vpf%*(endface%-startface%+1)
WHEN "SPHERE":
nv%=(endface%-startface%+1)*2*nf% *6
IF startface%=1 THEN nv%-=nf%*6
IF endface%=nf% THEN nv%-=nf%*6
WHEN "CONE":
IF capped% THEN vpf%=6 ELSE vpf%=3
nv%=vpf%*(endface%-startface%+1)
ENDCASE
=nv%
:
DEFPROCMake3D_Sphere(nf%,v(),n(),t(),startface%,endface%,texminu,texmaxu,textminv,texmaxv)
LOCAL nv%,vn%
nv%=(endface%-startface%+1)*2*nf% *6
IF startface%=1 THEN nv%-=nf%*6
IF endface%=nf% THEN nv%-=nf%*6
r=1.0
vn%=0
IF startface%=1 THEN
a=PI/nf%
lr=r*SIN(a)
FOR x%=0 TO 2*nf%-1
a2=x%*PI/nf%
px=-r*COS(a)
py=lr*SIN(x%*PI/nf%)
pz=lr*COS(x%*PI/nf%)
py2=lr*SIN((x%+1)*PI/nf%)
pz2=lr*COS((x%+1)*PI/nf%)
v(vn%,0)=px
v(vn%,1)=py
v(vn%,2)=pz
vn%+=1
v(vn%,0)=-r
v(vn%,1)=0
v(vn%,2)=0
vn%+=1
v(vn%,0)=px
v(vn%,1)=py2
v(vn%,2)=pz2
vn%+=1
NEXT x%
startface%+=1
ENDIF
IF endface%=nf% THEN
a=PI/nf%
lr=r*SIN(a)
FOR x%=0 TO 2*nf%-1
a2=x%*PI/nf%
px=r*COS(a)
py=lr*SIN(x%*PI/nf%)
pz=lr*COS(x%*PI/nf%)
py2=lr*SIN((x%+1)*PI/nf%)
pz2=lr*COS((x%+1)*PI/nf%)
v(vn%,0)=px
v(vn%,1)=py
v(vn%,2)=pz
vn%+=1
v(vn%,0)=r
v(vn%,1)=0
v(vn%,2)=0
vn%+=1
v(vn%,0)=px
v(vn%,1)=py2
v(vn%,2)=pz2
vn%+=1
NEXT x%
endface%-=1
ENDIF
FOR y%=startface%-1 TO endface%-1
a=y%*PI/nf%
lr=r*SIN(a)
px=-r*COS(a)
a2=(y%+1)*PI/nf%
lr2=r*SIN(a2)
px2=-r*COS(a2)
FOR x%=0 TO 2*nf%-1
a=x%*PI/nf%
py=lr*SIN(x%*PI/nf%)
pz=lr*COS(x%*PI/nf%)
py2=lr*SIN((x%+1)*PI/nf%)
pz2=lr*COS((x%+1)*PI/nf%)
a2=(x%+1)*PI/nf%
ey=lr2*SIN(x%*PI/nf%)
ez=lr2*COS(x%*PI/nf%)
ey2=lr2*SIN((x%+1)*PI/nf%)
ez2=lr2*COS((x%+1)*PI/nf%)
v(vn%,0)=px
v(vn%,1)=py
v(vn%,2)=pz
vn%+=1
v(vn%,0)=px2
v(vn%,1)=ey2
v(vn%,2)=ez2
vn%+=1
v(vn%,0)=px2
v(vn%,1)=ey
v(vn%,2)=ez
vn%+=1
v(vn%,0)=px
v(vn%,1)=py
v(vn%,2)=pz
vn%+=1
v(vn%,0)=px
v(vn%,1)=py2
v(vn%,2)=pz2
vn%+=1
v(vn%,0)=px2
v(vn%,1)=ey2
v(vn%,2)=ez2
vn%+=1
NEXT x%
NEXT y%
FOR x%=0 TO vn%-1
n(x%,0)=v(x%,0)*2
n(x%,1)=v(x%,1)*2
n(x%,2)=v(x%,2)*2
t(x%,0)=r+v(x%,0)/2
t(x%,1)=r+v(x%,1)/3
NEXT x%
IF vn%<>nv% THEN PRINT vn%,nv%:STOP
ENDPROC
:
DEFPROCMake3D_Cone(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv)
LOCAL a,pa,vpf%,nv%,l,r,tdu,tdv
IF capped% THEN vpf%=6 ELSE vpf%=3
nv%=vpf%*(endface%-startface%+1)
l=1
r=1.0
tdu=texmaxu-texminu
tdv=texmaxv-texminv
FOR a=0 TO endface%-startface%
pa=a+startface%-1
py=r*SIN(pa*2*PI/nf%)
pz=r*COS(pa*2*PI/nf%)
py2=r*SIN((pa+1)*2*PI/nf%)
pz2=r*COS((pa+1)*2*PI/nf%)
v(a*vpf%,0)=0
v(a*vpf%,1)=py
v(a*vpf%,2)=pz
v(a*vpf%+1,0)=0
v(a*vpf%+1,1)=py2
v(a*vpf%+1,2)=pz2
v(a*vpf%+2,0)=l
v(a*vpf%+2,1)=0
v(a*vpf%+2,2)=0
ny=(r+1)*SIN(pa*2*PI/nf%)
nz=(r+1)*COS(pa*2*PI/nf%)
ny2=(r+1)*SIN((pa+1)*2*PI/nf%)
nz2=(r+1)*COS((pa+1)*2*PI/nf%)
vn(a*vpf%,0)=0
vn(a*vpf%,1)=ny
vn(a*vpf%,2)=nz
vn(a*vpf%+1,0)=0
vn(a*vpf%+1,1)=ny2
vn(a*vpf%+1,2)=nz2
vn(a*vpf%+2,0)=l
vn(a*vpf%+2,1)=ny
vn(a*vpf%+2,2)=nz
t(a*vpf%,0)=texminu
t(a*vpf%,1)=texminv+tdv*pa/nf%
t(a*vpf%+1,0)=texminu
t(a*vpf%+1,1)=texminv+tdv*(pa+1)/nf%
t(a*vpf%+2,0)=texmaxu
t(a*vpf%+2,1)=texminv+tdv*(pa+1)/nf%
IF capped% THEN
v(a*vpf%+3,0)=0
v(a*vpf%+3,1)=py
v(a*vpf%+3,2)=pz
v(a*vpf%+4,0)=0
v(a*vpf%+4,1)=0
v(a*vpf%+4,2)=0
v(a*vpf%+5,0)=0
v(a*vpf%+5,1)=py2
v(a*vpf%+5,2)=pz2
vn(a*vpf%+3,0)=-1
vn(a*vpf%+3,1)=py
vn(a*vpf%+3,2)=pz
vn(a*vpf%+4,0)=-1
vn(a*vpf%+4,1)=0
vn(a*vpf%+4,2)=0
vn(a*vpf%+5,0)=-1
vn(a*vpf%+5,1)=py2
vn(a*vpf%+5,2)=pz2
vn(a*vpf%+9,0)=l+1
vn(a*vpf%+9,1)=py
vn(a*vpf%+9,2)=pz
vn(a*vpf%+10,0)=l+1
vn(a*vpf%+10,1)=0
vn(a*vpf%+10,2)=0
vn(a*vpf%+11,0)=l+1
vn(a*vpf%+11,1)=py2
vn(a*vpf%+11,2)=pz2
t(a*vpf%+3,0)=texminu+tdu*a/nf%
t(a*vpf%+3,1)=texminv
t(a*vpf%+4,0)=texminu+tdu/2
t(a*vpf%+4,1)=texmaxv
t(a*vpf%+5,0)=texminu+tdu*(a+1)/nf%
t(a*vpf%+5,1)=texminv
ENDIF
NEXT a
PRINT nv%
ENDPROC
:
DEFPROCMake3D_Prism(nf%,v(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv):Make3dLibNormals%=FALSE
DEFPROCMake3D_Cylinder(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv):Make3dLibNormals%=TRUE
LOCAL r,r2
r=1
r2=1
DEFPROCMake3D_TruncCone(r,r2,nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv):Make3dLibNormals%=TRUE
LOCAL a,pa,vpf%,nv%,l,tdu,tdv
IF capped% THEN vpf%=12 ELSE vpf%=6
nv%=vpf%*(endface%-startface%+1)
l=1
tdu=texmaxu-texminu
tdv=texmaxv-texminv
FOR a=0 TO endface%-startface%
pa=a+startface%-1
py=r*SIN(pa*2*PI/nf%)
pz=r*COS(pa*2*PI/nf%)
py2=r*SIN((pa+1)*2*PI/nf%)
pz2=r*COS((pa+1)*2*PI/nf%)
ey=r2*SIN(pa*2*PI/nf%)
ez=r2*COS(pa*2*PI/nf%)
ey2=r2*SIN((pa+1)*2*PI/nf%)
ez2=r2*COS((pa+1)*2*PI/nf%)
v(a*vpf%,0)=0
v(a*vpf%,1)=py
v(a*vpf%,2)=pz
v(a*vpf%+1,0)=l
v(a*vpf%+1,1)=ey2
v(a*vpf%+1,2)=ez2
v(a*vpf%+2,0)=l
v(a*vpf%+2,1)=ey
v(a*vpf%+2,2)=ez
v(a*vpf%+3,0)=0
v(a*vpf%+3,1)=py
v(a*vpf%+3,2)=pz
v(a*vpf%+4,0)=0
v(a*vpf%+4,1)=py2
v(a*vpf%+4,2)=pz2
v(a*vpf%+5,0)=l
v(a*vpf%+5,1)=ey2
v(a*vpf%+5,2)=ez2
IF Make3dLibNormals% THEN
ny=(r+1)*SIN(pa*2*PI/nf%)
nz=(r+1)*COS(pa*2*PI/nf%)
ny2=(r+1)*SIN((pa+1)*2*PI/nf%)
nz2=(r+1)*COS((pa+1)*2*PI/nf%)
eny=(r2+1)*SIN(pa*2*PI/nf%)
enz=(r2+1)*COS(pa*2*PI/nf%)
eny2=(r2+1)*SIN((pa+1)*2*PI/nf%)
enz2=(r2+1)*COS((pa+1)*2*PI/nf%)
vn(a*vpf%,0)=0
vn(a*vpf%,1)=ny
vn(a*vpf%,2)=nz
vn(a*vpf%+1,0)=l
vn(a*vpf%+1,1)=eny2
vn(a*vpf%+1,2)=enz2
vn(a*vpf%+2,0)=l
vn(a*vpf%+2,1)=eny
vn(a*vpf%+2,2)=enz
vn(a*vpf%+3,0)=0
vn(a*vpf%+3,1)=ny
vn(a*vpf%+3,2)=nz
vn(a*vpf%+4,0)=0
vn(a*vpf%+4,1)=ny2
vn(a*vpf%+4,2)=nz2
vn(a*vpf%+5,0)=l
vn(a*vpf%+5,1)=eny2
vn(a*vpf%+5,2)=enz2
ENDIF
t(a*vpf%,0)=texminu
t(a*vpf%,1)=texminv+tdv*pa/nf%
t(a*vpf%+1,0)=texmaxu
t(a*vpf%+1,1)=texminv+tdv*(pa+1)/nf%
t(a*vpf%+2,0)=texmaxu
t(a*vpf%+2,1)=texminv+tdv*pa/nf%
t(a*vpf%+3,0)=texminu
t(a*vpf%+3,1)=texminv+tdv*pa/nf%
t(a*vpf%+4,0)=texminu
t(a*vpf%+4,1)=texminv+tdv*(pa+1)/nf%
t(a*vpf%+5,0)=texmaxu
t(a*vpf%+5,1)=texminv+tdv*(pa+1)/nf%
IF capped% THEN
v(a*vpf%+6,0)=0
v(a*vpf%+6,1)=py
v(a*vpf%+6,2)=pz
v(a*vpf%+7,0)=0
v(a*vpf%+7,1)=0
v(a*vpf%+7,2)=0
v(a*vpf%+8,0)=0
v(a*vpf%+8,1)=py2
v(a*vpf%+8,2)=pz2
v(a*vpf%+9,0)=l
v(a*vpf%+9,1)=ey
v(a*vpf%+9,2)=ez
v(a*vpf%+10,0)=l
v(a*vpf%+10,1)=0
v(a*vpf%+10,2)=0
v(a*vpf%+11,0)=l
v(a*vpf%+11,1)=ey2
v(a*vpf%+11,2)=ez2
IF Make3dLibNormals% THEN
vn(a*vpf%+6,0)=-10
vn(a*vpf%+6,1)=py
vn(a*vpf%+6,2)=pz
vn(a*vpf%+7,0)=-10
vn(a*vpf%+7,1)=0
vn(a*vpf%+7,2)=0
vn(a*vpf%+8,0)=-10
vn(a*vpf%+8,1)=py2
vn(a*vpf%+8,2)=pz2
vn(a*vpf%+9,0)=l+10
vn(a*vpf%+9,1)=ey2
vn(a*vpf%+9,2)=ez2
vn(a*vpf%+10,0)=l+10
vn(a*vpf%+10,1)=0
vn(a*vpf%+10,2)=0
vn(a*vpf%+11,0)=l+10
vn(a*vpf%+11,1)=ey2
vn(a*vpf%+11,2)=ez2
ENDIF
t(a*vpf%+6,0)=texminu+tdu*a/nf%
t(a*vpf%+6,1)=texminv
t(a*vpf%+7,0)=texminu+tdu/2
t(a*vpf%+7,1)=texmaxv
t(a*vpf%+8,0)=texminu+tdu*(a+1)/nf%
t(a*vpf%+8,1)=texminv
t(a*vpf%+9,0)=texminu+tdu*a/nf%
t(a*vpf%+9,1)=texminv
t(a*vpf%+10,0)=texminu+tdu/2
t(a*vpf%+10,1)=texmaxv
t(a*vpf%+11,0)=texminu+tdu*(a+1)/nf%
t(a*vpf%+11,1)=texminv
ENDIF
NEXT a
ENDPROC
:
DEFPROCRotate(a(),xa,ya,za)
LOCAL xrm(),yrm(),zrm()
DIM xrm(2,2),yrm(2,2),zrm(2,2)
xrm()=1,0,0,0,COS(xa),-SIN(xa),0,SIN(xa),COS(xa)
yrm()=COS(ya),0,SIN(ya),0,1,0,-SIN(ya),0,COS(ya)
zrm()=COS(za),-SIN(za),0,SIN(za),COS(za),0,0,0,1
xrm()=xrm().yrm()
xrm()=xrm().zrm()
a()=a().xrm()
ENDPROC
:
DEFPROCShift(a(),dx,dy,dz,nv%)
LOCAL x%
FOR x%=0 TO nv%-1
a(x%,0)+=dx
a(x%,1)+=dy
a(x%,2)+=dz
NEXT x%
ENDPROC
:
DEFPROCShear(nv%,a(),xs,ys,zs)
LOCAL x%,maxx,maxy,maxz
FOR x%=0 TO nv%-1
IF ABS(a(x%,0))>maxx THEN maxx=ABS(a(x%,0))
IF ABS(a(x%,1))>maxy THEN maxy=ABS(a(x%,1))
IF ABS(a(x%,2))>maxz THEN maxz=ABS(a(x%,2))
NEXT x%
FOR x%=0 TO nv%-1
a(x%,1)+=xs*a(x%,0)/maxx
a(x%,2)+=ys*a(x%,1)/maxy
a(x%,0)+=zs*a(x%,2)/maxz
NEXT x%
ENDPROC
:
DEFPROCDisplay(v(),n(),nv%)
LOCAL x%,xoff,yoff,zoff,xr,yr,zr
xoff=1000
yoff=700
zoff=0
xr=0
yr=0
zr=0
*REFRESH OFF
FOR zr=0 TO 2*PI STEP 0.1
yr=zr/2
xr=zr/3
vr()=v()
vr()*=100
vnr()=vn()
vnr()*=100
PROCRotate(vr(),xr,yr,zr)
PROCShift(vr(),xoff,yoff,0,nv%)
PROCRotate(vnr(),xr,yr,zr)
PROCShift(vnr(),xoff,yoff,0,nv%)
FOR x%=0 TO nv%-2 STEP 3
MOVE vr(x%,0),vr(x%,1)
DRAW vr(x%+1,0),vr(x%+1,1)
DRAW vr(x%+2,0),vr(x%+2,1)
LINE vr(x%,0),vr(x%,1),vnr(x%,0),vnr(x%,1)
NEXT x%
*REFRESH
WAIT 5
CLS
NEXT zr
*REFRESH ON
ENDPROC
:
DEFPROCNormalise(nv%,n())
LOCAL x%,l
FOR x%=0 TO nv%-1 STEP 3
l=SQR(n(x%,0)^2 + n(x%,1)^2+n(x%,2)^2)
IF l<>0 THEN
n(x%,0)/=l
n(x%,1)/=l
n(x%,2)/=l
ENDIF
NEXT x%
ENDPROC
:
DEFPROCStretch(nv%,v(),xf,yf,zf)
LOCAL x%
FOR x%=0 TO nv%-1
v(x%,0)*=xf
v(x%,1)*=yf
v(x%,2)*=zf
NEXT x%
ENDPROC
:
DEFPROCFindNormals(nv%,v(),n())
LOCAL a,b,c,d,e,f,x%,y%,t()
DIM t(2)
REM Modified slightly from Richard's "lighting" program
FOR x%=0 TO nv%-2 STEP 3
a = v(x%+1,0) - v(x%+2,0)
b = v(x%+1,1) - v(x%+2,1)
c = v(x%+1,2) - v(x%+2,2)
d = v(x%,0) - v(x%+2,0)
e = v(x%,1) - v(x%+2,1)
f = v(x%,2) - v(x%+2,2)
t(0) = b*f-c*e
t(1) = c*d-a*f
t(2) = a*e-b*d
t() /= MOD(t())
FOR y%=0 TO 2
n(x%+y%,0) = t(0)
n(x%+y%,1) = t(1)
n(x%+y%,2) = t(2)
NEXT y%
NEXT x%
ENDPROC
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: The 3D editor tool kit: ideas
« Reply #7 on: Sep 15th, 2017, 12:07pm » |
|
The first part had the routines for making and manipulating the primitives: this part is the routines for writing them to a B3D file (that's what Richard calls them, so I've stuck with that nomenclature).
You can either use "PROCWriteB3D", which writes a single set of data to a file, or you can use the more complex but more flexible routine of:
FNOpenB3D (to open the file and write the initial data. Note that you need to know the total number of vertices you will need before you do that! returns a file handle needed to extend and close it)
Then use
PROCExtendB3D to write each component in turn.
Once you've sent them all to the file,
PROCCloseB3D
Note that using this approach means that each component can be a different colour. If you want different vertices to be different colours you'll need to make some changes! More sensibly, you can map a texture to the shape (but you can only have one texture for the whole, combined, shape.)
You can specify which part of the texture is used to cover each component,so you could have a "patchwork" texture, and use the relevant bit. I'll work on an example at some point.
There are a few other routines to put numbers into SINGLE format, stolen from Richard's 3D code, and one to change a text string to upper case, for convenience in the routine where you can ask what size a buffer needs to be.
I'll post some code using this library to make the starship Enterprise, as an example.
Then I'll post some instructions on how to use the routines.
Best wishes,
D Code: :
DEFPROCWriteB3D(name$,nv%,vf%,vdat(),ndat(),tdat(),acol%,scol%)
LOCAL f%,x%,vs%
vs%=0
IF vf% AND 2 THEN vs%+=12
IF vf% AND &10 THEN vs%+=12
IF vf% AND &40 THEN vs%+=4
IF vf% AND &80 THEN vs%+=4
IF vf% AND &100 THEN vs%+=8
REM Create file and fill it with data
f%=OPENOUT(@dir$+name$+".b3d")
PRINT nv%
PROC4(f%,nv%)
PROC4(f%,(vs%<<16)+vf%)
FOR x%=0 TO nv%-1
IF vf% AND 2 THEN PROC4(f%,FN_f4(vdat(x%,0))):PROC4(f%,FN_f4(vdat(x%,1))):PROC4(f%,FN_f4(vdat(x%,2)))
IF vf% AND &10 THEN PROC4(f%,FN_f4(ndat(x%,0))):PROC4(f%,FN_f4(ndat(x%,1))):PROC4(f%,FN_f4(ndat(x%,2)))
IF vf% AND &40 THEN PROC4(f%,acol%)
IF vf% AND &80 THEN PROC4(f%,scol%)
IF vf% AND &100 THEN PROC4(f%,FN_f4(tdat(x%,0))):PROC4(f%,FN_f4(tdat(x%,1)))
NEXT x%
CLOSE #f%
ENDPROC
:
DEFFNOpenB3D(name$,nv%,vf%)
LOCAL f%,x%,vs%
vs%=0
IF vf% AND 2 THEN vs%+=12
IF vf% AND &10 THEN vs%+=12
IF vf% AND &40 THEN vs%+=4
IF vf% AND &80 THEN vs%+=4
IF vf% AND &100 THEN vs%+=8
REM Create file and fill it with data
f%=OPENOUT(@dir$+name$+".b3d")
PROC4(f%,nv%)
PROC4(f%,(vs%<<16)+vf%)
=f%
:
DEFPROCCloseB3D(f%)
CLOSE #f%
ENDPROC
:
DEFPROCExtendB3D(f%,vf%,nv%,vdat(),ndat(),tdat(),acol%,scol%)
LOCAL x%
FOR x%=0 TO nv%-1
IF vf% AND 2 THEN PROC4(f%,FN_f4(vdat(x%,0))):PROC4(f%,FN_f4(vdat(x%,1))):PROC4(f%,FN_f4(vdat(x%,2)))
IF vf% AND &10 THEN PROC4(f%,FN_f4(ndat(x%,0))):PROC4(f%,FN_f4(ndat(x%,1))):PROC4(f%,FN_f4(ndat(x%,2)))
IF vf% AND &40 THEN PROC4(f%,acol%)
IF vf% AND &80 THEN PROC4(f%,scol%)
IF vf% AND &100 THEN PROC4(f%,FN_f4(tdat(x%,0))):PROC4(f%,FN_f4(tdat(x%,1)))
NEXT x%
ENDPROC
:
DEFPROCUpcase(RETURN n$)
LOCAL x%
FOR x%=1 TO LEN(n$)
IF ASC(MID$(n$,x%,1))>96 AND ASC(MID$(n$,x%,1))<123 THEN n$=LEFT$(n$,x%-1)+CHR$(ASC(MID$(n$,x%,1))-32)+MID$(n$,x%+1)
NEXT x%
ENDPROC
:
REM Stolen from Richard's D3D demo
DEF PROC4(F%, A%)
BPUT#F%,A% : BPUT#F%,A%>>8 : BPUT#F%,A%>>16 : BPUT#F%,A%>>24
ENDPROC
:
REM Stolen from Richard's D3D library
DEF FN_f4(A#)
LOCAL A%,P%,U#
PRIVATE F%
IF F%=0 THEN
DIM P% 10
[OPT 2
.F%
mov esi,[ebp+2]:mov edi,[ebp+7]
fld qword [esi]:fstp dword [edi]
ret
]
ENDIF
!(^U#+4)=&3FF00000
A#*=U#
CALL F%,A#,A%
=A%
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: The 3D editor tool kit: ideas
« Reply #8 on: Sep 15th, 2017, 12:26pm » |
|
Here is the code to generate a B3D file holding a model something like the starship Enterprise.
Code: REM A Demonstration program using Make3DLib to generate a model of the Starship Enterprise
INSTALL "Make3dLib.BBC"
capped%=TRUE :REM Include ends on the cylinder
nf%=20 :REM Number of faces
startface%=1 :REM Include the whole cylinder, or only part of it?
endface%=10
REM Coordinates to map a texture to the shape. You might want to use only a small part of a texture
texminu=0
texmaxu=1
texminv=0
texmaxv=1
maxnv%=FNGetNumVerts("sphere",nf%,1,nf%,TRUE)
DIM v(maxnv%,2),vn(maxnv%,2),t(maxnv%,1) :REM hold vertex, normal, and texture data
DIM vr(maxnv%,2),vnr(maxnv%,2) :REM These are only needed for the display routine
nf%=10
REM We need to count up all the vertices that will be used in all the sections, so that we can put it at the beginning of the file
tnv%=4*FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)+1*FNGetNumVerts("sphere",nf%,1,nf%,FALSE)+4*FNGetNumVerts("sphere",nf%,6,nf%,FALSE)+4*FNGetNumVerts("prism",5,1,5,FALSE)
vform%=&52 :REM Here I'm making a file with vertex, normal, and colour data
fh%=FNOpenB3D("Enterprise",tnv%,vform%)
nv%=FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)
PROCMake3D_TruncCone(1.0,0.5,nf%,v(),vn(),t(),1,nf%,TRUE,texminu,texmaxu,textminv,texmaxv)
PROCStretch(nv%,v(),-0.5,1,1)
REM Normals for smooth shapes are initially generated as their endpoints, so that can be scaled etc,
REM So we need to carry out any transformations on them in parallel
PROCStretch(nv%,vn(),-0.5,1,1)
REM Now we need to convert the normals to normalised vectors
vn()=vn()-v()
PROCNormalise(nv%,vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)
nv%=FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)
PROCMake3D_TruncCone(1.0,0.5,nf%,v(),vn(),t(),1,nf%,TRUE,texminu,texmaxu,textminv,texmaxv)
PROCStretch(nv%,v(),4,1,1)
PROCStretch(nv%,vn(),4,1,1)
vn()=vn()-v() :REM "Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
PROCNormalise(nv%,vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)
nv%=FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)
PROCMake3D_TruncCone(0.5,0.4,nf%,v(),vn(),t(),1,nf%,TRUE,texminu,texmaxu,textminv,texmaxv)
PROCStretch(nv%,v(),4,1,1)
PROCStretch(nv%,vn(),4,1,1)
PROCShift(v(),2,2.5,2.5,nv%)
PROCShift(vn(),2,2.5,2.5,nv%)
vn()=vn()-v() :REM "Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
PROCNormalise(nv%,vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)
nv%=FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)
PROCMake3D_TruncCone(0.5,0.4,nf%,v(),vn(),t(),1,nf%,TRUE,texminu,texmaxu,textminv,texmaxv)
PROCStretch(nv%,v(),4,1,1)
PROCStretch(nv%,vn(),4,1,1)
PROCShift(v(),2,2.5,-2.5,nv%)
PROCShift(vn(),2,2.5,-2.5,nv%)
vn()=vn()-v() :REM "Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
PROCNormalise(nv%,vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)
nv%=FNGetNumVerts("sphere",nf%,1,nf%,TRUE)
PROCMake3D_Sphere(nf%,v(),vn(),t(),1,nf%,texminu,texmaxu,textminv,texmaxv)
PROCStretch(nv%,v(),3,0.2,3)
PROCStretch(nv%,vn(),3,0.2,3)
PROCShift(v(),-2,1.5,0,nv%)
PROCShift(vn(),-2,1.5,0,nv%)
vn()=vn()-v() :REM "Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
PROCNormalise(nv%,vn())
PROCFindNormals(nv%,v(),vn()) :REM Cheat: something is going wrong with normals of sphere by flattening it so much: cheat by using triangles directly - OK when this flat
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)
nf%=4
nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,texminu,texmaxu,textminv,texmaxv)
PROCRotate(v(),PI/4,0,0)
PROCStretch(nv%,v(),3.5,0.5,0.2)
PROCRotate(v(),0,0,-PI/2)
PROCRotate(v(),-PI/4,0,0)
PROCShift(v(),2.5,0,0,nv%)
PROCFindNormals(nv%,v(),vn()) :REM With facetted shapes we can simply calculate the normals after all the messing around
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)
nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,texminu,texmaxu,textminv,texmaxv)
PROCRotate(v(),PI/4,0,0)
PROCStretch(nv%,v(),3.5,0.5,0.2)
PROCRotate(v(),0,0,-PI/2)
PROCRotate(v(),PI/4,0,0)
PROCShift(v(),2.5,0,0,nv%)
PROCFindNormals(nv%,v(),vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)
nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,texminu,texmaxu,textminv,texmaxv)
PROCRotate(v(),PI/4,0,0)
PROCStretch(nv%,v(),1.5,0.5,0.3)
PROCShear(nv%,v(),2,0,0)
PROCRotate(v(),0,0,-PI/2)
PROCShift(v(),1,0,0,nv%)
PROCFindNormals(nv%,v(),vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)
nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,texminu,texmaxu,textminv,texmaxv)
PROCRotate(v(),PI/4,0,0)
PROCStretch(nv%,v(),0.5,0.1,0.1)
PROCShift(v(),-1,0,0,nv%)
PROCFindNormals(nv%,v(),vn()) :REM Cheating here - the flattening is messing with the normals, so I've just treated it as a facetted surface
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF804040,&FFFFFFFF)
nf%=10
nv%=FNGetNumVerts("sphere",nf%,6,nf%,TRUE)
PROCMake3D_Sphere(nf%,v(),vn(),t(),6,nf%,texminu,texmaxu,textminv,texmaxv)
PROCStretch(nv%,v(),0.2,0.5,0.5)
PROCStretch(nv%,vn(),0.2,0.5,0.5)
PROCShift(v(),-0.8,0,0,nv%)
PROCShift(vn(),-0.8,0,0,nv%)
vn()=vn()-v()
PROCNormalise(nv%,vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF804040,&FFFFFFFF)
nv%=FNGetNumVerts("sphere",nf%,1,5,TRUE)
PROCMake3D_Sphere(nf%,v(),vn(),t(),1,5,texminu,texmaxu,textminv,texmaxv)
PROCStretch(nv%,v(),0.4,0.4,0.4)
PROCStretch(nv%,vn(),0.4,0.4,0.4)
PROCShift(v(),2,2.5,-2.5,nv%)
PROCShift(vn(),2,2.5,-2.5,nv%)
vn()=vn()-v()
PROCNormalise(nv%,vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FFF04040,&FFFFFFFF)
nv%=FNGetNumVerts("sphere",nf%,1,5,TRUE)
PROCMake3D_Sphere(nf%,v(),vn(),t(),1,5,texminu,texmaxu,textminv,texmaxv)
PROCStretch(nv%,v(),0.4,0.4,0.4)
PROCStretch(nv%,vn(),0.4,0.4,0.4)
PROCShift(v(),2,2.5,2.5,nv%)
PROCShift(vn(),2,2.5,2.5,nv%)
vn()=vn()-v()
PROCNormalise(nv%,vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FFF04040,&FFFFFFFF)
nv%=FNGetNumVerts("sphere",nf%,6,nf%,TRUE)
PROCMake3D_Sphere(nf%,v(),vn(),t(),6,nf%,texminu,texmaxu,textminv,texmaxv)
PROCRotate(v(),0,0,-PI/2)
PROCRotate(vn(),0,0,-PI/2)
PROCStretch(nv%,v(),1,0.3,0.5)
PROCStretch(nv%,vn(),1,0.3,0.5)
PROCShift(v(),-1.7,1.7,0,nv%)
PROCShift(vn(),-1.7,1.7,0,nv%)
vn()=vn()-v()
PROCNormalise(nv%,vn())
PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)
PROCCloseB3D(fh%)
PRINT "Success!"
END
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: The 3D editor tool kit: ideas
« Reply #9 on: Sep 15th, 2017, 9:59pm » |
|
Here are my comments, in the form of REMs which can be pasted at the head of the library Code:
REM Make3dLib: A set of routines to create, manipulate and combine a range of primitive shapes,
REM which can then be written to a file to be loaded by D3DLib or equivalents
REM For each shape you can specify the number of faces (nf%) making up up the "cylinder" it fits in,
REM controlling how good the mapping to a circular profile is.
REM You can also specify which of these sides to start and end drawing at, allowing you to produce part-shapes-
REM so the sphere routine can make hemispheres, or "collars", or the cylinder routine can make bulges on the side of something.
REM Rather perversely, startface%=1 means the first one, and endface%=nf% means the last one - unlike almost everything else it isn't 0-based.
REM You can specify that capped% is TRUE or FALSE: if true, the ends of cylinders etc will be filled.
REM By default, the resulting mesh will have a length 1 and/or radius 1, but by changing the r or l parameters in the routine you can change this.
REM It's probably better to leave it as 1, and then scale the figures later.
REM Cylinders, cones etc all have the origin in the middle of their base, and extend positively along the X axis (to 1).
REM Spheres are centred on the origin (so extend from -1 to 1).
REM For truncated Cylinders you can specify a starting and ending radius: the starting one will apply at x=0 and the ending one at x=1. Either can be larger.
REM At present, all routines generate vertices, and texture mapping coordinates.
REM All "smooth"-surfaced ones (cylinder, cone, truncated cone, sphere) also generate normals- but do so by generating the endpoint of the normal.
REM This is so that shapes can be manipulated, with the array of normal-ends being manipulated in parallel, to maintain them. This is a bit clumsy, but useful.
REM For facetted shapes (prisms) it's easier to generate the normals at the end, using PROCFindNormals, from the coordinates of each triangle (since all 3 points share the same normal).
REM You can do the same for any of the smooth shapes, to create facetted equivalents - simply send the array of normals to PROCFindNormal, and they will be overwritten.
REM In general, you need to create a set of arrays, to hold vertices (xyz values), normals (xyz values), and texture coordinates (uv values, equivalent to xy coordinates on the texture, scaled between 0 and 1).
REM Each of these needs to have a first dimension of (at least) the number of vertices to be generated. FNGetNumVerts() will return this.
REM All arrays are 0-based. So, for example, having determined that you need nv% vertices, you might DIM v(nv%-1,2), n(nv%-1,2),t(nv%-1,1)
REM v(x%,0) refers to the x coordinate, v(x%,1) refers to the y coordinate, and v(x%,2) refers to the z coordinate of point x% (the first point is at x%=0).
REM It's probably best to work out the most complex shape you will need, then DIM the arrays for that - then you can recycle them.
REM Spheres are by far the biggest, so if you choose arrays to hold, say, a 20-sided sphere, which needs 4560 vertices, you should be OK.
REM Go much bigger and you are likely to need to raise HIMEM....
REM FNGetNumVerts(n$,nf%,startface%,endface%,capped%) takes the name of a shape (cylinder,prism, trunccone,sphere,cone; case insensitive) and other elements as noted above, and returns the number of vertices generated
REM PROCMake3D_Sphere(nf%,v(),n(),t(),startface%,endface%,texminu,texmaxu,texminv,texmaxv) Generates a sphere, or part of one, returning vertices in v(),normals in n() and texture coordinates in t()
REM PROCMake3D_Cone(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,texminv,texmaxv) similarly generates a cone
REM PROCMake3D_Prism(nf%,v(),t(),startface%,endface%,capped%,texminu,texmaxu,texminv,texmaxv) Generates a prism (flat-sided structure, where edges are parallel to x axis).
REM An equivalent effect can be generated by using PROCMake3D_Cylinder() and then using PROCFindNormals.
REM PROCMake3D_Cylinder(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,texminv,texmaxv) Generates a cylinder
REM PROCMake3D_TruncCone(r,r2,nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,texminv,texmaxv) generates a truncated cone, tapering from r to r1 as it goes from 0 to 1 on the x axis
REM All these routines take minimum and maximum values for U andd V coordinates for texture mapping set these to 0 and 1 respectively to use the whole texture, or subfractions of this to use a bit of a "patchwork" texture
REM Then there are a series of routines to modify the basic primitives:
REM PROCRotate(a(),xa,ya,za) takes an array of coordinates, and rotates them around the x axis by xa radians, around the y axis by ya radians, and around the z axis by za radians
REM It does it in this order, and that is important! You can do all three at once, but it may be easier to visualise if you do one at a time!
REM PROCShift(a(),dx,dy,dz,nv%) takes an array of coordinates, and shifts the whole thing as specified in the x,y, and z directions
REM PROCStretch(nv%,v(),xf,yf,zf) takes an array of coordinates and stretches it in each direction by the factor specified. You could make them all the same to scale it, but...
REM You can scale a whole array by simply multiplying it by the relevant scale factor (for example, v()*=3 )
REM PROCShear(nv%,a(),xs,ys,zs) Shears the shape along the x axis in the y direction by xs, along the y axis in the z direction by ys, and along the z axis in the x direction by zs
REM This seemed a good idea at the time, but is hard to use. I'll probably change it in future versions to specify the amount of shear, the axis along which it's applied, and the direction to change
REM That will break existing uses, but be much more user friendly.
REM PROCNormalise(nv%,n()) takes an array of normals, and normalises them to a vector length of 1.
REM If you've got a set of normal end points generated by one of the smoooth routines (sphere, cone, etc) you should convert them to vectors (by subtracting the underlying vertex address) and then normalise them
REM For example you could do n()-=v():PROCNormalise(nv%,n())
REM PROCFindNormals(nv%,v(),n()) takes an array of vertices and calculates the (normalised) normals to each triangle, then sticks them in the normals array for each point of the triangle
REM If you have/want a shape with flat faces, you can just pass it the vertex array once all your fiddling around has been done, and just before you want to write it to a file.
REM PROCDisplay(v(),n(),nv%) will display a wire-frame version of your shape, with the normal for the first point of each triangle sticking out.
REM It's really for diagnostic use, but I've left it in. You might want to fiddle with the offset and scaling values depending on your display.
REM PROCWriteB3D(name$,nv%,vf%,vdat(),ndat(),tdat(),acol%,scol%) writes a whole file at once, based on a single set of buffers. You need to supply the vertex format - have a look at the the manual for details
REM FNOpenB3D(name$,nv%,vf%) Opens a file, and writes the vertex format and size (calculated itself from the format) as well as the total number of vertices to be written to it.
REM returns a handle to the file
REM PROCCloseB3D(f%) Go on - have a wild guess! The parameter is the file handle returned by FNOpenB3D
REM PROCExtendB3D(f%,vf%,nv%,vdat(),ndat(),tdat(),acol%,scol%) Writes data from one set of arrays to the file previously opened. acol% and scol% are colours for ambient and specular lighting, respectively.
REM Only the data specified by the vertex format code is actually written
REM PROCUpcase(RETURN n$) Takes a string, and returns it with all lower case letters converted to upper case. Non-alphabetic characters are left untouched
REM PROC4(F%, A%) Routine stolen from Richard's D3D programs; it writes 4 bytes to the file
REM FN_f4(A#) Routine stolen from Richard's D3D programs; it takes a float variable and converts it to a "single" (i.e. 32 bit float), returned in an integer variable. This is the format required by Direct3D
|
|
Logged
|
|
|
|
michael
Senior Member
member is offline


Posts: 335
|
 |
Re: The 3D editor tool kit: ideas
« Reply #10 on: Sep 16th, 2017, 02:14am » |
|
Very nice work! Ill get some shapes made this weekend.
|
|
Logged
|
I like making program generators and like reinventing the wheel
|
|
|
michael
Senior Member
member is offline


Posts: 335
|
 |
Re: The 3D editor tool kit: ideas
« Reply #11 on: Sep 24th, 2017, 01:16am » |
|
DDRM, would you be so kind as to repost the 3D tools you provided on Richards Forum? I am sure he would be happy to see this on his forum.
I cant do it, as it would be improper. I think he would like this very much as a contribution.
Also I hope to surprise everyone on Monday night with a useable object editor for both forums on one screen for both BBC4W and BBCSDL.
I appreciate this DDRM !!
|
|
Logged
|
I like making program generators and like reinventing the wheel
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: The 3D editor tool kit: ideas
« Reply #12 on: Sep 24th, 2017, 6:35pm » |
|
Hi Folks,
I've posted my current version of "Make3DLib" in the libraries section of the files section of the groups.io discussion group.
https://groups.io/g/bb4w/files/Libraries/Make3dLib.bbc
It does one naughty thing - it uses a global variable to facilitate "overloading" of the routines.
You may need to be logged in as a member to get it. It's slightly updated from the version I posted on the BB4W conforum - most significantly with much better texture mapping to some shapes.
It has fairly copious notes at the beginning about what routines are included, and how to use them, and I've got some sort examples which give an idea. It can make spheres, cones,cylinders, truncated cones (and, indirectly prisms) prisms and write them either singly or en masses to an FVF file. You can include coordinates, normals, texture coordinates, and ambient and specular colours, depending on the vertex format code you specify. There are also routines to modify the shapes (shear/stretch/rotate/translate), so you can align them to make more complex shapes.
I will add some more primitives (torus and "cove" are on my list - the latter once I work out how to calculate the external centre of curvature!
Best wishes,
D
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: The 3D editor tool kit: ideas
« Reply #13 on: Sep 27th, 2017, 2:03pm » |
|
Here's an example which: 1) Generates a bitmap file to use as a texture 2) Makes a model of a jewel-hilted sword and saves it as an FVF file.
As a clarification on why this is now an FVF file not a B3D file, Richard has clarified that this is a better nomenclature: he chose B3D not realising it already had a use in the "graphics market". FVF stands for "flexible vertex format", which is what Microsoft call it.
I've assumed that you will save this file into the same directory as your "viewer", so the bitmap will be accessible. I've also assumed Make3DLib is in the same folder: if not, amend the INSTALL call appropriately (for example, by adding @libs$+).
You can use the viewer I listed below, but you'll need to change the file loaded into b%(0) to "sword.fvf",and the texture loaded into t%(0) to "swordtexture.bmp".
Note that the bitmap is made up of four regions, each of which is used in different parts of the sword. The texminu/texmaxu/texminv/texmaxv parameters are used to set the texture coordinates appropriately.
You'll need to use the most recent version of the library, posted on the groups.io site (see link below) to get correct rendering of the bitmap to the shape. Here's the link again: https://groups.io/g/bb4w/files/Libraries/Make3dLib.bbc
Best wishes,
D
Code:
INSTALL "Make3DLib"
MODE 21
GCOL 7
RECTANGLE FILL 100,100,512,256
FOR x%=1 TO 3
FOR y%=1 TO 3
PROCPoly(8,0,x%*60+100,100+60*y%,20,20,1,9)
NEXT y%
NEXT x%
GCOL 0
LINE 356,150,480,150
LINE 356,180,480,180
LINE 356,280,480,280
LINE 356,310,480,310
FOR x%=100 TO 356 STEP 16
GCOL 0
RECTANGLE FILL x%,356,4,256
GCOL 8
RECTANGLE FILL x%+4,356,12,256
GCOL 7
RECTANGLE FILL x%+8,356,2,256
NEXT x%
GCOL 3
RECTANGLE FILL 356,356,256,256
*GSAVE swordtexture.bmp 100,100,512,512
nf%=6
maxverts%=FNGetNumVerts("Sphere",nf%,1,nf%,TRUE)
DIM v(maxverts%-1,2),n(maxverts%-1,2),t(maxverts%-1,1)
nf%=6
totalverts%=2*FNGetNumVerts("prism",nf%,1,nf%,FALSE)+FNGetNumVerts("cone",nf%,1,nf%,FALSE)+FNGetNumVerts("prism",4,1,4,FALSE)+3*FNGetNumVerts("sphere",nf%,1,nf%,FALSE)
vf%=&152
f%=FNOpenFVF("sword",totalverts%,vf%)
nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,0.5,0.75,0,0.5)
PROCStretch(nv%,v(),3,0.1,0.3)
PROCFindNormals(nv%,v(),n())
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)
nv%=FNGetNumVerts("cone",nf%,1,nf%,FALSE)
PROCMake3D_Cone(nf%,v(),n(),t(),1,nf%,FALSE,0.75,1.0,0,0.5)
PROCStretch(nv%,v(),0.5,0.1,0.3)
PROCShift(v(),3,0,0,nv%)
PROCFindNormals(nv%,v(),n())
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)
nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,0.0,0.5,0.5,1.0)
PROCStretch(nv%,v(),1,0.15,0.15)
PROCShift(v(),-1,0,0,nv%)
PROCFindNormals(nv%,v(),n())
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)
nf%=4
nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,0.5,1.0,0.5,1.0)
PROCShift(v(),-0.5,0,0,nv%)
PROCStretch(nv%,v(),1.5,0.15,0.15)
PROCRotate(v(),-PI/4,PI/2,0)
PROCFindNormals(nv%,v(),n())
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)
nf%=6
nv%=FNGetNumVerts("sphere",nf%,1,nf%,FALSE)
PROCMake3D_Sphere(nf%,v(),n(),t(),1,nf%,0.0,0.4,0.1,0.4)
v()*=0.2
n()*=0.2
PROCRotate(v(),PI,0,0)
PROCRotate(n(),PI,0,0)
PROCShift(v(),0,0,-0.75,nv%)
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)
nv%=FNGetNumVerts("sphere",nf%,1,nf%,FALSE)
PROCMake3D_Sphere(nf%,v(),n(),t(),1,nf%,0.0,0.4,0.1,0.4)
v()*=0.2
n()*=0.2
PROCShift(v(),0,0,0.75,nv%)
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)
nv%=FNGetNumVerts("sphere",nf%,1,nf%,FALSE)
PROCMake3D_Sphere(nf%,v(),n(),t(),1,nf%,0.0,0.4,0.01,0.4)
v()*=0.3
n()*=0.3
PROCShift(v(),-1,0,0,nv%)
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)
PROCCloseFVF(f%)
END
:
DEFPROCPoly(n%,starta,cx%,cy%,hr%,vr%,c1%,c2%)
REM number of sides, start angle in radians, centre x and y, horizontal and vertical radii, main and highlight colours
LOCAL a%,dx%,dy%
REM Draw basic shape
GCOL c1%
FOR a%=0 TO n%-1
MOVE cx%,cy%
dx%=hr%*COS(2*PI*a%/n%+starta)
dy%=vr%*SIN(2*PI*a%/n%+starta)
MOVE cx%+dx%,cy%+dy%
dx%=hr%*COS(2*PI*(a%+1)/n%+starta)
dy%=vr%*SIN(2*PI*(a%+1)/n%+starta)
PLOT 85,cx%+dx%,cy%+dy%
NEXT a%
REM add radii in highlight colour
GCOL c2%
FOR a%=0 TO n%-1
dx%=hr%*COS(2*PI*a%/n%+starta)
dy%=vr%*SIN(2*PI*a%/n%+starta)
LINE cx%,cy%,cx%+dx%,cy%+dy%
NEXT a%
REM Draw a front facet half the size
hr% DIV=2
vr% DIV=2
FOR a%=0 TO n%-1
MOVE cx%,cy%
dx%=hr%*COS(2*PI*a%/n%+starta)
dy%=vr%*SIN(2*PI*a%/n%+starta)
MOVE cx%+dx%,cy%+dy%
dx%=hr%*COS(2*PI*(a%+1)/n%+starta)
dy%=vr%*SIN(2*PI*(a%+1)/n%+starta)
PLOT 85,cx%+dx%,cy%+dy%
NEXT a%
ENDPROC
:
|
|
Logged
|
|
|
|
michael
Senior Member
member is offline


Posts: 335
|
 |
Re: The 3D editor tool kit: ideas
« Reply #14 on: Sep 28th, 2017, 03:13am » |
|
Nice work DDRM! And here is the viewer:
TYPE: sword When it asks for the file name and then when the black screen shows, left click with your mouse..
ALSO: use left mouse button on TOP, RIGHT, LEFT and BOTTOM of screen to rotate the object.
NOTE: this renderer also cycles because it is part of the 3D editor that is still being worked on. (the two window version)
I plan to add another axis of rotation and improve it much more Code: PRINT "USE LEFT MOUSE BUTTON TO ACTIVATE RENDERER AND TO ROTATE THE OBJECT"
PRINT "Name of FVF image. No need for extension"
INPUT name$
peak=0
IF INKEY$(-256)="W" INSTALL @lib$+"D3DLIBA" ELSE INSTALL @lib$+"OGLLIB"
pass%=0
MODE 8
DIM l%(0), b%(1), n%(1), f%(1), s%(1), m%(1), t%(1), y(1), p(1), r(1), X(1), Y(1), Z(1), e(2), a(2)
ON CLOSE PROCcleanup:QUIT
ON ERROR PROCcleanup:PRINT REPORT$:END
IF INKEY$(-256)="W" d% = FN_initd3d(@hwnd%, 1, 0) ELSE d% = FN_initgl(@hwnd%, 1, 0)
IF d% = 0 ERROR 100, "Can't initialise Direct3D"
e() = 0, 0, -6
a() = 0, 0, 0
l%()=1
REPEAT
REPEAT
MOUSE mx,my,mb
IF mx>0 AND my>0 AND mx<1270 AND my<1000 AND mb=4 THEN pass%=1
WAIT 1
UNTIL pass%=1
IF pass%=1 THEN
IF mx>800 AND my>400 AND my<600 THEN y()+=0.1
IF mx<400 AND my>400 AND my<600 THEN y()-=0.1
IF my>600 AND my<1000 THEN p()+=0.1
IF my<400 AND my>0 THEN p()-=0.1
ENDIF
pass%=0
b%(0) = FN_load3d(d%, @dir$+name$+".FVF", n%(0), f%(0), s%(0))
IF b%(0) = 0 ERROR 100, "Can't load TRIANGLE.FVF"
t%(0) = FN_loadtexture(d%, @dir$+"swordtexture.BMP")
IF t%(0) = 0 ERROR 100, "Can't load face.JPG"
REM y() =0:REM yaw (rotations around the Y axis)
REM pitch
REM p() =0:REM TIME/100 (pitch angles rotations around the X axis)
REM roll
r() = 0:REM TIME/40 (roll angles (rotations around the Z axis)
REM X (right left)
X() = 0:REM SIN(TIME/200)
REM Y() up and down
Y() = 0
REM Z() depth
Z() = 10:REM
REM PROC_render(d%, &FF7F7F7F, 0, l%(), 2, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000)
PROC_render(d%, &FF7F7F7F, 0, l%(), 2, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000, 0) :REM experimental
REM 1 2 3 4 5 6 7 8 9 10 11 yaw pitch roll X Y Z eye0123 18 19 20 ^mcd ^( cam to farplane dist)
REM 1 Val returned from FN_init3D
REM 2 back color 3 #of lights 4 light pointers
REM t%() - holds texture
REM mcd - minimum near cam distance
WAIT 1
t%(1) += 0:IF t%(1) PROC_release(t%(1))
b%(0) += 0:IF b%(0) PROC_release(b%(0))
b%(1) += 0:IF b%(1) PROC_release(b%(1))
UNTIL FALSE
END
DEF PROCcleanup
t%(1) += 0:IF t%(1) PROC_release(t%(1))
b%(0) += 0:IF b%(0) PROC_release(b%(0))
b%(1) += 0:IF b%(1) PROC_release(b%(1))
d% += 0 :IF d% PROC_release(d%)
ENDPROC
|
« Last Edit: Sep 28th, 2017, 04:18am by michael » |
Logged
|
I like making program generators and like reinventing the wheel
|
|
|
|