Posted: 22nd Mar 2023 18:53
Hello everyone, could someone provide me with a terrain editor using the latest AppGameKit functions and updates so I can get a feel for how to start making my terrain editor?
Posted: 22nd Mar 2023 19:23
In the examples provided with the product (In the IDE select Tools/Install additional files) there is a folder called "Terrain" that has an example of using the heightmap commands.
Posted: 22nd Mar 2023 21:06
i would like to edit heightmap on realtime ?
Posted: 22nd Mar 2023 21:14
I personally would modify the image and re-generate the mesh because CreateObjectFromHeightMap() creates a special type of mesh that loading from disk would take ages.

If you want to modify a mesh then I would look at the following commands.
CreateMemblockFromObjectMesh()
and
SetObjectMeshFromMemblock()

Remember that you will need to manually save the mesh to one of the supported 3D formats like .obj .fbx .x etc

This might help as well
Posted: 23rd Mar 2023 11:07
there is a couple of examples here https://forum.thegamecreators.com/thread/222027
or you could use this method which is only suitable for smaller maps
+ Code Snippet
// Project: heights 
// Created: 2019-01-01
   
// show all errors
SetErrorMode(2)
   
#constant screenwidth=1024
#constant screenheight=768
#constant fullscreen=0
#constant screenrate=0
#constant	SCALE_X	1
#constant	SCALE_Y	1
#constant	SCALE_Z	1
 
  
// set window properties
SetWindowTitle( "heights" )
SetWindowSize( screenwidth, screenheight, fullscreen )
SetWindowAllowResize( 1 ) // allow the user to resize the window
   
// set display properties
SetVirtualResolution( screenwidth, screenheight ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( screenrate, 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
Create3DPhysicsWorld()  
#constant sizex=21 // change this to extend the map
#constant sizez=21 // change this to exeend the map
global angx#, angy#,startx#,starty#
startx#=screenwidth/2
starty#=screenheight/2
 
size=5
 
type _map
    id
    x#
    height#
    z#
    colorred
    colorgreen
    colorblue
    texture
endtype
  
global map as _map[sizex,sizez]
 
global vertexnumber

//textimages as integer[10]
//for loops=0 to 10
//   textimages[loops]= createtexture(64,64,MakeColor(0,255,0),255)
//next
textimages as integer[10]
textimages[0]= createtexture(64,64,MakeColor(0,255,0),255)
textimages[1]= createtexture(64,64,MakeColor(255,255,255),255)

land = CreateObjectBox(.01,.01,.01)
colorgreen=150
for x=1 to sizex
    for z=1 to sizez
        map[x,z].id = CreateObjectBox(9,9,9)
        map[x,z].x# = x * GetObjectSizeMaxX(map[x,z].id)*2 // Remove the * 2 to join the cubes together
        map[x,z].height#=random(0,0)
        map[x,z].z# = z * GetObjectSizeMaxZ(map[x,z].id)*2 // Remove the * 2 to join the cubes together

        //map[x,z].colorgreen = random(150,200)
		//SetObjectImage(map[x,z].id,textimages[0],0)
		if colorgreen=150
			colorgreen=200
		else
			colorgreen=150
		endif
				
		map[x,z].colorgreen =colorGreen	
		SetObjectImage(map[x,z].id,textimages[0],0)
		
        Create3DPhysicsStaticBody(map[x,z].id)   
        SetObjectColor(map[x,z].id,0,map[x,z].colorgreen,0,255)
        SetObjectPosition(map[x,z].id,map[x,z].x#,0,map[x,z].z#)
        FixObjectToObject(map[x,z].id,land)
        		
    next
next
 
//RotateObjectLocalY(land,-30)
prepareheights()
  
camerax#=20
cameray#=30
cameraz#=0
 
  
// frameImg=LoadImage("\media\frame2.png")
//FrameSpr=createSprite(frameImg) 
collisioner=CreateObjectBox(10,10,10)
do
  
  //  SetSpriteDepth(frameSpr,100) //set the frame to behind all tiles to allow clicking to work
 
    unit_x#=Get3DVectorXFromScreen(getpointerx(),getpointery())
    unit_y#=Get3DVectorYFromScreen(getpointerx(),getpointery())
    unit_z#=Get3DVectorZFromScreen(getpointerx(),getpointery()) 
    // calculate the start of the ray cast, which is the unit vector + the camera position
        start_x# = unit_x# + camerax#
        start_y# = unit_y# + cameray#
        start_z# = unit_z# - cameraz#
 
        // calculate the end of the vector, which is the unit vector multiplied by the length of the ray cast and then add the camera position to it
        end_x# = 800*unit_x# + camerax#
        end_y# = 800*unit_y# + cameray#
        end_z# = 800*unit_z# - cameraz#
 
        // determine which object has been hit
        object_hit = ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)
 
        // if an object has been hit then turn it red
        if object_hit <> 0
 
            x=getobjectx(object_hit)/9
            z=getobjectz(object_hit)/9
             
        else
        endif
 
 
     
    if GetRawKeyState(13)
        //RotateObjectLocalY(land,.05)
    endif
    if GetRawMouseLeftState()
        flag=1
        if x<2 or x>sizex-1 then flag=0
        if z<2 or z>sizez-1 then flag=0
        if flag=1
            inc map[x,z].height#,.01
            SetObjectPosition(map[x,z].id,map[x,z].x#,map[x,z].height#,map[x,z].z#)
            changeverts(x,z,.01)
            Delete3DPhysicsBody(map[x,z].id) 
            Create3DPhysicsStaticBody(map[x,z].id)   
        endif
    endif
 
 
    if GetRawMouseRightState()
        flag=1
        if x<2 or x>sizex-1 then flag=0
        if z<2 or z>sizez-1 then flag=0
        if flag=1 and map[x,z].height#>0
            dec map[x,z].height#,.01
            SetObjectPosition(map[x,z].id,map[x,z].x#,map[x,z].height#,map[x,z].z#)
            changeverts(x,z,-.01)
            Delete3DPhysicsBody(map[x,z].id) 
            Create3DPhysicsStaticBody(map[x,z].id)   
        endif
    endif
     
    if GetRawMouseMiddlePressed() 
        flag=1
        if x<2 or x>sizex-1 then flag=0
        if z<2 or z>sizez-1 then flag=0
        if flag=1 
			//if map[x,z].height#>0
				dec map[x,z].height#,10
				SetObjectPosition(map[x,z].id,map[x,z].x#,map[x,z].height#,map[x,z].z#)
				changeverts(x,z,-10.01)
				Delete3DPhysicsBody(map[x,z].id) 
				Create3DPhysicsStaticBody(map[x,z].id)
            //endif   
			//SetObjectColor(map[x,z].id,GetObjectColorRed(map[x,z].id)-50,GetObjectColorGreen(map[x,z].id)-50,GetObjectColorBlue(map[x,z].id)-50,255)  
			//SetObjectColor(map[x+1,z+1].id,GetObjectColorRed(map[x+1,z+1].id)-50,GetObjectColorGreen(map[x+1,z+1].id)-50,GetObjectColorBlue(map[x+1,z+1].id)-50,255)  
			//SetObjectColor(map[x-1,z+1].id,GetObjectColorRed(map[x-1,z+1].id)-50,GetObjectColorGreen(map[x-1,z+1].id)-50,GetObjectColorBlue(map[x-1,z+1].id)-50,255)  
			//SetObjectColor(map[x-1,z-1].id,GetObjectColorRed(map[x-1,z-1].id)-50,GetObjectColorGreen(map[x-1,z-1].id)-50,GetObjectColorBlue(map[x-1,z-1].id)-50,255)  
			//SetObjectColor(map[x+1,z].id,GetObjectColorRed(map[x+1,z].id)-50,GetObjectColorGreen(map[x+1,z].id)-50,GetObjectColorBlue(map[x+1,z].id)-50,255)  
			//SetObjectColor(map[x-1,z].id,GetObjectColorRed(map[x-1,z].id)-50,GetObjectColorGreen(map[x-1,z].id)-50,GetObjectColorBlue(map[x-1,z].id)-50,255)  
			//SetObjectColor(map[x,z+1].id,GetObjectColorRed(map[x,z+1].id)-50,GetObjectColorGreen(map[x,z+1].id)-50,GetObjectColorBlue(map[x,z+1].id)-50,255)  
			//SetObjectColor(map[x,z-1].id,GetObjectColorRed(map[x,z-1].id)-50,GetObjectColorGreen(map[x,z-1].id)-50,GetObjectColorBlue(map[x,z-1].id)-50,255)  
			SetObjectColor(map[x,z].id,100,100,100,255):SetObjectImage(map[x,z].id,textImages[1],0)  
			SetObjectColor(map[x+1,z+1].id,100,100,100,255):SetObjectImage(map[x+1,z+1].id,textImages[1],0) 
			SetObjectColor(map[x-1,z+1].id,100,100,100,255):SetObjectImage(map[x-1,z+1].id,textImages[1],0) 
			SetObjectColor(map[x-1,z-1].id,100,100,100,255):SetObjectImage(map[x-1,z-1].id,textImages[1],0) 
			SetObjectColor(map[x+1,z].id,100,100,100,255):SetObjectImage(map[x+1,z].id,textImages[1],0) 
			SetObjectColor(map[x-1,z].id,100,100,100,255):SetObjectImage(map[x-1,z].id,textImages[1],0) 
			SetObjectColor(map[x,z+1].id,100,100,100,255):SetObjectImage(map[x,z+1].id,textImages[1],0) 
			SetObjectColor(map[x,z-1].id,100,100,100,255):SetObjectImage(map[x,z-1].id,textImages[1],0) 
			
		endif
        
    endif  
    //if GetRawKeyPressed(32) then AGK_Save_X(map,"Map.x",0) 
    if GetRawKeyPressed(32) then AGK_SaveObject(map,"Map.obj","map.mtl") 
    
    
    if GetRawKeyState(68) then inc camerax#,.1
    if GetRawKeyState(65) then dec camerax#,.1
    if GetRawKeyState(83) then inc cameray#,.1
    if GetRawKeyState(87) then dec cameray#,.1
      
         movecamera()
 
    SetCameraPosition(1,camerax#,cameray#,cameraz#)
    Print( ScreenFPS() )
    Sync()
loop
 
function movecamera()
    if GetRawKeyState(32)
    fDiffX# = (GetPointerX() - startx#)/4.0
    fDiffY# = (GetPointerY() - starty#)/4.0
    newX# = angx# + fDiffY#
    if ( newX# > 89 ) then newX# = 89
    if ( newX# < -89 ) then newX# = -89
    SetCameraRotation(1, newX#, angy# + fDiffX#, 0 )
    endif
endfunction
   
function prepareheights()
    for x=2 to sizex-1
        for z=2 to sizez-1
            changeverts(x,z,map[x,z].height#)
        next
    next
endfunction
   
function changeverts(x,z,slope#)
      
            CreateMemblockFromObjectMesh(2,map[x+1,z-1].id,1) // bottom right corner
            CreateMemblockFromObjectMesh(4,map[x+1,z+1].id,1) // top right corner
            CreateMemblockFromObjectMesh(5,map[x-1,z+1].id,1) // top left corner
            CreateMemblockFromObjectMesh(6,map[x-1,z-1].id,1) // bottom left corner
    
            CreateMemblockFromObjectMesh(3,map[x+1,z].id,1) // right edges
  
            CreateMemblockFromObjectMesh(7,map[x-1,z].id,1) // left cube edges
           CreateMemblockFromObjectMesh(8,map[x,z-1].id,1) // bottom cube edges
           CreateMemblockFromObjectMesh(9,map[x,z+1].id,1) // top cube edges
  
              
    for i=0 to 23
          
// bottom rightcorner
        if i=8 then SetMeshMemblockVertexPosition(2,i,GetMeshMemblockVertexX(2,i),GetMeshMemblockVertexY(2,i)+slope#,GetMeshMemblockVertexZ(2,i))
        if i=16 then SetMeshMemblockVertexPosition(2,i,GetMeshMemblockVertexX(2,i),GetMeshMemblockVertexY(2,i)+slope#,GetMeshMemblockVertexZ(2,i))
        if i=14 then SetMeshMemblockVertexPosition(2,i,GetMeshMemblockVertexX(2,i),GetMeshMemblockVertexY(2,i)+slope#,GetMeshMemblockVertexZ(2,i))
  
// top rightcorner
        if i=9 then SetMeshMemblockVertexPosition(4,i,GetMeshMemblockVertexX(4,i),GetMeshMemblockVertexY(4,i)+slope#,GetMeshMemblockVertexZ(4,i))
        if i=0 then SetMeshMemblockVertexPosition(4,i,GetMeshMemblockVertexX(4,i),GetMeshMemblockVertexY(4,i)+slope#,GetMeshMemblockVertexZ(4,i))
        if i=18 then SetMeshMemblockVertexPosition(4,i,GetMeshMemblockVertexX(4,i),GetMeshMemblockVertexY(4,i)+slope#,GetMeshMemblockVertexZ(4,i))
  
// top leftcorner
        if i=11 then SetMeshMemblockVertexPosition(5,i,GetMeshMemblockVertexX(5,i),GetMeshMemblockVertexY(5,i)+slope#,GetMeshMemblockVertexZ(5,i))
        if i=2 then SetMeshMemblockVertexPosition(5,i,GetMeshMemblockVertexX(5,i),GetMeshMemblockVertexY(5,i)+slope#,GetMeshMemblockVertexZ(5,i))
       if i=4 then SetMeshMemblockVertexPosition(5,i,GetMeshMemblockVertexX(5,i),GetMeshMemblockVertexY(5,i)+slope#,GetMeshMemblockVertexZ(5,i))
   
  
// tbottom leftcorner
        if i=10 then SetMeshMemblockVertexPosition(6,i,GetMeshMemblockVertexX(6,i),GetMeshMemblockVertexY(6,i)+slope#,GetMeshMemblockVertexZ(6,i))
        if i=6 then SetMeshMemblockVertexPosition(6,i,GetMeshMemblockVertexX(6,i),GetMeshMemblockVertexY(6,i)+slope#,GetMeshMemblockVertexZ(6,i))
        if i=12 then SetMeshMemblockVertexPosition(6,i,GetMeshMemblockVertexX(6,i),GetMeshMemblockVertexY(6,i)+slope#,GetMeshMemblockVertexZ(6,i))
  
  
// right cube
        if i=8 then SetMeshMemblockVertexPosition(3,i,GetMeshMemblockVertexX(3,i),GetMeshMemblockVertexY(3,i)+slope#,GetMeshMemblockVertexZ(3,i))
        if i=9 then SetMeshMemblockVertexPosition(3,i,GetMeshMemblockVertexX(3,i),GetMeshMemblockVertexY(3,i)+slope#,GetMeshMemblockVertexZ(3,i))
        if i=16 then SetMeshMemblockVertexPosition(3,i,GetMeshMemblockVertexX(3,i),GetMeshMemblockVertexY(3,i)+slope#,GetMeshMemblockVertexZ(3,i))
        if i=18 then SetMeshMemblockVertexPosition(3,i,GetMeshMemblockVertexX(3,i),GetMeshMemblockVertexY(3,i)+slope#,GetMeshMemblockVertexZ(3,i))
        if i=0 then SetMeshMemblockVertexPosition(3,i,GetMeshMemblockVertexX(3,i),GetMeshMemblockVertexY(3,i)+slope#,GetMeshMemblockVertexZ(3,i))
        if i=14 then SetMeshMemblockVertexPosition(3,i,GetMeshMemblockVertexX(3,i),GetMeshMemblockVertexY(3,i)+slope#,GetMeshMemblockVertexZ(3,i))
  
// left cube
        if i=10 then SetMeshMemblockVertexPosition(7,i,GetMeshMemblockVertexX(7,i),GetMeshMemblockVertexY(7,i)+slope#,GetMeshMemblockVertexZ(7,i))
        if i=11 then SetMeshMemblockVertexPosition(7,i,GetMeshMemblockVertexX(7,i),GetMeshMemblockVertexY(7,i)+slope#,GetMeshMemblockVertexZ(7,i))
        if i=4 then SetMeshMemblockVertexPosition(7,i,GetMeshMemblockVertexX(7,i),GetMeshMemblockVertexY(7,i)+slope#,GetMeshMemblockVertexZ(7,i))
        if i=6 then SetMeshMemblockVertexPosition(7,i,GetMeshMemblockVertexX(7,i),GetMeshMemblockVertexY(7,i)+slope#,GetMeshMemblockVertexZ(7,i))
        if i=2 then SetMeshMemblockVertexPosition(7,i,GetMeshMemblockVertexX(7,i),GetMeshMemblockVertexY(7,i)+slope#,GetMeshMemblockVertexZ(7,i))
        if i=12 then SetMeshMemblockVertexPosition(7,i,GetMeshMemblockVertexX(7,i),GetMeshMemblockVertexY(7,i)+slope#,GetMeshMemblockVertexZ(7,i))
         
// bottom cube
        if i=8 then SetMeshMemblockVertexPosition(8,i,GetMeshMemblockVertexX(8,i),GetMeshMemblockVertexY(8,i)+slope#,GetMeshMemblockVertexZ(8,i))
        if i=10 then SetMeshMemblockVertexPosition(8,i,GetMeshMemblockVertexX(8,i),GetMeshMemblockVertexY(8,i)+slope#,GetMeshMemblockVertexZ(8,i))
        if i=6 then SetMeshMemblockVertexPosition(8,i,GetMeshMemblockVertexX(8,i),GetMeshMemblockVertexY(8,i)+slope#,GetMeshMemblockVertexZ(8,i))
        if i=12 then SetMeshMemblockVertexPosition(8,i,GetMeshMemblockVertexX(8,i),GetMeshMemblockVertexY(8,i)+slope#,GetMeshMemblockVertexZ(8,i))
        if i=14 then SetMeshMemblockVertexPosition(8,i,GetMeshMemblockVertexX(8,i),GetMeshMemblockVertexY(8,i)+slope#,GetMeshMemblockVertexZ(8,i))
        if i=16 then SetMeshMemblockVertexPosition(8,i,GetMeshMemblockVertexX(8,i),GetMeshMemblockVertexY(8,i)+slope#,GetMeshMemblockVertexZ(8,i))
  
// top cube
        if i=9 then SetMeshMemblockVertexPosition(9,i,GetMeshMemblockVertexX(9,i),GetMeshMemblockVertexY(9,i)+slope#,GetMeshMemblockVertexZ(9,i))
        if i=11 then SetMeshMemblockVertexPosition(9,i,GetMeshMemblockVertexX(9,i),GetMeshMemblockVertexY(9,i)+slope#,GetMeshMemblockVertexZ(9,i))
        if i=0 then SetMeshMemblockVertexPosition(9,i,GetMeshMemblockVertexX(9,i),GetMeshMemblockVertexY(9,i)+slope#,GetMeshMemblockVertexZ(9,i))
        if i=2 then SetMeshMemblockVertexPosition(9,i,GetMeshMemblockVertexX(9,i),GetMeshMemblockVertexY(9,i)+slope#,GetMeshMemblockVertexZ(9,i))
        if i=4 then SetMeshMemblockVertexPosition(9,i,GetMeshMemblockVertexX(9,i),GetMeshMemblockVertexY(9,i)+slope#,GetMeshMemblockVertexZ(9,i))
        if i=18 then SetMeshMemblockVertexPosition(9,i,GetMeshMemblockVertexX(9,i),GetMeshMemblockVertexY(9,i)+slope#,GetMeshMemblockVertexZ(9,i))
  
    next
      
    SetObjectMeshFromMemblock(map[x+1,z-1].id,1,2)   
    SetObjectMeshFromMemblock(map[x+1,z].id,1,3)   
    SetObjectMeshFromMemblock(map[x+1,z+1].id,1,4)   
    SetObjectMeshFromMemblock(map[x-1,z+1].id,1,5)   
    SetObjectMeshFromMemblock(map[x-1,z-1].id,1,6)   
    SetObjectMeshFromMemblock(map[x-1,z].id,1,7)   
    SetObjectMeshFromMemblock(map[x,z-1].id,1,8)   
    SetObjectMeshFromMemblock(map[x,z+1].id,1,9)   
  
  
  
  
  
  
    DeleteMemblock(2)
    DeleteMemblock(3)
    DeleteMemblock(4)
    DeleteMemblock(5)
    DeleteMemblock(6)
    DeleteMemblock(7)
    DeleteMemblock(8)
    DeleteMemblock(9)
   
   
endfunction

// Function to create a texture
//
// Inputs - Sizex - size of the texture to create - width
//          Sizey - size of the texture to create - height
//          Color - is the main color of the image
//          Denisity - is a the depth of the texture - the lower the value, the more detail. higher value = no detail
// 
// Returns the image for the resulting texture
//
// EG. CreateTexture ( 100, 100,  makecolor(0,0,255), 100)
//          This could create a DEEP water effect texture?
  
function createtexture(sizex# as float, sizey# as float, color, density as integer)
  
      
    swap()
    drawbox(0,0,sizex#, sizey#, color, color,color,color, 1)
    render()
    img = getimage(0,0,sizex#, sizey#)
      
    memblockid = CreateMemblockFromImage (img)
    imgwidth = GetMemblockInt(memblockid, 0)
    imgheight = GetMemblockInt(memblockid, 4)
      
      
        size=GetMemblockSize(memblockid)
  
        for offset=12 to size-4 step 4
        
            r=GetMemblockByte(memblockid, offset)
            g=GetMemblockByte(memblockid, offset+1)
            b=GetMemblockByte(memblockid, offset+2)
            a=GetMemblockByte(memblockid, offset+3)
              
          
            strength=random(1,density)
  
            SetMemblockByte (memblockid, offset, r-strength)
            SetMemblockByte (memblockid, offset+1, g-strength)
            SetMemblockByte (memblockid, offset+2, b-strength )
            SetMemblockByte (memblockid, offset+3, a-strength)
               
          
    next
      
    deleteimage (img)
      
    img = CreateImageFromMemblock(memblockid)
    DeleteMemblock(memblockid)
  
  
endfunction img
//////////////////////////////////////////////////////////////////////////////
Function AGK_Save_X(Amap as _map[][],filename$ as string,material as integer)
n as integer:s as integer: t as integer:mesh as integer:verts as integer:i as integer
x# as float:y# as float: z# as float: ox# as float:oy# as float: oz# as float
end$ as string:b$ as string:nx# as float:ny# as float:nz# as float: u# as float:v# as float
x as integer,y as integer
setrawwritepath(getreadpath())
OpenToWrite ( 1, filename$, 0 )
writeline( 1,"xof 0303txt 0032")
writeline(1," ")  `space
writeline(1,"#Save boxes to .x by Chafari ")
writeline(1,"#Made in AGK2 December 2018")
writeline(1,"")  `space
//for t= 0 to boxes.length step 1
   
 
xx as integer:for xx=1 to sizex
zz as integer:for zz=1 to sizez`

	
	n=0
	s=0
  if GetObjectExists(aMap[xx,zz].id)
	    //setobjectrotation(aMap[xx,zz].id,0,0,45)
	    //setobjectimage(boxes[x,y],material,0) //// add a default material here because it needs one
		mesh = CreateMemblockFromObjectMesh(aMap[xx,zz].id,1)
		//boxes[t].memID=Mesh
		`number of vertex
		verts= GetMemblockInt( mesh, 0 )

		`VERTICES
		writeline(1,"Mesh {")
		writeline(1, str(verts) + ";")
		 for i= 0 to verts-1
			 x#=GetMeshMemblockVertexX(mesh,i)
			 y#=GetMeshMemblockVertexy(mesh,i)
			 z#=GetMeshMemblockVertexz(mesh,i)
			
			
ox#=GetObjectWorldX(aMap[xx,zz].id)
oy#=GetObjectWorldY(aMap[xx,zz].id)
oz#=GetObjectWorldZ(aMap[xx,zz].id)			
			
			
			`vertex
			 if i < verts - 1 then end$ = ";," else end$ = ";;"
			 writeline( 1, str(x#+ox#, 6) + ";" + str(y#+oy#, 6) + ";" + str(z#+oz#, 6) + end$)
		 next i
		 
		`FACES 
		writeline(1,"12;") 
		for i= 0 to 18

			inc s
			if s=3
			   writeline(1,str(3)+";"+str(n+2)+","+str(n+1)+","+str(n)+";,")
				if i<16 then b$=";," else b$=";;"
			   writeline(1,str(3)+";"+str(n+3)+","+str(n+1)+","+str(n+2)+b$)
			   n=n+1
			   s=0
			   n=n+3
			endif
		next
		n=0 `reset n
		`----------------------------------------------------------------------------
		`NORMALES
		writeline(1,"MeshNormals {")
		writeline(1, str(verts) + ";")
		 for i= 0 to verts-1
			 nx#=GetMeshMemblockVertexNormalX(mesh,i)
			 ny#=GetMeshMemblockVertexNormaly(mesh,i)
			 nz#=GetMeshMemblockVertexNormalz(mesh,i)
			
			`Normals
			 if i < verts - 1 then end$ = ";," else end$ = ";;"
			 writeline( 1, str(nx#, 6) + ";" + str(ny#, 6) + ";" + str(nz#, 6) + end$)
		 next i
		 
		writeline(1,"12;") 
		for i= 0 to 18
			
			inc s
			if s=3
			   writeline(1,str(3)+";"+str(n+2)+","+str(n+1)+","+str(n)+";,")
			   if i<16 then b$=";," else b$=";;"
			   writeline(1,str(3)+";"+str(n+3)+","+str(n+1)+","+str(n+2)+b$)
			   n=n+1
			   s=0
			   n=n+3
			endif
		next
		writeline(1,"}")


		`TEXTURE COORDINATES
		writeline(1,"MeshTextureCoords {")
		writeline(1, str(verts) + ";")
		 for i= 0 to verts-1
			 U#=GetMeshMemblockVertexU(mesh,i)
			 V#=GetMeshMemblockVertexV(mesh,i)
			`UV
			 if i < verts - 1 then end$ = ";," else end$ = ";;"
			 writeline( 1, str(U#, 6) + ";" + str(V#, 6) + end$)
		 next
		 
		writeline(1,"}")

		 writeline(1," MeshMaterialList { ")
		 writeline(1,"    1;")
		 writeline(1,"    1;")
		 writeline(1,"    0;;")
		 writeline(1,"    Material Material {")
		 writeline(1,"    0.640000; 0.640000; 0.640000; 1.000000;;")
		 writeline(1,"    96.078431;")
		 writeline(1,"    0.500000; 0.500000; 0.500000;;")
		 writeline(1,"    0.000000; 0.000000; 0.000000;;")
		 //writeline(1,"    TextureFilename {" + chr(34)+ str(t)+".png" + chr(34)+ ";}")  `different texture per limb...  1.png,  2.png  3.png   etc etc.
		            `to import all meshes (limbs) in AGK , as AGK will cosider all meshes with same texture as the same mesh (limb)
		 writeline(1,"    TextureFilename {" + chr(34)+"test.png" + chr(34)+ ";}")  `saving a texture for the whole object
		 writeline(1,"       }")
		 writeline(1,"    }")
		 writeline(1,"}")
		 writeline(1,"//------------------new mesh -------------------------")

		 DeleteMemblock(mesh)
   endif
next zz
next xx
   CloseFile ( 1 )
   /*
   for t= boxes.length to 0 step -1
	if GetObjectExists(boxes[x,y])	
		DeleteObject(boxes[x,y])
    	DeleteMemblock(boxes[t].memID)
    	boxes.remove(t)
	endif
	next t
	boxes.length=0
	*/
endfunction

Function AGK_SaveObject(aMap as _map[][],filename$ as string,material$ as string)
//for t= 1 to boxes.length //to 0 step-1
	//if GetObjectExists(boxes[t].id)	
		//SetObjectPosition(boxes[t].id,getobjectX(boxes[t].id)-64,getobjectY(boxes[t].id),getobjectZ(boxes[t].id)+64)
	//endif
//next t	
t as integer: mesh as integer:x# as float: y# as float : z# as float:ox# as float: oy# as float : oz# as float
verts as integer: i as integer: uu# as float: vv# as float: s as integer: n as integer: nor as integer
setrawwritepath(getreadpath())
fw as integer
fw = OpenToWrite(filename$) 
 
WriteLine(fw,"#3D Extruder Object - " + filename$)
WriteLine(fw,"#Exported with AppGameKit")
WriteLine(fw,"")
WriteLine(fw,"mtllib " + material$)
Writeline ( fw, " ")
incrementalcounter as integer:incrementalcounter=0
m as integer  :meshb as integer
`number of material
m=0
	//nor=0
	//n=0
	//obj=10000
meshB=0

xx as integer:for xx=1 to sizex
zz as integer:for zz=1 to sizez`
	if GetObjectExists(aMap[xx,zz].id)	
				
	 //meshB=CreateMemblockFromObjectMesh(aMap[xx,zz].id, 1 )
		mesh = CreateMemblockFromObjectMesh(aMap[xx,zz].id,1)
        //aMap[xx,zz].mem=Mesh
`		get object vertex quantity 
		verts= GetMemblockInt( mesh, 0 )
		//writeline(fw,"g Group.000") //GROUP
		inc incrementalcounter
		writeline(fw,"o Object."+str(incrementalcounter))
		`VERTEX
		for i= 0 to verts -1
			x#=GetMeshMemblockVertexX(mesh,i)
			y#=GetMeshMemblockVertexy(mesh,i)
			z#=GetMeshMemblockVertexz(mesh,i)
			ox#=GetObjectWorldX(aMap[xx,zz].id)
			oy#=GetObjectWorldY(aMap[xx,zz].id)
			oz#=GetObjectWorldZ(aMap[xx,zz].id)
			//Writeline ( fw, " v " + str(x#+ox#)+ " "+str(y#+oy#)+ " "+str(z#+oz#))
			WriteLine(fw, "v "+str((x#+ox#) * SCALE_X)+" "+str((y#+oy#) * SCALE_Y)+" "+str((z#+oz#)* SCALE_Z)+" ")
		next i
		Writeline ( fw, " ")
 
	`TEXTURE VEERTICES
	for i= 0 to verts -1
		uu#=GetMeshMemblockVertexU( mesh, i )
		vv#=GetMeshMemblockVertexV( mesh, i )
		writeline(fw, " vt "+str(uu#)+" "+str(vv#))
	next
    Writeline ( fw, " ")
  `		NORMALS
	for i= 0 to verts -1
		x#=GetMeshMemblockVertexnormalX(mesh,i)
		y#=GetMeshMemblockVertexnormaly(mesh,i)
		z#=GetMeshMemblockVertexnormalz(mesh,i)
 
		Writeline ( fw, " vn " + str(x#)+ " "+str(y#)+ " "+str(z#))
	next i
    Writeline ( fw, " ")
   
	`FACES
	inc m,1
	Writeline ( fw,"usemtl Material.00"+str(m))
	s=0 `reseting variable s
 
   for i= 1 to verts-4
        
    inc s,1
      if s=3
        n=n+1
        nor=nor+4
        writeline (fw, " f "+ str(n+1)+"/"+str(n+1)+"/"+str(nor)    +" "+str(n) +"/"+str(n+2)+"/"+str(nor)     +" "+str(n+2)+"/"+str(n)+"/"+str(nor)      +" "+str(n+3)+"/"+str(n+3)+"/"+str(nor))
        //writeline (fw, " f "+ str(n+1)+" "+str(n+1)+" "+str(nor)    +" "+str(n) +" "+str(n+2)+" "+str(nor)     +" "+str(n+2)+" "+str(n)+" "+str(nor)      +" "+str(n+3)+" "+str(n+3)+" "+str(nor))
        
         s=0
        n=n+3
      endif
   next
   Writeline ( fw, " ")
   DeleteMemblock(mesh)
endif 
next zz
next xx

CloseFile ( fw ) 
/*  
fw=OpenToWrite(material$)
WriteLine(fw,"#Exported with AppGameKit")
for t= 1 to boxes.length step 1
	if GetObjectExists(aMap[xx,zz].id)	
		Writeline ( fw,"newmtl Material.00"+str(t))
		WriteLine(fw,"Kd " + str(GetObjectColorRed(aMap[xx,zz].id)/255.0) + " " + str(GetObjectColorGreen(aMap[xx,zz].id)/255.0) + " " + str(GetObjectColorBlue(aMap[xx,zz].id)/255.0)+"_0")
    	//DeleteObject(aMap[xx,zz].id)
    	//DeleteMemblock(aMap[xx,zz].memID)
    	//boxes.remove(t)
	endif
next t
CloseFile(fw)
*/
//DeleteAllObjects()
//boxes.length=0
endfunction