result a mesh with UV mapped.
If someone can help improve it, it is appreciated.
The program create a OBJ file for test (cube cuboPB.obj).
Code: Select all
Global.b sal
Global objsize.Vector3
Global normal.Vector3
Structure caras
verXY.i
verUV.i
EndStructure
Procedure CalculateTriangleNormal(x1.f, y1.f, z1.f, x2.f, y2.f, z2.f, x3.f, y3.f, z3.f)
;devuelve la normal del triangulo
Protected.f ABx, ABy, ABz, ACx, ACy, ACz
ABx = x2 - x1
ABy = y2 - y1
ABz = z2 - z1
ACx = x3 - x1
ACy = y3 - y1
ACz = z3 - z1
; Calcula el producto cruz de AB y AC
; Protected.f Nx, Ny, Nz
normal\x = ABy * ACz - ABz * ACy
normal\y = ABz * ACx - ABx * ACz
normal\z = ABx * ACy - ABy * ACx
; Normaliza el vector resultante
Protected.f length
length = Sqr(normal\x * normal\x + normal\y * normal\y + normal\z * normal\z)
If length <> 0
normal\x = normal\x / length
normal\y = normal\y / length
normal\z = normal\z / length
EndIf
EndProcedure
Procedure CalculateNormalVector4(x1.f, y1.f, z1.f, x2.f, y2.f, z2.f, x3.f, y3.f, z3.f, x4.f, y4.f, z4.f)
;devuelve las normales de los dos triángulos formados por los vértices
Protected.f n1.Vector3, n2.Vector3
CalculateTriangleNormal(x1, y1, z1, x2, y2, z2, x3, y3, z3)
n1\x= normal\x
n1\y= normal\y
n1\z= normal\z
CalculateTriangleNormal(x1, y1, z1, x3, y3, z3, x4, y4, z4)
n2\x= normal\x
n2\y= normal\y
n2\z= normal\z
; Promedia las normales de los triángulos para obtener la normal del plano
Protected.f NormalX, NormalY, NormalZ
normal\x = (n1\x + n2\x) / 2
normal\y = (n1\y + n2\y) / 2
normal\z = (n1\z + n2\z) / 2
; Devuelve el vector normal
; Result NormalX, NormalY, NormalZ
EndProcedure
Procedure loadOBJmesh(file.s,s.f=1)
Protected.s l,a, name
Protected Dim verXY.Vector3(2000)
Protected Dim verUV.Vector3(2000)
Protected Dim faces.caras(2000,4)
Protected vposXY,vposUV,carast
Protected.b ncaras
Protected p,n
Protected tx3d,ma,e
Protected.f no,su,es,oe,ar,ab
If ReadFile(0,file)
While Eof(0)=0
l= ReadString(0)
a= StringField(l,1," ")
Select a
Case "g"
name= StringField(l,2," ")
Case "v"
vposXY+1
verXY(vposXY)\x= ValF(StringField(l,2," ")) * s
verXY(vposXY)\y= ValF(StringField(l,3," ")) * s
verXY(vposXY)\z= ValF(StringField(l,4," ")) * s
If verXY(vposXY)\x>0 : If verXY(vposXY)\x>es : es=verXY(vposXY)\x:EndIf : Else: If verXY(vposXY)\x<oe:oe=verXY(vposXY)\x : EndIf : EndIf
If verXY(vposXY)\y>0 : If verXY(vposXY)\y>ar : ar=verXY(vposXY)\y:EndIf : Else: If verXY(vposXY)\y<ab:ab=verXY(vposXY)\y : EndIf : EndIf
If verXY(vposXY)\z>0 : If verXY(vposXY)\y>no : no=verXY(vposXY)\z:EndIf : Else: If verXY(vposXY)\z<su:su=verXY(vposXY)\z : EndIf : EndIf
Case "vt"
vposUV+1
verUV(vposUV)\x= ValF(StringField(l,2," "))
verUV(vposUV)\y= 1-ValF(StringField(l,3," "))
Case "f"
carast+1
ncaras= CountString(l," ")-1
faces(carast,0)\verXY= ncaras
For n= 1 To ncaras
faces(carast,n)\verXY= ValF(StringField(StringField(l,n+1," "),1,"/"))
faces(carast,n)\verUV= ValF(StringField(StringField(l,n+1," "),2,"/"))
Next n
EndSelect
Wend
CloseFile(0)
objsize\x= Abs(oe)+es
objsize\y= Abs(ab)+ar
objsize\z= Abs(su)+no
Debug "Objeto: "+name
Debug "vertices: "+vposXY
Debug "verti.UV: "+vposUV
Debug "Caras: "+carast
Debug "NCaras: "+ncaras
Debug "Tamño: "+Str(objsize\x)+" , "+Str(objsize\y)+" , "+Str(objsize\z)+" escalado: "+StrF(s,3)
vr= 0
m= CreateMesh(#PB_Any)
For p= 1 To carast
If faces(p,0)= 3
CalculateTriangleNormal(verXY(faces(p,1)\verXY)\x, verXY(faces(p,1)\verXY)\y, verXY(faces(p,1)\verXY)\z,
verXY(faces(p,2)\verXY)\x, verXY(faces(p,2)\verXY)\y, verXY(faces(p,2)\verXY)\z,
verXY(faces(p,3)\verXY)\x, verXY(faces(p,3)\verXY)\y, verXY(faces(p,3)\verXY)\z)
Else
CalculateNormalVector4( verXY(faces(p,1)\verXY)\x, verXY(faces(p,1)\verXY)\y, verXY(faces(p,1)\verXY)\z,
verXY(faces(p,2)\verXY)\x, verXY(faces(p,2)\verXY)\y, verXY(faces(p,2)\verXY)\z,
verXY(faces(p,3)\verXY)\x, verXY(faces(p,3)\verXY)\y, verXY(faces(p,3)\verXY)\z,
verXY(faces(p,4)\verXY)\x, verXY(faces(p,4)\verXY)\y, verXY(faces(p,4)\verXY)\z)
EndIf
For n= 1 To faces(p,0)\verXY
MeshVertex( verXY(faces(p,n)\verXY)\x, verXY(faces(p,n)\verXY)\y, verXY(faces(p,n)\verXY)\z,
verUV(faces(p,n)\verUV)\x, verUV(faces(p,n)\verUV)\y, $ffffff, normal\x, normal\y, normal\z)
faces(p,n)\verXY= vr
vr +1
Next n
Next p
For p= 1 To carast
If faces(p,0)\verXY= 3
MeshFace(faces(p,1)\verXY,faces(p,2)\verXY,faces(p,3)\verXY)
Else
MeshFace(faces(p,1)\verXY,faces(p,2)\verXY,faces(p,3)\verXY,faces(p,4)\verXY)
EndIf
Next p
FinishMesh(#True)
FreeArray(verXY())
FreeArray(verUV())
FreeArray(faces())
EndIf
ProcedureReturn m
EndProcedure
Procedure grabaOBJtest(file.s="cuboPB.obj")
If CreateFile(0,file)
WriteStringN(0,"# WaveFront *.obj file (generada con purebasic)")
WriteStringN(0,"g Cubo")
WriteStringN(0,"usemtl Mat_1")
WriteStringN(0,"v -100 -100 100")
WriteStringN(0,"v -100 100 100")
WriteStringN(0,"v 100 -100 100")
WriteStringN(0,"v 100 100 100")
WriteStringN(0,"v 100 -100 -100")
WriteStringN(0,"v 100 100 -100")
WriteStringN(0,"v -100 -100 -100")
WriteStringN(0,"v -100 100 -100")
WriteStringN(0,"")
WriteStringN(0,"vt 0.511675 0.32555 0")
WriteStringN(0,"vt 0.988325 0.341117 0")
WriteStringN(0,"vt 0.011675 0.67445 0")
WriteStringN(0,"vt 0.011675 0.007784 0")
WriteStringN(0,"vt 0.988325 0.658883 0")
WriteStringN(0,"vt 0.011675 0.992216 0")
WriteStringN(0,"vt 0.988325 0.32555 0")
WriteStringN(0,"vt 0.511675 0.67445 0")
WriteStringN(0,"vt 0.488325 0.67445 0")
WriteStringN(0,"vt 0.488325 0.007784 0")
WriteStringN(0,"vt 0.511675 0.992216 0")
WriteStringN(0,"vt 0.488325 0.992216 0")
WriteStringN(0,"vt 0.988325 0.007784 0")
WriteStringN(0,"vt 0.011675 0.341117 0")
WriteStringN(0,"vt 0.988325 0.67445 0")
WriteStringN(0,"vt 0.488325 0.32555 0")
WriteStringN(0,"vt 0.011675 0.658883 0")
WriteStringN(0,"vt 0.988325 0.992216 0")
WriteStringN(0,"vt 0.511675 0.007784 0")
WriteStringN(0,"vt 0.511675 0.341117 0")
WriteStringN(0,"vt 0.488325 0.341117 0")
WriteStringN(0,"vt 0.011675 0.32555 0")
WriteStringN(0,"vt 0.511675 0.658883 0")
WriteStringN(0,"vt 0.488325 0.658883 0")
WriteStringN(0,"")
WriteStringN(0,"f 3/9 4/12 2/6 1/3 ")
WriteStringN(0,"f 5/15 6/18 4/11 3/8 ")
WriteStringN(0,"f 7/21 8/24 6/17 5/14 ")
WriteStringN(0,"f 1/2 2/5 8/23 7/20 ")
WriteStringN(0,"f 4/10 6/16 8/22 2/4 ")
WriteStringN(0,"f 5/13 3/7 1/1 7/19 ")
CloseFile(0)
EndIf
EndProcedure
Procedure eventos3D(camara, speed.f=1, mouseSpd.f=0.05)
Protected.f KeyX,KeyY, MouseX,MouseY
If KeyboardPushed(#PB_Key_A)
KeyX= -speed
ElseIf KeyboardPushed(#PB_Key_D)
KeyX= speed
Else
KeyX= 0
EndIf
If KeyboardPushed(#PB_Key_W)
KeyY= -speed
ElseIf KeyboardPushed(#PB_Key_S)
KeyY= speed
Else
KeyY= 0
EndIf
If KeyboardPushed(#PB_Key_LeftShift)
keyY * 10
keyX * 10
EndIf
MouseX = -MouseDeltaX() * mouseSpd
MouseY = -MouseDeltaY() * mouseSpd
RotateCamera(camara, MouseY, MouseX, 0, #PB_Relative)
MoveCamera (camara, KeyX, 0, KeyY)
EndProcedure
InitEngine3D(): InitSprite(): InitKeyboard(): InitMouse()
ExamineDesktops():width=DesktopWidth(0):height=DesktopHeight(0)
OpenWindow(0, 0, 0, width, height, "PB OBJ wavefront", #PB_Window_BorderLess)
SetWindowColor(0,$444444)
OpenWindowedScreen(WindowID(0), 0, 0, width,height,0,0,0,#PB_Screen_NoSynchronization)
grabaOBJtest()
m= loadOBJmesh("cuboPB.obj",0.04)
ma= CreateMaterial(#PB_Any,#Null,$ff0000)
e= CreateEntity(#PB_Any,MeshID(m),MaterialID(ma))
CreateLine3D(0,-objsize\x*2,0,0,$00ffff, objsize\x*2,0,0,$0000ff)
CreateLine3D(1,0,0,-objsize\y*2,$ffff00, 0,0,objsize\y*2,$ff0000)
CreateLine3D(2,0,-objsize\z*2,0,$00ff44, 0,objsize\z*2,0,$009900)
luz= CreateLight(#PB_Any,$ffffff,objsize\x*2,objsize\y*2,-objsize\z*2,#PB_Light_Point)
camara= CreateCamera(#PB_Any,0,0,100,100)
MoveCamera(camara,objsize\x*2,objsize\y*2,objsize\z*2)
CameraLookAt(camara,0,0,0)
CameraRange(camara, 0.1, (objsize\x+objsize\y+objsize\z)*4)
Repeat
Repeat : event= WindowEvent() : Until event= 0
ExamineKeyboard() : ExamineMouse()
eventos3D(camara, 0.1)
If KeyboardPushed(#PB_Key_Escape) : sal= 1: EndIf
ElapsedTime = RenderWorld()
FlipBuffers()
Delay(1)
Until sal=1