3D Collision de triangle
Publié : dim. 25/juil./2004 16:15
Bonjour,
J'ai fait une collision de triangle pour vous. Elle n'est pas commentée, mais vous pouvez l'employer par l'intermédiaire des procédures et des structures.
Mon engine obtiendra la collision peut-être.
[EDIT in English]
I have forgotten the OGLSetCamera Procedure, so now it works
J'ai fait une collision de triangle pour vous. Elle n'est pas commentée, mais vous pouvez l'employer par l'intermédiaire des procédures et des structures.
Code : Tout sélectionner
IncludeFile "C:\Programme\PureBASIC\Examples\Sources - Advanced\OpenGL Cube\OpenGL.pbi"
Global PI.f
PI.f = ATan(1)*4
#WindowWidth = 500
#WindowHeight = 400
#WindowFlags = #PB_Window_TitleBar | #PB_Window_MaximizeGadget | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered
Version = 1
Procedure MyWindowCallback(WindowID, Message, wParam, lParam)
Result = #PB_ProcessPureBasicEvents
If Message = #WM_SIZE
glViewport_(0, 0, WindowWidth(), WindowHeight())
Result = 1
EndIf
ProcedureReturn Result
EndProcedure
Structure Point3D
X.f
Y.f
Z.f
EndStructure
Dim Vec.Point3D(2)
Dim Line3D.Point3D(1)
Procedure.f Magnitude(X.f, Y.f, Z.f)
ProcedureReturn Sqr(X*X + Y*Y + Z*Z)
EndProcedure
Procedure OGLSetCamera(FOV.f, X.f, Y.f, Z.f, AngleX.f, AngleY.f, AngleZ.f, Near.f, Far.f)
If AngleY <= 0
AngleY + 360
ElseIf AngleY > 360
AngleY - 360
EndIf
If AngleX <= 0
AngleX + 360
ElseIf AngleX > 360
AngleX - 360
EndIf
If AngleZ <= 0
AngleZ + 360
ElseIf AngleZ > 360
AngleZ - 360
EndIf
glMatrixMode_(5889)
glLoadIdentity_()
gluPerspective__(FOV, WindowWidth()/WindowHeight(), Near.f, Far.f)
glRotatef_(AngleX, 1.0, 0.0, 0.0)
glRotatef_(AngleY, 0.0, 1.0, 0.0)
glRotatef_(AngleZ, 0.0, 0.0, 1.0)
glTranslatef_(X, Y, Z)
glMatrixMode_(5888)
EndProcedure
Procedure.l Normal(*Pos1.Point3D, *Pos2.Point3D, *Pos3.Point3D, *vNormal.Point3D)
vVector1.Point3D
vVector1\X = *Pos1\X - *Pos2\X
vVector1\Y = *Pos1\Y - *Pos2\Y
vVector1\Z = *Pos1\Z - *Pos2\Z
vVector2.Point3D
vVector2\X = *Pos1\X - *Pos3\X
vVector2\Y = *Pos1\Y - *Pos3\Y
vVector2\Z = *Pos1\Z - *Pos3\Z
*vNormal\X = ((vVector1\Y * vVector2\Z) - (vVector1\Z * vVector2\Y))
*vNormal\Y = ((vVector1\Z * vVector2\X) - (vVector1\X * vVector2\Z))
*vNormal\Z = ((vVector1\X * vVector2\Y) - (vVector1\Y * vVector2\X))
Magnitude.f = Magnitude(*vNormal\X, *vNormal\Y, *vNormal\Z)
*vNormal\X / Magnitude
*vNormal\Y / Magnitude
*vNormal\Z / Magnitude
EndProcedure
Procedure.f PlaneDistance(*vNormal.Point3D, *Point.Point3D)
distance.f = 0
distance = - ((*vNormal\X * *Point\X) + (*vNormal\Y * *Point\Y) + (*vNormal\Z * *Point\Z))
ProcedureReturn distance.f
EndProcedure
Procedure IntersectedPlane(*LPos1.Point3D, *LPos2.Point3D, *TPos1.Point3D, *TPos2.Point3D, *TPos3.Point3D, *vNormal.Point3D)
distance1.f=0
distance2.f=0
originDistance.f = PlaneDistance(*vNormal.Point3D, *TPos1.Point3D)
distance1 = ((*vNormal\X * *LPos1\X) + (*vNormal\Y * *LPos1\Y) + (*vNormal\Z * *LPos1\Z)) + originDistance
distance2 = ((*vNormal\X * *LPos2\X) + (*vNormal\Y * *LPos2\Y) + (*vNormal\Z * *LPos2\Z)) + originDistance
If distance1 * distance2 >= 0
ProcedureReturn 0
Else
ProcedureReturn 1
EndIf
EndProcedure
Procedure.f Dot(*vVector1.Point3D, *vVector2.Point3D)
ProcedureReturn ((*vVector1\x * *vVector2\x) + (*vVector1\y * *vVector2\y) + (*vVector1\z * *vVector2\z))
EndProcedure
Procedure Isnan(Num.f)
If StrF(Num, 6) = "-1.#IND00"
ProcedureReturn 1
EndIf
EndProcedure
Procedure.f AngleBetweenVectors(*Vector1.Point3D, *Vector2.Point3D)
dotProduct.f = Dot(*Vector1, *Vector2)
vectorsMagnitude.f = Magnitude(*Vector1\X, *Vector1\Y, *Vector1\Z) * Magnitude(*Vector2\X, *Vector2\Y, *Vector2\Z)
angle.f = ACos(dotProduct / vectorsMagnitude)
If Isnan(angle.f)
ProcedureReturn 0
Else
ProcedureReturn angle
EndIf
EndProcedure
Procedure InsidePolygon(*vIntersection.Point3D, *TPos1.Point3D, *TPos2.Point3D, *TPos3.Point3D)
vA.Point3D
vB.Point3D
Angle.f = 0.0
MATCH_FACTOR.f = 0.9999
vA\X = *TPos1\X - *vIntersection\X
vA\Y = *TPos1\Y - *vIntersection\Y
vA\Z = *TPos1\Z - *vIntersection\Z
vB\X = *TPos2\X - *vIntersection\X
vB\Y = *TPos2\Y - *vIntersection\Y
vB\Z = *TPos2\Z - *vIntersection\Z
Angle + AngleBetweenVectors(@vA, @vB)
vA\X = *TPos2\X - *vIntersection\X
vA\Y = *TPos2\Y - *vIntersection\Y
vA\Z = *TPos2\Z - *vIntersection\Z
vB\X = *TPos3\X - *vIntersection\X
vB\Y = *TPos3\Y - *vIntersection\Y
vB\Z = *TPos3\Z - *vIntersection\Z
Angle + AngleBetweenVectors(@vA, @vB)
vA\X = *TPos3\X - *vIntersection\X
vA\Y = *TPos3\Y - *vIntersection\Y
vA\Z = *TPos3\Z - *vIntersection\Z
vB\X = *TPos1\X - *vIntersection\X
vB\Y = *TPos1\Y - *vIntersection\Y
vB\Z = *TPos1\Z - *vIntersection\Z
Angle + AngleBetweenVectors(@vA, @vB)
If Angle >= (MATCH_FACTOR * (2.0 * PI))
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure IntersectionPoint(*vNormal.Point3D, *LPos1.Point3D, *LPos2.Point3D, distance.f)
vPoint.Point3D
vLineDir.Point3D
Numerator.f = 0.0
Denominator.f = 0.0
dist.f = 0.0
vLineDir\X = *LPos2\X - *LPos1\X
vLineDir\Y = *LPos2\Y - *LPos1\Y
vLineDir\Z = *LPos2\Z - *LPos1\Z
Mag.f = Magnitude(vLineDir\X, vLineDir\Y, vLineDir\Z)
vLineDir\X / Mag
vLineDir\Y / Mag
vLineDir\Z / Mag
Numerator = - (*vNormal\X * *LPos1\X + *vNormal\Y * *LPos1\Y + *vNormal\Z * *LPos1\Z + distance)
Denominator = Dot(*vNormal, @vLineDir)
If Denominator = 0.0
ProcedureReturn *LPos1
EndIf
dist = Numerator / Denominator
vPoint\X = (*LPos1\X + (vLineDir\X * dist))
vPoint\Y = (*LPos1\Y + (vLineDir\y * dist))
vPoint\Z = (*LPos1\Z + (vLineDir\z * dist))
ProcedureReturn @vPoint
EndProcedure
Procedure IntersectedPolygon(*TPos1.Point3D, *TPos2.Point3D, *TPos3.Point3D, *LPos1.Point3D, *LPos2.Point3D, *vNormal.Point3D)
originDistance.f = PlaneDistance(*vNormal.Point3D, *TPos1.Point3D)
If IntersectedPlane(*LPos1.Point3D, *LPos2.Point3D, *TPos1.Point3D, *TPos2.Point3D, *TPos3.Point3D, *vNormal.Point3D) = 0
ProcedureReturn 0
EndIf
CopyMemory(IntersectionPoint(*vNormal.Point3D, *LPos1.Point3D, *LPos2.Point3D, originDistance), @vIntersection.Point3D, SizeOf(Point3D))
If InsidePolygon(@vIntersection, *TPos1.Point3D, *TPos2.Point3D, *TPos3.Point3D) = 1
ProcedureReturn 1
EndIf
EndProcedure
If OpenWindow(0, 0, 0, #WindowWidth, #WindowHeight, #WindowFlags, "Trianglecollision by DarkDragon")
SetWindowCallback(@MyWindowCallback())
hWnd = WindowID(0)
pfd.PIXELFORMATDESCRIPTOR ;OpenGL starten
hDC = GetDC_(hWnd)
pfd\nSize = SizeOf(PIXELFORMATDESCRIPTOR)
pfd\nVersion = 1
pfd\dwFlags = #PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER | #PFD_DRAW_TO_WINDOW
pfd\iLayerType = #PFD_MAIN_PLANE
pfd\iPixelType = #PFD_TYPE_RGBA
pfd\cColorBits = 24
pfd\cDepthBits = 32
pixformat = ChoosePixelFormat_(hDC, pfd)
SetPixelFormat_(hDC, pixformat, pfd)
hrc = wglCreateContext_(hDC)
wglMakeCurrent_(hDC, hrc)
SwapBuffers_(hDC)
glEnable_(#GL_DEPTH_TEST)
Vec(0)\X = -0.225
Vec(0)\Y = 0.5
Vec(0)\Z = 0.0
Vec(1)\X = -0.225
Vec(1)\Y = -0.5
Vec(1)\Z = 0.5
Vec(2)\X = -0.225
Vec(2)\Y = -0.5
Vec(2)\Z = -0.5
Line3D(0)\X = -0.5
Line3D(1)\X = 0.5
Line3D(1)\Z = 0.5
vNormal.Point3D
vNormal\X = 1.0
vIntersection.Point3D
vIntersection\X = -0.225
Repeat
Collision = IntersectedPolygon(@Vec(0), @Vec(1), @Vec(2), @Line3D(0), @Line3D(1), @vNormal.Point3D)
OGLSetCamera(45.0, 0.0, -0.125, -2.0, 1.0, 0.0, 0.0, 0.1, 50.0)
glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
glLoadIdentity_()
glBegin_(#GL_LINES)
If Collision = 0
glColor3f_(0.0, 1.0, 0.0)
Else
glColor3f_(1.0, 1.0, 0.0)
EndIf
glVertex3f_(Line3D(0)\X, Line3D(0)\Y, Line3D(0)\Z)
glVertex3f_(Line3D(1)\X, Line3D(1)\Y, Line3D(1)\Z)
glEnd_()
glLoadIdentity_()
glBegin_(#GL_TRIANGLES)
glNormal3f_(vNormal\X, vNormal\Y, vNormal\Z)
glColor4f_(0.0, 0.0, 1.0, 1.0)
glVertex3f_(Vec(0)\X, Vec(0)\Y, Vec(0)\Z)
glColor4f_(1.0, 0.0, 0.0, 1.0)
glVertex3f_(Vec(1)\X, Vec(1)\Y, Vec(1)\Z)
glColor4f_(1.0, 1.0, 0.0, 1.0)
glVertex3f_(Vec(2)\X, Vec(2)\Y, Vec(2)\Z)
glEnd_()
SwapBuffers_(hDC)
Event = WindowEvent()
If Event = #WM_KEYDOWN
Select EventwParam()
Case #VK_PRIOR
Vec(0)\Y + 0.05
Vec(1)\Y + 0.05
Vec(2)\Y + 0.05
Case #VK_NEXT
Vec(0)\Y - 0.05
Vec(1)\Y - 0.05
Vec(2)\Y - 0.05
Case #VK_DOWN
Vec(0)\Z + 0.05
Vec(1)\Z + 0.05
Vec(2)\Z + 0.05
Case #VK_UP
Vec(0)\Z - 0.05
Vec(1)\Z - 0.05
Vec(2)\Z - 0.05
Case #VK_LEFT
Vec(0)\X - 0.05
Vec(1)\X - 0.05
Vec(2)\X - 0.05
Case #VK_RIGHT
Vec(0)\X + 0.05
Vec(1)\X + 0.05
Vec(2)\X + 0.05
EndSelect
EndIf
Delay(5)
Until Event = #PB_Event_CloseWindow
End
EndIf
[EDIT in English]
I have forgotten the OGLSetCamera Procedure, so now it works
