PDA

View Full Version : ColDet 3D integration with TBGL ?



Artem
03-09-2012, 16:57
Hello everybody!

I'm novice in programming (gamedev) and realy like TBGL module. I working on one interesting mini game and need some help. Is there a chance to integrate a Coldet3D lib with TBGL module? I think it would be great to see advanced 3d collision system in TBGL. I found sources of Blitz3D wrapper with examples, 7933.

Petr Schreiber
03-09-2012, 19:51
Hello Artem,

for license issues I would hesitate to integrate any thirdparty software directly to TBGL.

But!

As entity system in TBGL allows to read/write object transformation matrices, it should be possible to make it cooperate.
In the past I did something similar with ODE (Open Dynamics Engine), it worked, but sadly I don't like the ODE as such.

I will check out the ColDet3D during next week and let you know (I would jump on it right now, but I have crunch time at work currently).


Petr

Artem
04-09-2012, 20:11
Hello Artem,

for license issues I would hesitate to integrate any thirdparty software directly to TBGL.

But!

As entity system in TBGL allows to read/write object transformation matrices, it should be possible to make it cooperate.
In the past I did something similar with ODE (Open Dynamics Engine), it worked, but sadly I don't like the ODE as such.

I will check out the ColDet3D during next week and let you know (I would jump on it right now, but I have crunch time at work currently).


Petr

It would be very powerful feature for Gamedev with ThinBasic. Waiting impatiently news.

Petr Schreiber
04-09-2012, 21:37
In the meantime, you can have a look at the physics examples in TBGL Bonus Pack (http://www.thinbasic.com/index.php?option=com_jdownloads&Itemid=95&task=view.download&cid=6). They are located in directory named Physics.


Petr

Artem
08-09-2012, 12:57
In the meantime, you can have a look at the physics examples in TBGL Bonus Pack (http://www.thinbasic.com/index.php?option=com_jdownloads&Itemid=95&task=view.download&cid=6). They are located in directory named Physics.
Petr

I saw examples with ODE, but where's nothing samples with collisions with static geometry and raycasting. Thanks for info I will deal with ode.

Petr Schreiber
11-09-2012, 18:52
Hi Artem,

the step #1 to get it working with thinBASIC is to convert the declarations hidden in file coldets.decls to thinBasic include file. This will allow to touch the functions in coldet_wrap.dll.

I created conversion script:


'
' Program to convert BlitzMax DECLS file to tBasicI include
'

Uses "UI", "File", "Console"

Function TBMain()

' -- Ask user for file
String srcFile = Dialog_OpenFile(%HWND_DESKTOP, "Please choose DECLS file", APP_SourcePath, "DECLS Files (*.Decls)|*.Decls", "Decls", %OFN_FILEMUSTEXIST Or %OFN_HIDEREADONLY Or %OFN_ENABLESIZING)

If Len(srcFile) = 0 Then
Exit Function
End If

' -- Evaluate automagically output filename
String dstFile = FILE_PathSplit(srcFile, %PATH_ROOTPATHFILE) + ".tBasicI"

Print "Converting: " + srcFile + "..."
Convert_Decls2TBasicI(srcFile, dstFile)
PrintL "OK"

PrintL "Saved as: " + dstFile

PrintL

PrintL "Press any key to continue..."
WaitKey

End Function

Function Convert_Decls2TBasicI(srcFile As String, dstFile As String)

String sLineSrc()
Long nLines = Parse(File srcFile, sLineSrc, $CRLF)

String sLineDst(nLines)

Long libraryDetected = FALSE
String libraryName
String sLineSingle

String sFuncName, sFuncType, sFuncParams, sFuncAlias
String sFuncParamSrc()
Long nFuncParam
String sFuncParamDst()


Long i, j

' -- Scanning the lines
For i = 1 To nLines

' -- Preprocess the source line a bit
sLineSingle = Trim$(sLineSrc(i))

' -- Skip empty lines
If Len(sLineSingle) = 0 Then
Iterate For
End If

' -- Did we found the .lib tag yet? It should precede the rest...
If libraryDetected = FALSE Then

If StartsWith(sLineSingle, ".lib ") Then
' -- Library name is stored between the quotes, let's grab it!
libraryName = Grab$(sLineSingle, $DQ, $DQ)

sLineDst(i) = "' -- This file is include for " + libraryName

libraryDetected = TRUE
End If

' -- We got it, let's find the declarations
Else

' -- Is it just comment? Convert it to TB style!
If StartsWith(sLineSingle, ";") Then
sLineDst(i) = "' -- " + LTrim$(sLineSingle, ";")

' -- Is it declare?
ElseIf InStr(sLineSingle, "(") > 0 And InStr(sLineSingle, ")") > 0 Then

' -- Extract function name
sFuncName = Trim$(Extract$(sLineSingle, "("))

sFuncType = GetDataTypeForToken(sFuncName)

' -- Extract function parameters
sFuncParams = Grab$(sLineSingle, "(", ")")
nFuncParam = Parse(sFuncParams, sFuncParamSrc, ",")

ReDim sFuncParamDst(nFuncParam)
' -- Convert them to ThinBASIC form
For j = 1 To nFuncParam

sFuncParamDst(j) = GetDeclareForToken(sFuncParamSrc(j))

Next

' -- Detect alias
sFuncAlias = Trim$(Remain$(sLineSingle, ":"))
If Len(sFuncAlias) = 0 Then
sFuncAlias = sFuncName
End If

' -- Here we recreate the declaration in THINBASIC form
sLineDst(i) = "DECLARE " + IIf$(sFuncType = "NONE", "SUB ", "FUNCTION ") + sFuncName + " LIB " + $DQ + libraryName + $DQ + " ALIAS " + sFuncAlias + " ("
' -- Append parameters, one by one
For j = 1 To nFuncParam

sLineDst(i) += sFuncParamDst(j) + ", "

Next

' -- The last parameter is ended with redundant ", ", let's trim it
sLineDst(i) = RTrim$(sLineDst(i), ", ")

' -- If it is SUB, no return type, otherwise append type
sLineDst(i) += ")" + IIf$(sFuncType = "NONE", "", " AS " + sFuncType)

End If

End If
Next

' -- Save the converted file
FILE_Save( dstFile, Join$(sLineDst, $CRLF))

End Function

' -- Returns the token data type, AND removes from it the data type info
Function GetDataTypeForToken( ByRef sToken As String) As String

sToken = Trim$(sToken)

' -- Detect type specifier from token
String sDataTypeChar = RIGHT$(sToken, 1)

' -- Strip the type specifier from token
sToken = RTrim$(sToken, sDataTypeChar)

String sDataTypeTB

' -- Convert it to TB
Select Case sDataTypeChar
Case ""
sDataTypeTB = "NONE"

Case "%"
sDataTypeTB = "LONG"

Case "#"
sDataTypeTB = "SINGLE"

Case "!"
sDataTypeTB = "DOUBLE"

Case "$"
sDataTypeTB = "STRING"

Case "*"
sDataTypeTB = "DWORD"

Case Else
sDataTypeTB = "UNKNOWN"

End Select

Return sDataTypeTB

End Function

' -- Creates BYVAL <name> AS <type> string from token
Function GetDeclareForToken( sToken As String ) As String

String sType = GetDataTypeForToken(sToken)

Return "BYVAL " + sToken + " AS " + sType

End Function


... which converts this Blitz stuff:


.lib "coldet_wrap.dll"

;wrapper functions
coldet_make_model%(trinum%,static%):"_coldet_make_model@8"
coldet_add_model%(model%,bank*,tris%):"_coldet_addmod@12"
coldet_finalize%(model%):"_coldet_finalize@4"
coldet_set_matrix%(model%,bank*):"_coldet_set_matrix@8"
coldet_addtri%(model%,vx1#,vy1#,vz1#,vx2#,vy2#,vz2#,vx3#,vy3#,vz3#):"_coldet_addTriangle@40"
coldet_free_model%(model%):"_coldet_free@4"

coldet_collision%(model1%,model2%):"_colldet_collision@8"
coldet_getcollision_point%(model%,bank*,global%):"_get_collision_point@12"
coldet_getcolliding_verts%(model%,bank1*,bank2*):"_getcolliding_tris1@12"
coldet_getcolliding_tris%(model%,bank1*,bank2*):"_getcolliding_tris2@12"
coldet_ray_collision1%(model%,origin*,direction*,closest%,segmin#,segmax#):"_coldet_rayCollision1@24"
coldet_ray_collision2%(model%,origin*,direction*):"_coldet_rayCollision2@12"
coldet_sphere_collision%(model%,bank*,radius#):"_coldet_sphereCollision@12"



;Utility functions
SphereRayCollision%(center*,radius#,origin*,direction*,point*):"_coldet_SphereRayCollision@20"
SphereSphereCollision%(center1*,radius1#,center2*,radius2#,point*):"_coldet_SphereSphereCollision@20"


... directly to thinBasic declares:


' -- This file is include for coldet_wrap.dll

' -- wrapper functions
Declare Function coldet_make_model Lib "coldet_wrap.dll" Alias "_coldet_make_model@8" (ByVal trinum As Long, ByVal Static As Long) As Long
DECLARE FUNCTION coldet_add_model LIB "coldet_wrap.dll" ALIAS "_coldet_addmod@12" (BYVAL model AS LONG, BYVAL bank AS DWORD, BYVAL tris AS LONG) AS LONG
DECLARE FUNCTION coldet_finalize LIB "coldet_wrap.dll" ALIAS "_coldet_finalize@4" (BYVAL model AS LONG) AS LONG
DECLARE FUNCTION coldet_set_matrix LIB "coldet_wrap.dll" ALIAS "_coldet_set_matrix@8" (BYVAL model AS LONG, BYVAL bank AS DWORD) AS LONG
DECLARE FUNCTION coldet_addtri LIB "coldet_wrap.dll" ALIAS "_coldet_addTriangle@40" (BYVAL model AS LONG, BYVAL vx1 AS SINGLE, BYVAL vy1 AS SINGLE, BYVAL vz1 AS SINGLE, BYVAL vx2 AS SINGLE, BYVAL vy2 AS SINGLE, BYVAL vz2 AS SINGLE, BYVAL vx3 AS SINGLE, BYVAL vy3 AS SINGLE, BYVAL vz3 AS SINGLE) AS LONG
DECLARE FUNCTION coldet_free_model LIB "coldet_wrap.dll" ALIAS "_coldet_free@4" (BYVAL model AS LONG) AS LONG

DECLARE FUNCTION coldet_collision LIB "coldet_wrap.dll" ALIAS "_colldet_collision@8" (BYVAL model1 AS LONG, BYVAL model2 AS LONG)AS LONG
DECLARE FUNCTION coldet_getcollision_point LIB "coldet_wrap.dll" ALIAS "_get_collision_point@12" (BYVAL model AS LONG, BYVAL bank AS DWORD, BYVAL global AS LONG) AS LONG
DECLARE FUNCTION coldet_getcolliding_verts LIB "coldet_wrap.dll" ALIAS "_getcolliding_tris1@12" (BYVAL model AS LONG, BYVAL bank1 AS DWORD, BYVAL bank2 AS DWORD) AS LONG
DECLARE FUNCTION coldet_getcolliding_tris LIB "coldet_wrap.dll" ALIAS "_getcolliding_tris2@12" (BYVAL model AS LONG, BYVAL bank1 AS DWORD, BYVAL bank2 AS DWORD) AS LONG
DECLARE FUNCTION coldet_ray_collision1 LIB "coldet_wrap.dll" ALIAS "_coldet_rayCollision1@24" (BYVAL model AS LONG, BYVAL origin AS DWORD, BYVAL direction AS DWORD, BYVAL closest AS LONG, BYVAL segmin AS SINGLE, BYVAL segmax AS SINGLE) AS LONG
DECLARE FUNCTION coldet_ray_collision2 LIB "coldet_wrap.dll" ALIAS "_coldet_rayCollision2@12" (BYVAL model AS LONG, BYVAL origin AS DWORD, BYVAL direction AS DWORD) AS LONG
DECLARE FUNCTION coldet_sphere_collision LIB "coldet_wrap.dll" ALIAS "_coldet_sphereCollision@12" (BYVAL model AS LONG, BYVAL bank AS DWORD, BYVAL radius AS SINGLE) AS LONG



' -- Utility functions
DECLARE FUNCTION SphereRayCollision LIB "coldet_wrap.dll" ALIAS "_coldet_SphereRayCollision@20" (BYVAL center AS DWORD, BYVAL radius AS SINGLE, BYVAL origin AS DWORD, BYVAL direction AS DWORD, BYVAL point AS DWORD) AS LONG
DECLARE FUNCTION SphereSphereCollision LIB "coldet_wrap.dll" ALIAS "_coldet_SphereSphereCollision@20" (BYVAL center1 AS DWORD, BYVAL radius1 AS SINGLE, BYVAL center2 AS DWORD, BYVAL radius2 AS SINGLE, BYVAL point AS DWORD) AS LONG


Because I am not familiar with Blitz syntax (nor ColDet3D library), I guess the conversion of code samples (in BB files) must be done by somebody more knowledgeable. Do you dare to try? :)


Petr

Artem
12-09-2012, 11:26
Hi Artem,

the step #1 to get it working with thinBASIC is to convert the declarations hidden in file coldets.decls to thinBasic include file. This will allow to touch the functions in coldet_wrap.dll.

I created conversion script:


'
' Program to convert BlitzMax DECLS file to tBasicI include
'

Uses "UI", "File", "Console"

Function TBMain()

' -- Ask user for file
String srcFile = Dialog_OpenFile(%HWND_DESKTOP, "Please choose DECLS file", APP_SourcePath, "DECLS Files (*.Decls)|*.Decls", "Decls", %OFN_FILEMUSTEXIST Or %OFN_HIDEREADONLY Or %OFN_ENABLESIZING)

If Len(srcFile) = 0 Then
Exit Function
End If

' -- Evaluate automagically output filename
String dstFile = FILE_PathSplit(srcFile, %PATH_ROOTPATHFILE) + ".tBasicI"

Print "Converting: " + srcFile + "..."
Convert_Decls2TBasicI(srcFile, dstFile)
PrintL "OK"

PrintL "Saved as: " + dstFile

PrintL

PrintL "Press any key to continue..."
WaitKey

End Function

Function Convert_Decls2TBasicI(srcFile As String, dstFile As String)

String sLineSrc()
Long nLines = Parse(File srcFile, sLineSrc, $CRLF)

String sLineDst(nLines)

Long libraryDetected = FALSE
String libraryName
String sLineSingle

String sFuncName, sFuncType, sFuncParams, sFuncAlias
String sFuncParamSrc()
Long nFuncParam
String sFuncParamDst()


Long i, j

' -- Scanning the lines
For i = 1 To nLines

' -- Preprocess the source line a bit
sLineSingle = Trim$(sLineSrc(i))

' -- Skip empty lines
If Len(sLineSingle) = 0 Then
Iterate For
End If

' -- Did we found the .lib tag yet? It should precede the rest...
If libraryDetected = FALSE Then

If StartsWith(sLineSingle, ".lib ") Then
' -- Library name is stored between the quotes, let's grab it!
libraryName = Grab$(sLineSingle, $DQ, $DQ)

sLineDst(i) = "' -- This file is include for " + libraryName

libraryDetected = TRUE
End If

' -- We got it, let's find the declarations
Else

' -- Is it just comment? Convert it to TB style!
If StartsWith(sLineSingle, ";") Then
sLineDst(i) = "' -- " + LTrim$(sLineSingle, ";")

' -- Is it declare?
ElseIf InStr(sLineSingle, "(") > 0 And InStr(sLineSingle, ")") > 0 Then

' -- Extract function name
sFuncName = Trim$(Extract$(sLineSingle, "("))

sFuncType = GetDataTypeForToken(sFuncName)

' -- Extract function parameters
sFuncParams = Grab$(sLineSingle, "(", ")")
nFuncParam = Parse(sFuncParams, sFuncParamSrc, ",")

ReDim sFuncParamDst(nFuncParam)
' -- Convert them to ThinBASIC form
For j = 1 To nFuncParam

sFuncParamDst(j) = GetDeclareForToken(sFuncParamSrc(j))

Next

' -- Detect alias
sFuncAlias = Trim$(Remain$(sLineSingle, ":"))
If Len(sFuncAlias) = 0 Then
sFuncAlias = sFuncName
End If

' -- Here we recreate the declaration in THINBASIC form
sLineDst(i) = "DECLARE " + IIf$(sFuncType = "NONE", "SUB ", "FUNCTION ") + sFuncName + " LIB " + $DQ + libraryName + $DQ + " ALIAS " + sFuncAlias + " ("
' -- Append parameters, one by one
For j = 1 To nFuncParam

sLineDst(i) += sFuncParamDst(j) + ", "

Next

' -- The last parameter is ended with redundant ", ", let's trim it
sLineDst(i) = RTrim$(sLineDst(i), ", ")

' -- If it is SUB, no return type, otherwise append type
sLineDst(i) += ")" + IIf$(sFuncType = "NONE", "", " AS " + sFuncType)

End If

End If
Next

' -- Save the converted file
FILE_Save( dstFile, Join$(sLineDst, $CRLF))

End Function

' -- Returns the token data type, AND removes from it the data type info
Function GetDataTypeForToken( ByRef sToken As String) As String

sToken = Trim$(sToken)

' -- Detect type specifier from token
String sDataTypeChar = RIGHT$(sToken, 1)

' -- Strip the type specifier from token
sToken = RTrim$(sToken, sDataTypeChar)

String sDataTypeTB

' -- Convert it to TB
Select Case sDataTypeChar
Case ""
sDataTypeTB = "NONE"

Case "%"
sDataTypeTB = "LONG"

Case "#"
sDataTypeTB = "SINGLE"

Case "!"
sDataTypeTB = "DOUBLE"

Case "$"
sDataTypeTB = "STRING"

Case "*"
sDataTypeTB = "DWORD"

Case Else
sDataTypeTB = "UNKNOWN"

End Select

Return sDataTypeTB

End Function

' -- Creates BYVAL <name> AS <type> string from token
Function GetDeclareForToken( sToken As String ) As String

String sType = GetDataTypeForToken(sToken)

Return "BYVAL " + sToken + " AS " + sType

End Function


... which converts this Blitz stuff:


.lib "coldet_wrap.dll"

;wrapper functions
coldet_make_model%(trinum%,static%):"_coldet_make_model@8"
coldet_add_model%(model%,bank*,tris%):"_coldet_addmod@12"
coldet_finalize%(model%):"_coldet_finalize@4"
coldet_set_matrix%(model%,bank*):"_coldet_set_matrix@8"
coldet_addtri%(model%,vx1#,vy1#,vz1#,vx2#,vy2#,vz2#,vx3#,vy3#,vz3#):"_coldet_addTriangle@40"
coldet_free_model%(model%):"_coldet_free@4"

coldet_collision%(model1%,model2%):"_colldet_collision@8"
coldet_getcollision_point%(model%,bank*,global%):"_get_collision_point@12"
coldet_getcolliding_verts%(model%,bank1*,bank2*):"_getcolliding_tris1@12"
coldet_getcolliding_tris%(model%,bank1*,bank2*):"_getcolliding_tris2@12"
coldet_ray_collision1%(model%,origin*,direction*,closest%,segmin#,segmax#):"_coldet_rayCollision1@24"
coldet_ray_collision2%(model%,origin*,direction*):"_coldet_rayCollision2@12"
coldet_sphere_collision%(model%,bank*,radius#):"_coldet_sphereCollision@12"



;Utility functions
SphereRayCollision%(center*,radius#,origin*,direction*,point*):"_coldet_SphereRayCollision@20"
SphereSphereCollision%(center1*,radius1#,center2*,radius2#,point*):"_coldet_SphereSphereCollision@20"


... directly to thinBasic declares:


' -- This file is include for coldet_wrap.dll

' -- wrapper functions
Declare Function coldet_make_model Lib "coldet_wrap.dll" Alias "_coldet_make_model@8" (ByVal trinum As Long, ByVal Static As Long) As Long
DECLARE FUNCTION coldet_add_model LIB "coldet_wrap.dll" ALIAS "_coldet_addmod@12" (BYVAL model AS LONG, BYVAL bank AS DWORD, BYVAL tris AS LONG) AS LONG
DECLARE FUNCTION coldet_finalize LIB "coldet_wrap.dll" ALIAS "_coldet_finalize@4" (BYVAL model AS LONG) AS LONG
DECLARE FUNCTION coldet_set_matrix LIB "coldet_wrap.dll" ALIAS "_coldet_set_matrix@8" (BYVAL model AS LONG, BYVAL bank AS DWORD) AS LONG
DECLARE FUNCTION coldet_addtri LIB "coldet_wrap.dll" ALIAS "_coldet_addTriangle@40" (BYVAL model AS LONG, BYVAL vx1 AS SINGLE, BYVAL vy1 AS SINGLE, BYVAL vz1 AS SINGLE, BYVAL vx2 AS SINGLE, BYVAL vy2 AS SINGLE, BYVAL vz2 AS SINGLE, BYVAL vx3 AS SINGLE, BYVAL vy3 AS SINGLE, BYVAL vz3 AS SINGLE) AS LONG
DECLARE FUNCTION coldet_free_model LIB "coldet_wrap.dll" ALIAS "_coldet_free@4" (BYVAL model AS LONG) AS LONG

DECLARE FUNCTION coldet_collision LIB "coldet_wrap.dll" ALIAS "_colldet_collision@8" (BYVAL model1 AS LONG, BYVAL model2 AS LONG)AS LONG
DECLARE FUNCTION coldet_getcollision_point LIB "coldet_wrap.dll" ALIAS "_get_collision_point@12" (BYVAL model AS LONG, BYVAL bank AS DWORD, BYVAL global AS LONG) AS LONG
DECLARE FUNCTION coldet_getcolliding_verts LIB "coldet_wrap.dll" ALIAS "_getcolliding_tris1@12" (BYVAL model AS LONG, BYVAL bank1 AS DWORD, BYVAL bank2 AS DWORD) AS LONG
DECLARE FUNCTION coldet_getcolliding_tris LIB "coldet_wrap.dll" ALIAS "_getcolliding_tris2@12" (BYVAL model AS LONG, BYVAL bank1 AS DWORD, BYVAL bank2 AS DWORD) AS LONG
DECLARE FUNCTION coldet_ray_collision1 LIB "coldet_wrap.dll" ALIAS "_coldet_rayCollision1@24" (BYVAL model AS LONG, BYVAL origin AS DWORD, BYVAL direction AS DWORD, BYVAL closest AS LONG, BYVAL segmin AS SINGLE, BYVAL segmax AS SINGLE) AS LONG
DECLARE FUNCTION coldet_ray_collision2 LIB "coldet_wrap.dll" ALIAS "_coldet_rayCollision2@12" (BYVAL model AS LONG, BYVAL origin AS DWORD, BYVAL direction AS DWORD) AS LONG
DECLARE FUNCTION coldet_sphere_collision LIB "coldet_wrap.dll" ALIAS "_coldet_sphereCollision@12" (BYVAL model AS LONG, BYVAL bank AS DWORD, BYVAL radius AS SINGLE) AS LONG



' -- Utility functions
DECLARE FUNCTION SphereRayCollision LIB "coldet_wrap.dll" ALIAS "_coldet_SphereRayCollision@20" (BYVAL center AS DWORD, BYVAL radius AS SINGLE, BYVAL origin AS DWORD, BYVAL direction AS DWORD, BYVAL point AS DWORD) AS LONG
DECLARE FUNCTION SphereSphereCollision LIB "coldet_wrap.dll" ALIAS "_coldet_SphereSphereCollision@20" (BYVAL center1 AS DWORD, BYVAL radius1 AS SINGLE, BYVAL center2 AS DWORD, BYVAL radius2 AS SINGLE, BYVAL point AS DWORD) AS LONG


Because I am not familiar with Blitz syntax (nor ColDet3D library), I guess the conversion of code samples (in BB files) must be done by somebody more knowledgeable. Do you dare to try? :)


Petr

I'll try. Thanks for help!!!

Artem
13-09-2012, 23:09
Hello Petr,

I need help with translating coldet.bb source to thinbasic. How i can retrieve information from entities? For example i create a sphere with TBGL_EntityCreateSphere( %sScene, %eSPHERE1 ) and i need info about how many tris containted and about vertexes xyz position of all vertexes.

Petr Schreiber
14-09-2012, 11:34
Hi Artem,

I didn't studied ColDet3D in depth. If it works mainly with meshes, then I would recommend to use mesh geometries in ThinBASIC, instead of Sphere/Box/... prefabs.

ThinBASIC TBGL loads M15 format. It is specific to TBGL, but the good news is that you can create it easily:

Create model in basically any 3D modeller (I recommend Wings3D (http://www.wings3d.com/), it is easy to use and also free)
Export it as OBJ
Convert it to M15 using TBGL OBJ to M15 converter (http://www.thinbasic.com/community/showthread.php?8585-TBGL-OBJ-to-M15-converter-UPDATED-to-v-1-5&highlight=obj2m15)


Then, you can use this model as entity and also access the info on triangles using TBGL_m15GetVertexXYZ and TBGL_m15GetVertexPStop.

Too much information at once I guess :oops:

To get better idea, I prepaired little example package for you. It contains:

original model done in Wings3D
exported model in OBJ format
converted M15 model
example script, which displays the model AND allows to list information about its vertex data (just press F1, it will be printed to console)



Petr