curious about what AGK allows for surfaces (verticescount, trianglescount)

Started by RemiD, February 24, 2018, 23:10:02

Previous topic - Next topic

RemiD

@TomToad>>thanks for the code example, it looks quite complicated to create just a simple 3d triangle. I find it already complex enough to find which vertices indexes to use to create a triangle procedurally so i if we have to also calculate the specific "memory block" to write / read in, well a good way to become insane imo... Unless if somebody writes functions that simplify this process...

Not something i want to try at the moment. (but thanks)

Rick Nasher

@TomToad

Simply: wow!
Bit complicated but it shows that it can be done.

Quote
I'll write out a short tutorial explaining just what each of the fields are for.  Once the header is created, it can be copied to any mesh memblock that uses the same structure.
That be really great. I'm sure a lot of people would benefit from that.


I hope you submitted the example to https://www.appgamekit.com/documentation/Reference/Memblock/CreateObjectFromMeshMemblock.htm

If you didn't yet, then I can do it for you(with your permission) and nominate you for one of these badge thingies they apparently are using for honoring people that contribute to the community, if you care for that of course..


Your other example has been validated and accepted btw, see:
https://www.appgamekit.com/documentation/Reference/Memblock/SetMeshMemblockVertexPosition.htm
So you are now 'immortalized' in the AGK help file. 8)

_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

RemiD

As i said previously, the functions (in Blitz3d) to create a mesh, surface, vertices, triangles, or to get properties from the surface, vertices, triangles, or to set the properties of the surface, vertices, triangles, are probably "shortcuts" to read/write in memory banks, so you could probably code similar functions for AGK, once you understand how it works...

Rick Nasher

I've launched a thread on the AGK forum, might be interesting regarding the opinions about this over there:
https://forum.thegamecreators.com/thread/221755

Apparently it raised some discussions, which- you never know- may lead to new command implementations.
Fingers x-ed.

[EDIT]
See TomToad's excellent tutorial:
https://www.syntaxbomb.com/index.php/topic,4235.0.html
Direct link:
http://www.tomtoad.com/AGK2/Tutorial/ProceduralMesh/ProceduralMeshAGK.html

(BTW: nominated TomToad for a AGK badge)  :)
_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

TomToad

Here is a first attempt at adding mesh helper functions to AGK2. Save this as "mesh.agc"


Type Vertex
x as float
y as float
z as float
nx as float
ny as float
nz as float
u as float
v as float
color as integer
endtype

Type Triangle
v1 as integer
v2 as integer
v3 as integer
endtype

Type Mesh
VertexList as Vertex[]
TriangleList as Triangle[]
endtype

Function AddVertex(m ref as Mesh, x as float, y as float, z as float, nx as float, ny as float, nz as float, u as float, v as float, color as integer)
vert as vertex
vert.x = x
vert.y = y
vert.z = z
vert.nx = nx
vert.ny = ny
vert.nz = nz
vert.u = u
vert.v = v
vert.color = color
m.VertexList.Insert(vert)
endfunction

Function AddTriangle(m ref as Mesh, v1 as integer, v2 as integer, v3 as integer)
t as Triangle
t.v1 = v1
t.v2 = v2
t.v3 = v3
m.TriangleList.Insert(t)
endfunction

Function CreateObjectFromMesh(m ref as mesh)
VertexCount = m.VertexList.Length + 1
IndexCount = (m.TriangleList.Length + 1) * 3
IndexOffset = 72 + VertexCount*36
memblock = CreateMemblock(IndexOffset+IndexCount*4)
SetMemblockInt(memblock,0,VertexCount)
SetMemblockInt(memblock,4,IndexCount)
SetMemblockInt(Memblock,8,4)
SetMemblockInt(memblock,12,36)
SetmemblockInt(memblock,16,72)
SetMemblockInt(memblock,20,IndexOffset)
SetMemblockInt(memblock,24,0x0c000300)
SetMemblockString(Memblock,28,"position")
SetMemblockInt(memblock,40,0x08000300)
SetMemblockString(memblock,44,"normal")
SetMemblockInt(memblock,52,0x04000200)
SetMemblockString(memblock,56,"uv")
SetMemblockInt(memblock,60,0x08010401)
SetMemblockString(memblock,64,"color")

for i = 0 to m.VertexList.Length
SetMemblockFloat(memblock,72+i*36,m.VertexList[i].x)
SetMemblockFloat(memblock,76+i*36,m.VertexList[i].y)
SetMemblockFloat(memblock,80+i*36,m.VertexList[i].z)
SetMemblockFloat(memblock,84+i*36,m.VertexList[i].nx)
SetMemblockFloat(memblock,88+i*36,m.VertexList[i].ny)
SetMemblockFloat(memblock,92+i*36,m.VertexList[i].nz)
SetMemblockFloat(memblock,96+i*36,m.VertexList[i].u)
SetMemblockFloat(memblock,100+i*36,m.VertexList[i].v)
SetMemblockInt(memblock,104+i*36,m.VertexList[i].color)
next

for i = 0 to m.TriangleList.Length
SetMemblockInt(memblock,IndexOffset+i*12,m.TriangleList[i].v1)
SetMemblockInt(memblock,IndexOffset+i*12+4,m.TriangleList[i].v2)
SetMemblockInt(memblock,IndexOffset+i*12+8,m.TriangleList[i].v3)
next
id = CreateObjectFromMeshMemblock(memblock)
DeleteMemblock(memblock)
endfunction id


Example of usage.  For this example to work, copy the file "mesh3-1.jpg" from the "AppGameKit\Samples\3D\3D-FirstPersonExample\media" folder to the project media folder, or save your own texture and change line 78 accordingly.

// Project: Cube
// Created: 2018-03-06

#insert "mesh.agc"
// show all errors
SetErrorMode(2)

// set window properties
SetWindowTitle( "Cube" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts

cube as Mesh

//face 1
AddVertex(Cube,-5,-5,-5,0,0,-1,0,1,0xFFFFFFFF) //0
AddVertex(Cube,-5,5,-5,0,0,-1,0,0,0xFFFFFFFF) //1
AddVertex(Cube,5,5,-5,0,0,-1,1,0,0xFFFFFFFF) //2
AddVertex(Cube,5,-5,-5,0,0,-1,1,1,0xFFFFFFFF) //3

AddTriangle(Cube,0,2,1)
AddTriangle(Cube,0,3,2)

//face 2
AddVertex(Cube,5,5,-5,1,0,0,0,0,0xFF0000FF) //4
AddVertex(Cube,5,5,5,1,0,0,1,0,0xFF0000FF) //5
AddVertex(Cube,5,-5,5,1,0,0,1,1,0xFF0000FF) //6
AddVertex(Cube,5,-5,-5,1,0,0,0,1,0xFF0000FF) //7

AddTriangle(Cube,4,7,5)
AddTriangle(Cube,5,7,6)

//face 3
AddVertex(Cube,5,5,5,0,0,1,0,0,0xFF00FF00) //8
AddVertex(Cube,5,-5,5,0,0,1,0,1,0xFF00FF00) //9
AddVertex(Cube,-5,-5,5,0,0,1,1,1,0xFF00FF00) //10
AddVertex(Cube,-5,5,5,0,0,1,1,0,0xFF00FF00) //11

AddTriangle(Cube,8,9,10)
AddTriangle(Cube,10,11,8)

//face 4
AddVertex(Cube,-5,5,5,-1,0,0,0,0,0xFFFF0000) //12
AddVertex(Cube,-5,5,-5,-1,0,0,1,0,0xFFFF0000) //13
AddVertex(Cube,-5,-5,-5,-1,0,0,1,1,0xFFFF0000) //14
AddVertex(Cube,-5,-5,5,-1,0,0,0,1,0xFFFF0000) //15

AddTriangle(Cube,12,14,13)
AddTriangle(Cube,14,12,15)

//face 5
AddVertex(Cube,-5,5,5,0,1,0,0,0,0xFF00FFFF) //16
AddVertex(Cube,5,5,5,0,1,0,1,0,0xFF00FFFF) //17
AddVertex(Cube,5,5,-5,0,1,0,1,1,0xFF00FFFF) //18
AddVertex(Cube,-5,5,-5,0,1,0,0,1,0xFF00FFFF) //19

AddTriangle(Cube,16,18,17)
AddTriangle(Cube,16,19,18)

//face 6
AddVertex(Cube,5,-5,-5,0,-1,0,1,0,0xFFFFFF00) //20
AddVertex(Cube,-5,-5,-5,0,-1,0,0,0,0xFFFFFF00) //21
AddVertex(Cube,-5,-5,5,0,-1,0,0,1,0xFFFFFF00) //22
AddVertex(Cube,5,-5,5,0,-1,0,1,1,0xFFFFFF00) //23

Addtriangle(Cube,20,21,22)
Addtriangle(Cube,20,22,23)

cubeObject = CreateObjectFromMesh(cube)
image = loadimage("mesh3-1.jpg")
SetObjectImage(cubeObject,image,0)
do
    RotateObjectLocalX(cubeObject,.1)
    RotateObjectLocalY(cubeObject,.2)
    RotateObjectLocalZ(cubeObject,.3)

    Print( ScreenFPS() )
    Sync()
loop

------------------------------------------------
8 rabbits equals 1 rabbyte.

Rick Nasher

Works like a charm.

Time for experiments.. Ehrr.. 00:46 : No-no, need to kick myself and go to bed. Have to get up in 5hrs ;)

_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

Qube

QuoteHere is a first attempt at adding mesh helper functions to AGK2.
Super cool beans, nice one ;D - * shifty sideways looks * have you figured out how to delete bits yet? * continued shifty sideways looks *
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

RemiD

@TomToad>>very good ! thanks :)


I don't use AGK, but i am curious about what it can do.

Can somebody please try to create a surface proceduraly to see if there is a vertices / triangles limit per surface (with Blitz3d, it would be around 32000 vertices / 32000 triangles per surface)

Here is a code example that you can convert :

Graphics3D(640,480,32,2)

SeedRnd(MilliSecs())

Global Camera = CreateCamera()
CameraRange(Camera,0.1,100)
CameraClsColor(Camera,000,000,000)

Mesh = CreateMesh()
Surface = CreateSurface(Mesh)
VerticesCount% = 0
TrianglesCount% = 0

PositionEntity(Camera,0,0,-10,True)

Repeat

Surface = GetSurface(Mesh,1)
VerticesCount = VerticesCount + 1
V0I% = VerticesCount-1
AddVertex( Surface, Rnd(-1.5,+1.5), Rnd(+1,+4), Rnd(-1,+1) )
VerticesCount = VerticesCount + 1
V1I% = VerticesCount-1
AddVertex( Surface, Rnd(+4,+1), Rnd(-1,-4), Rnd(-1,+1) )
VerticesCount = VerticesCount + 1
V2I% = VerticesCount-1
AddVertex( Surface, Rnd(-1,-4), Rnd(-1,-4), Rnd(-1,+1) )

TrianglesCount = TrianglesCount + 1
TI% = TrianglesCount-1
AddTriangle( Surface, V0I, V1I, V2I )

;UpdateNormals(Mesh)

WireFrame(True)

SetBuffer(BackBuffer())
RenderWorld()

Text(0,0,"VerticesCount = "+VerticesCount)
Text(0,10,"TrianglesCount = "+TrianglesCount)

Flip(1)

Until( MAV = True )

End()

RemiD

Quote
(with Blitz3d, it would be around 32000 vertices / 32000 triangles per surface)
i have tested this code on 3 different computers and the limit seems quite random... (with Blitz3d), this arbitrary limit is really really really annoying ! (because of that, if i want to merge many vertices / triangles in one surface, instead i have to create several surfaces, and it is a mess to keep track of what is what...) I hope that AGK does not have the same arbitrary limit...

Naughty Alien

Blitz3D uses unsigned 16-bit vertex buffers, which means 65535 vertices in Blitz3D should be fine as DX7 says , dwVertexCount
The number of vertices in the array. The maximum number of vertices allowed is D3DMAXNUMVERTICES (0xFFFF)
.

..Im sure AGK is well over this ancient limit..ill test tomorrow large mesh and see how it goes..

RemiD

Quote
which means 65535 vertices in Blitz3D should be fine
in theory, maybe, but in practice, no, the MAV happens with less than 32000 triangles (depending on the computer), this is weird (and annoying)

tested on 3 different computers :
MAV when the surface has 54615 vertices and 18205 triangles...

TomToad

If I remember correctly,Blitz3d had a maximum limit of 65535 vertices, but depending on video card memory size and driver capabilities, the actual number could be less. As I understand, this was a DirectX 7 problem and not aB3D problem.
------------------------------------------------
8 rabbits equals 1 rabbyte.

Naughty Alien

Quote from: RemiD on March 07, 2018, 15:57:10
Quote
which means 65535 vertices in Blitz3D should be fine
in theory, maybe, but in practice, no, the MAV happens with less than 32000 triangles (depending on the computer), this is weird (and annoying)

tested on 3 different computers :
MAV when the surface has 54615 vertices and 18205 triangles...

..tested just now and it works fine for me...however even that (65535 vertices) is still poor limitation, so for folks such as yourself who is building quite neat procedural cave system, down to triangle, I believe, B3D is bad choice of tool..

RemiD

Quote
so for folks such as yourself who is building quite neat procedural cave system, down to triangle, I believe, B3D is bad choice of tool..
i know that this limitation is annoying, but i manage to achieve what i achieve because i have a good understanding and experience with Blitz3d, so learning a new language / engine is useless for me at the moment, but maybe later, if i create something good enough...

TomToad

Ok, did a test of 1,002,001 vertices and 2,000,000 triangles.  Rendered at around 72 FPS on my laptop.

A couple of limitations that I've noticed.

1. Memblocks are limited to only 100,000,000 bytes in size.  So your mesh needs to fit in that.  It appears that you will reach that memblock limit before you will reach the max vertex limit (whatever that is)

2. creating a mesh that size procedurally takes a long time.  It took about 30 seconds to create the mesh using the mesh.agc functions I posted before.

Test code below.  You need the mesh.agc file I posted before, and the mesh3-1.jpg file as well.

// Project: maxverts
// Created: 2018-03-08
#insert "mesh.agc"
// show all errors
SetErrorMode(2)

// set window properties
SetWindowTitle( "maxverts" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 0, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
Setcameraposition(1,0,0,0)
SetCameraRotation(1,0,0,0)

grid as Mesh
for y = 0 to 1000
for x = 0 to 1000
AddVertex(grid,x-500,y-500,999,0,0,-1,mod(x,2),mod(y,2),0xFFFFFFFF)
next x
if mod(y,100) = 0
Print (y)
sync()
endif
next y

for y = 0 to 999
for x = 0 to 999
v1 = x+y*1001
v2 = x+y*1001+1
v3 = x+(y+1)*1001
v4 = x+(y+1)*1001+1
AddTriangle(grid,v1,v2,v3)
AddTriangle(grid,v2,v4,v3)
next
if mod(y,100) = 0
print (y)
sync()
endif
next

gridObject = CreateObjectFromMesh(grid)
image = LoadImage("mesh3-1.jpg")
SetObjectImage(gridObject,image,0)

do
   

    Print( ScreenFPS() )
    print("Vertex = "+str(grid.VertexList.Length+1))
    Print("Triangle = "+str(grid.TriangleList.Length+1))
    Sync()
loop
------------------------------------------------
8 rabbits equals 1 rabbyte.