- je fait un produit scalaire entre la normale du triangle et les 6 cotés de ma boite englobante
- je l'applique au triangle.
Code : Tout sélectionner
IncludePath "includes" : IncludeFile "n3xtD_PB.pbi"
Enumeration
#FACE_UP
#FACE_DN
#FACE_FR
#FACE_BK
#FACE_LF
#FACE_RT
EndEnumeration
Procedure.f GetMinX(*A.VECTOR3,*B.VECTOR3,*C.VECTOR3)
If *A\x < *B\x
If *C\x < *A\x
MinX.f = *C\x
ElseIf *C\x >= *A\x
MinX = *A\x
EndIf
ElseIf *A\x >= *B\x
If *C\x < *B\x
MinX = *C\x
ElseIf *C\x >= *B\x
MinX = *B\x
EndIf
EndIf
ProcedureReturn MinX
EndProcedure
Procedure.f GetMinY(*A.VECTOR3,*B.VECTOR3,*C.VECTOR3)
If *A\y < *B\y
If *C\y < *A\y
MinY.f = *C\y
ElseIf *C\y >= *A\y
MinY = *A\y
EndIf
ElseIf *A\y >= *B\y
If *C\y < *B\y
MinY = *C\y
ElseIf *C\y >= *B\y
MinY = *B\y
EndIf
EndIf
ProcedureReturn MinY
EndProcedure
Procedure.f GetMinZ(*A.VECTOR3,*B.VECTOR3,*C.VECTOR3)
If *A\z < *B\z
If *C\z < *A\z
MinZ.f = *C\z
ElseIf *C\z >= *A\z
MinZ = *A\z
EndIf
ElseIf *A\z >= *B\z
If *C\z < *B\z
MinZ = *C\z
ElseIf *C\z >= *B\z
MinZ = *B\z
EndIf
EndIf
ProcedureReturn MinZ
EndProcedure
Procedure.f GetMaxX(*A.VECTOR3,*B.VECTOR3,*C.VECTOR3)
If *A\x > *B\x
If *C\x > *A\x
MaxX.f = *C\x
ElseIf *C\x <= *A\x
MaxX = *A\x
EndIf
ElseIf *A\x <= *B\x
If *C\x > *B\x
MaxX = *C\x
ElseIf *C\x <= *B\x
MaxX = *B\x
EndIf
EndIf
ProcedureReturn MaxX
EndProcedure
Procedure.f GetMaxY(*A.VECTOR3,*B.VECTOR3,*C.VECTOR3)
If *A\y > *B\y
If *C\y > *A\y
MaxY.f = *C\y
ElseIf *C\y <= *A\y
MaxY = *A\y
EndIf
ElseIf *A\y <= *B\y
If *C\y > *B\y
MaxY = *C\y
ElseIf *C\y <= *B\y
MaxY = *B\y
EndIf
EndIf
ProcedureReturn MaxY
EndProcedure
Procedure.f GetMaxZ(*A.VECTOR3,*B.VECTOR3,*C.VECTOR3)
If *A\z > *B\z
If *C\z > *A\z
MaxZ.f = *C\z
ElseIf *C\z <= *A\z
MaxZ = *A\z
EndIf
ElseIf *A\z <= *B\z
If *C\z > *B\z
MaxZ = *C\z
ElseIf *C\z <= *B\z
MaxZ = *B\z
EndIf
EndIf
ProcedureReturn MaxZ
EndProcedure
Procedure TransformVertex(*node.IMesh, *v.VECTOR3)
Protected mat.MATRIX
iNodeTransformation(*node, @mat\m[0])
Matrix_TransformVect(*v, @mat\m[0] )
EndProcedure
iSetAntiAlias(1)
; open n3xt-D screen
;*app = iCreateGraphics3D(800,600,0,0)
; << OR >>
*app = iCreateGraphics3D(1680,1050, 32, #True, #True, #EDT_DIRECT3D9)
If *app= #Null
End
EndIf
*Triangle.IMMesh = iCreateEmptyMesh()
iAddBufferMesh(*Triangle)
v1.l= iAddVertexMesh.l(*Triangle, 0,0,0, $884444, 0,1, 0)
v2.l= iAddVertexMesh.l(*Triangle, 2,2,0.5, $448844, 1,0.884, 0)
v3.l= iAddVertexMesh.l(*Triangle, 2,0,0, $444488, 0.53125,0, 0)
iAddFaceMesh(*Triangle, v1,v2,v3, 0)
iRotateNode(*Triangle,45,45,0)
;iTurnNode(*Triangle,0,-90,0)
iBeginScene()
iDrawScene()
iEndScene()
*meshbuf.IMeshBuffer = iMeshGeometry(*Triangle)
; récupère le nombre de triangles
num.l = iMeshBufferPolyCount.l(*meshbuf)
Define.VECTOR3 A,B,C
Macro DebugVector(A)
Debug "#A"
Debug A\x
Debug A\y
Debug A\z
EndMacro
; parcours tous les triangles
For i = 0 To num-1
iMeshBufferFace(*meshbuf, i, @v1, @v2, @v3)
iMeshBufferVertex(*meshbuf, @A, v1)
iMeshBufferVertex(*meshbuf, @B, v2)
iMeshBufferVertex(*meshbuf, @C, v3)
TransformVertex(*Triangle,A)
TransformVertex(*Triangle,B)
TransformVertex(*Triangle,C)
; BOITE ENGLOBANTE
Min.VECTOR3
Max.VECTOR3
Min\x = GetMinX(A,B,C)
Min\y = GetMinY(A,B,C)
Min\z = GetMinZ(A,B,C)
Max\x = GetMaxX(A,B,C)
Max\y = GetMaxY(A,B,C)
Max\z = GetMaxZ(A,B,C)
MidPoint.VECTOR3
MidPoint\x = (A\x+B\x+C\x)/3
MidPoint\y = (A\y+B\y+C\y)/3
MidPoint\z = (A\z+B\z+C\z)/3
;on calcul sa normale
Define.VECTOR3 Vecteur1,Vecteur2,Normale
Vecteur1\x = (B\x - A\x)
Vecteur1\y = (B\y - A\y)
Vecteur1\z = (B\z - A\z)
Vecteur2\x = (C\x - A\x)
Vecteur2\y = (C\y - A\y)
Vecteur2\z = (C\z - A\z)
Normale\x = ((Vecteur1\y * Vecteur2\z) - (Vecteur1\z * Vecteur2\y))
Normale\y = ((Vecteur1\z * Vecteur2\x) - (Vecteur1\x * Vecteur2\z))
Normale\z = ((Vecteur1\x * Vecteur2\y) - (Vecteur1\y * Vecteur2\x))
Magnitude.f = Sqr(Normale\x*Normale\x + Normale\y*Normale\y + Normale\z*Normale\z)
Normale\x / Magnitude
Normale\y / Magnitude
Normale\z / Magnitude
; elle pointe sur quel pan de la boite ?
; On connais la normale de chaque face de notre boite englobante ( elle est alignée au axes du monde 3D )
BT_NORM.VECTOR3
BT_NORM\x=0
BT_NORM\y=1
BT_NORM\z=0
UP_NORM.VECTOR3
UP_NORM\x=0
UP_NORM\y=-1
UP_NORM\z=0
FT_NORM.VECTOR3
FT_NORM\x=0
FT_NORM\y=0
FT_NORM\z=-1
BK_NORM.VECTOR3
BK_NORM\x=0
BK_NORM\y=0
BK_NORM\z=1
LF_NORM.VECTOR3
LF_NORM\x=1
LF_NORM\y=0
LF_NORM\z=0
RT_NORM.VECTOR3
RT_NORM\x=-1
RT_NORM\y=0
RT_NORM\z=0
Dim Plan.d(5)
Plan(0) = Vec3_DotProduct(@Normale,@BT_NORM)
Plan(1) = Vec3_DotProduct(@Normale,@UP_NORM)
Plan(2) = Vec3_DotProduct(@Normale,@FT_NORM)
Plan(3) = Vec3_DotProduct(@Normale,@BK_NORM)
Plan(4) = Vec3_DotProduct(@Normale,@LF_NORM)
Plan(5) = Vec3_DotProduct(@Normale,@RT_NORM)
SortArray(Plan(),#PB_Sort_Ascending)
Norme.d= Plan(0)
Plan(0) = Vec3_DotProduct(@Normale,@BT_NORM)
Plan(1) = Vec3_DotProduct(@Normale,@UP_NORM)
Plan(2) = Vec3_DotProduct(@Normale,@FT_NORM)
Plan(3) = Vec3_DotProduct(@Normale,@BK_NORM)
Plan(4) = Vec3_DotProduct(@Normale,@LF_NORM)
Plan(5) = Vec3_DotProduct(@Normale,@RT_NORM)
Define.VECTOR3 VA,VB,VC,VD,TRI_A,TRI_B,TRI_C
Define.VECTOR2 pA,pB,pC,pD,TA,TB,TC
Select Norme
Case Plan(0): FACE = #FACE_DN
;Plan
VECTOR3_(VA,Min\x,Min\y,Min\z)
VECTOR3_(VB,Max\x,Min\y,Min\z)
VECTOR3_(VC,Max\x,Min\y,Max\z)
VECTOR3_(VD,Min\x,Min\y,Max\z)
;Projection du Triangle 3D sur le plan
TRI_A\x = A\x : TRI_B\x = B\x : TRI_C\x = C\x
TRI_A\Y = Min\y : TRI_B\Y = Min\y : TRI_C\Y = Min\y
TRI_A\z = A\z : TRI_B\z = B\z : TRI_C\z = C\z
; Plan 2D
pA\x=VA\x : pB\x=VB\x : pC\x=VC\x : pD\x=VD\x
pA\y=VA\z : pB\y=VB\z : pC\y=VC\z : pD\y=VD\z
;Triangle 2D
TA\x = A\x : TB\x = B\x : TC\x = C\x
TA\y = A\z : TB\y = B\z : TC\y = C\z
Case Plan(1): FACE = #FACE_UP
VECTOR3_(VA,Min\x,Max\y,Min\z)
VECTOR3_(VB,Max\x,Max\y,Min\z)
VECTOR3_(VC,Max\x,Max\y,Max\z)
VECTOR3_(VD,Min\x,Max\y,Max\z)
TRI_A\x = A\x : TRI_B\x = B\x : TRI_C\x = C\x
TRI_A\Y = Max\y : TRI_B\Y = Max\y : TRI_C\Y = Max\y
TRI_A\z = A\z : TRI_B\z = B\z : TRI_C\z = C\z
pA\x=VA\x : pB\x=VB\x : pC\x=VC\x : pD\x=VD\x
pA\y=VA\z : pB\y=VB\z : pC\y=VC\z : pD\y=VD\z
TA\x = A\x : TB\x = B\x : TC\x = C\x
TA\y = A\z : TB\y = B\z : TC\y = C\z
Case Plan(2): FACE = #FACE_FR
VECTOR3_(VA,Min\x,Min\y,Max\z)
VECTOR3_(VB,Max\x,Min\y,Max\z)
VECTOR3_(VC,Max\x,Max\y,Max\z)
VECTOR3_(VD,Min\x,Max\y,Max\z)
TRI_A\x = A\x : TRI_B\x = B\x : TRI_C\x = C\x
TRI_A\Y = A\y : TRI_B\Y = B\y : TRI_C\Y = C\y
TRI_A\z = Max\z : TRI_B\z = Max\z : TRI_C\z = Max\z
Case Plan(3): FACE = #FACE_BK
VECTOR3_(VA,Min\x,Min\y,Min\z)
VECTOR3_(VB,Max\x,Min\y,Min\z)
VECTOR3_(VC,Max\x,Max\y,Min\z)
VECTOR3_(VD,Min\x,Max\y,Min\z)
TRI_A\x = A\x : TRI_B\x = B\x : TRI_C\x = C\x
TRI_A\Y = A\y : TRI_B\Y = B\y : TRI_C\Y = C\y
TRI_A\z = Min\z : TRI_B\z = Min\z : TRI_C\z = Min\z
Case Plan(4): FACE = #FACE_LF
VECTOR3_(VA,Min\x,Min\y,Min\z)
VECTOR3_(VB,Min\x,Min\y,Max\z)
VECTOR3_(VC,Min\x,Max\y,Max\z)
VECTOR3_(VD,Min\x,Max\y,Min\z)
TRI_A\x = Min\x : TRI_B\x = Min\x : TRI_C\x = Min\x
TRI_A\Y = A\y : TRI_B\Y = B\y : TRI_C\Y = C\y
TRI_A\z = B\z : TRI_B\z = B\z : TRI_C\z = C\z
Case Plan(5): FACE = #FACE_RT
VECTOR3_(VA,Max\x,Min\y,Min\z)
VECTOR3_(VB,Max\x,Min\y,Max\z)
VECTOR3_(VC,Max\x,Max\y,Max\z)
VECTOR3_(VD,Max\x,Max\y,Min\z)
TRI_A\x = Max\x : TRI_B\x = Max\x : TRI_C\x = Max\x
TRI_A\Y = A\y : TRI_B\Y = B\y : TRI_C\Y = C\y
TRI_A\z = B\z : TRI_B\z = B\z : TRI_C\z = C\z
EndSelect
; On a le plan de projection ( face de la boite englobante )
; on a la projection du triangle sur le plan
; on peut créer une texture
TextSize=512
CreateImage(0,TextSize,TextSize)
Diffx.d = 0-pA\x
Diffy.d = 0-pA\y
Width.d = pC\x - pA\x
Height.d = pC\y - pA\y
StartDrawing(ImageOutput(0))
PixX_A.i = (TA\x+DiffX) * TextSize / Width
PixY_A.i = (TA\y+DiffY) * TextSize / Height
PixX_B.i = (TB\x+DiffX) * TextSize / Width
PixY_B.i = (TB\y+DiffY) * TextSize / Height
PixX_C.i = (TC\x+DiffX) * TextSize / Width
PixY_C.i = (TC\y+DiffY) * TextSize / Height
Ua_.d = PixX_A / TextSize
Va_.d = PixY_A / TextSize
Ub_.d = PixX_B / TextSize
Vb_.d = PixY_B / TextSize
Uc_.d = PixX_C / TextSize
Vc_.d = PixY_C / TextSize
Box(0,0,TextSize,TextSize,$0000FF)
LineXY(PixX_A,PixY_A,PixX_B,PixY_B,$000000)
LineXY(PixX_B,PixY_B,PixX_C,PixY_C,$000000)
LineXY(PixX_A,PixY_A,PixX_C,PixY_C,$000000)
mx=(PixX_A+PixX_B+PixX_C)/3
my=(PixY_A+PixY_B+PixY_C)/3
LineXY(mx,my,PixX_A,PixY_A,$000000)
LineXY(mx,my,PixX_B,PixY_B,$000000)
LineXY(mx,my,PixX_C,PixY_C,$000000)
StopDrawing()
SaveImage(0,"Test.bmp")
Next
*material.IMaterial = iNodeMaterial.l(*Triangle)
*tex.ITexture = iLoadTexture( "Test.bmp")
iTextureMaterial(*material, 0, *tex)
;---------------------------
; create a camera
Global *cam.ICamera = iCreateCamera()
iPositionNode(*cam, 1,0,-10)
; ---------------------------------------
; main loop
; ---------------------------------------
Repeat
; move camera with dir key and mouse (left click)
If iGetKeyDown(#KEY_ARROW_UP)
iMoveNode(*cam, 0,0,0.5)
EndIf
If iGetKeyDown(#KEY_ARROW_DOWN)
iMoveNode(*cam, 0,0,-0.5)
EndIf
; If iGetMouseEvent(#MOUSE_BUTTON_LEFT)
; If flagXDown=0
; omx = iGetMouseX()
; omy = iGetMouseY()
; flagXDown=11
; Else
; moy = iGetMouseY()-omy
; angley=(moy/10.0)
; omy= iGetMouseY()
; mox = iGetMouseX()-omx
; anglex=(mox/10.0)
; omx= iGetMouseX()
; iTurnNode(*cam, angley, anglex,0)
; EndIf
; Else
; flagXDown=0
; EndIf
If iGetMouseEvent(#MOUSE_BUTTON_LEFT)
iTurnNode(*cam, iGetDeltaMouseY()*0.5, iGetDeltaMouseX()*0.5,0)
EndIf
; if Escape Key, exit
If iGetKeyDown(#KEY_ESCAPE)
Quit=1
EndIf
; ---------------
; Render
; ---------------
iBeginScene(0,0,0)
iDrawScene()
For z = -25 To 25
For x = -25 To 25
iDrawLine3D(x,-0.01,z,x+1,0,z,$505050)
iDrawLine3D(x,-0.01,z,x,0,z+1,$505050)
Next
Next
; Face au sol
iDrawLine3D(Min\x,Min\y,Min\z,Max\x,Min\y,Min\z,$FFFFFF)
iDrawLine3D(Min\x,Min\y,Max\z,Max\x,Min\y,Max\z,$FFFFFF)
iDrawLine3D(Min\x,Min\y,Min\z,Min\x,Min\y,Max\z,$FFFFFF)
iDrawLine3D(Max\x,Min\y,Min\z,Max\x,Min\y,Max\z,$FFFFFF)
;Face du haut
iDrawLine3D(Min\x,Max\y,Min\z,Max\x,Max\y,Min\z,$FFFFFF)
iDrawLine3D(Min\x,Max\y,Max\z,Max\x,Max\y,Max\z,$FFFFFF)
iDrawLine3D(Min\x,Max\y,Min\z,Min\x,Max\y,Max\z,$FFFFFF)
iDrawLine3D(Max\x,Max\y,Min\z,Max\x,Max\y,Max\z,$FFFFFF)
; Lignes de cotées
iDrawLine3D(Min\x,Min\y,Min\z,Min\x,Max\y,Min\z,$FFFFFF)
iDrawLine3D(Max\x,Min\y,Min\z,Max\x,Max\y,Min\z,$FFFFFF)
iDrawLine3D(Min\x,Min\y,Max\z,Min\x,Max\y,Max\z,$FFFFFF)
iDrawLine3D(Max\x,Min\y,Max\z,Max\x,Max\y,Max\z,$FFFFFF)
;Normale du triangle
iDrawLine3D(MidPoint\x,MidPoint\y,MidPoint\z,MidPoint\x+Normale\x*2,MidPoint\y+Normale\y*2,MidPoint\z+Normale\z*2,$00FF00)
;plan choisi pour la projection
iDrawLine3D(VA\x,VA\y,VA\z,VB\x,VB\y,VB\z,$FF0000)
iDrawLine3D(VB\x,VB\y,VB\z,VC\x,VC\y,VC\z,$FF0000)
iDrawLine3D(VC\x,VC\y,VC\z,VD\x,VD\y,VD\z,$FF0000)
iDrawLine3D(VD\x,VD\y,VD\z,VA\x,VA\y,VA\z,$FF0000)
;Triangle projeté
iDrawLine3D(TRI_A\x,TRI_A\y,TRI_A\z,TRI_B\x,TRI_B\y,TRI_B\z,$FF0000)
iDrawLine3D(TRI_B\x,TRI_B\y,TRI_B\z,TRI_C\x,TRI_C\y,TRI_C\z,$FF0000)
iDrawLine3D(TRI_C\x,TRI_C\y,TRI_C\z,TRI_A\x,TRI_A\y,TRI_A\z,$FF0000)
iEndScene()
Until Quit=1
; end
iFreeEngine()