no where near as good as AGE3D but I created this one
A bare bones 3D Placement editor EDITED
// Project: 3D Placement Editor
// Created: 2019-02-11
// show all errors
SetErrorMode(2)
#constant screenwidth=1024
#constant screenheight=768
#constant fullscreen=0
#constant screenrate=0
#constant KEY_LEFT 37
#constant KEY_UP 38
#constant KEY_RIGHT 39
#constant KEY_DOWN 40
#constant KEY_W 87
#constant KEY_A 65
#constant KEY_S 83
#constant KEY_Z 90
#constant KEY_L 76
#constant KEY_F1 112
#constant KEY_F2 113
#constant KEY_LESSTHAN 188
#constant KEY_GREATERTHAN 190
#constant KEY_HOME 36
#constant KEY_PLUS 107
#constant KEY_SUBTRACT 109
#constant KEY_SHIFT 16
//change these values to ammounts you find useful
#constant moveAmmount 0.05
#constant rotateAmmount 0.05
#constant scaleAmmount 0.1
type _object
ID as integer
imageID as integer
scale as float
name as string
imageName as string
endtype
type point
x as float
y as float
z as float
endtype
type camera
dolly as integer
camera as integer
offset as point
last as point
angle as point
endtype
camera as camera
// set window properties
SetWindowTitle( "3D Placement Editor" )
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
camera.dolly = CreateObjectBox(1, 1, 1)
SetObjectVisible(camera.dolly, 0)
camera.camera = CreateObjectBox(1, 1, 1)
SetObjectVisible(camera.camera, 0)
camera.angle.x = 0
FixObjectToObject(camera.camera, camera.dolly)
MoveObjectLocalZ(camera.camera, -20)
RotateObjectLocalX(camera.dolly, camera.angle.x)
objects as _object[]
global current as integer
current=-1:saveFlag=0
SetCameraPosition(1,0,10,-20 )
do
if GetRawKeyPressed(KEY_L)
DeleteAllObjects()
DeleteAllImages()
for num = objects.length to 0 step-1
objects.remove(num)
next num
current=-1:saveFlag=1
loadObjects(objects)
Message(left(ret$,len(ret$)-(len(objects[current].name)+1))+" test.data loaded")
endif
if GetRawKeyPressed(KEY_F1)
object as _object
ret$=ChooseRawFile("*.obj;*.3ds",1)
if ret$<>""
object.ID=loadObject("raw:"+ret$)
count=1
for num = 1 to len(ret$)
if Mid(ret$,num,1)="\" then inc count
next num
object.name=GetStringToken( ret$, "\", count )
ret$=ChooseRawFile("*.jpg;*.png",1)
if ret$<>""
count=1
for num = 1 to len(ret$)
if Mid(ret$,num,1)="\" then inc count
next num
object.ImageName=GetStringToken( ret$, "\", count )
object.imageID=loadImage("raw:"+ret$)
SetObjectImage(object.ID,object.imageID,0)
endif
object.scale=1:saveFlag=1
objects.insert(object)
inc current
endif
endif
if GetRawKeyPressed(KEY_F2) and saveFlag=1
if current>=0
saveData(objects,"raw:"+left(ret$,len(ret$)-(len(objects[current].name)+1))+"test.data")
Message("test.data saved to "+left(ret$,len(ret$)-(len(objects[current].name)+1)))
endif
endif
if current>=0
Print(left(ret$,len(ret$)-(len(objects[current].name)+1))+"test.data")
endif
//camera movement commands
if GetRawKeyState(KEY_SHIFT) and GetRawKeyState(KEY_W)
MoveObjectLocalY(camera.camera,moveAmmount)
//SetCameraPosition(1,getCameraX(1),getCameraY(1)+1,getCameraZ(1))
elseif GetRawKeyState(KEY_W)
MoveObjectLocalZ(camera.camera,moveAmmount)
//SetCameraPosition(1,getCameraX(1),getCameraY(1),getCameraZ(1)+1)
endif
if GetRawKeyState(KEY_A)
MoveObjectLocalX(camera.camera,-moveAmmount)
//SetCameraPosition(1,getCameraX(1)-1,getCameraY(1),getCameraZ(1))
endif
if GetRawKeyState(KEY_S)
MoveObjectLocalX(camera.camera,moveAmmount)
//SetCameraPosition(1,getCameraX(1)+1,getCameraY(1),getCameraZ(1))
endif
if GetRawKeyState(KEY_SHIFT) and GetRawKeyState(KEY_Z)
MoveObjectLocalY(camera.camera,-moveAmmount)
//SetCameraPosition(1,getCameraX(1),getCameraY(1)-1,getCameraZ(1))
elseif GetRawKeyState(KEY_Z)
MoveObjectLocalZ(camera.camera, -moveAmmount)
//SetCameraPosition(1,getCameraX(1),getCameraY(1),getCameraZ(1)-1)
endif
if current>=0
//object movement commands
if GetRawKeyState(KEY_SHIFT) and GetRawKeyState(KEY_UP)
SetObjectPosition(objects[current].ID,getObjectX(objects[current].ID),getObjectY(objects[current].ID)+moveAmmount,getObjectZ(objects[current].ID))
elseif GetRawKeyState(KEY_UP)
SetObjectPosition(objects[current].ID,getObjectX(objects[current].ID),getObjectY(objects[current].ID),getObjectZ(objects[current].ID)+moveAmmount)
endif
if GetRawKeyState(KEY_LEFT)
SetObjectPosition(objects[current].ID,getObjectX(objects[current].ID)-moveAmmount,getObjectY(objects[current].ID),getObjectZ(objects[current].ID))
endif
if GetRawKeyState(KEY_RIGHT)
SetObjectPosition(objects[current].ID,getObjectX(objects[current].ID)+moveAmmount,getObjectY(objects[current].ID),getObjectZ(objects[current].ID))
endif
if GetRawKeyState(KEY_SHIFT) and GetRawKeyState(KEY_DOWN)
SetObjectPosition(objects[current].ID,getObjectX(objects[current].ID),getObjectY(objects[current].ID)-moveAmmount,getObjectZ(objects[current].ID))
elseif GetRawKeyState(KEY_DOWN)
SetObjectPosition(objects[current].ID,getObjectX(objects[current].ID),getObjectY(objects[current].ID),getObjectZ(objects[current].ID)-moveAmmount)
endif
if GetRawKeyState(KEY_GREATERTHAN)
RotateObjectLocalY(objects[current].ID,rotateAmmount)
endif
if GetRawKeyState(KEY_LESSTHAN)
RotateObjectLocalY(objects[current].ID,-rotateAmmount)
endif
if GetRawKeyPressed(KEY_PLUS)
objects[current].scale=objects[current].scale+scaleAmmount
SetObjectScale(objects[current].ID,objects[current].scale,objects[current].scale,objects[current].scale)
endif
if GetRawKeyPressed(KEY_SUBTRACT)
objects[current].scale=objects[current].scale-scaleAmmount
SetObjectScale(objects[current].ID,objects[current].scale,objects[current].scale,objects[current].scale)
endif
print("Name ="+(objects[current].name))
print("Scale ="+str(objects[current].scale))
print("Angle X#="+str(GetObjectAngleX(objects[current].ID)))
print("Angle Y#="+str(GetObjectAngleY(objects[current].ID)))
print("Angle Z#="+str(GetObjectAngleZ(objects[current].ID)))
print("Pos X#="+str(GetObjectX(objects[current].ID)))
print("Pos Y#="+str(GetObjectY(objects[current].ID)))
print("Pos Z#="+str(GetObjectZ(objects[current].ID)))
endif
Gimbal(camera)
print("CAMERA VALUES")
print("cam x="+str(GetCameraX(1)))
print("cam y="+str(GetCameraY(1)))
print("cam z="+str(GetCameraZ(1)))
print("CAMERA ANGLES")
print("Dolly ("+str(Round(GetObjectAngleX(camera.dolly)))+","+str(Round(GetObjectAngleY(camera.dolly)))+","+str(Round(GetObjectAngleZ(camera.dolly)))+")")
print("Camera ("+str(Round(GetObjectWorldAngleX(camera.camera)))+","+str(Round(GetObjectWorldAngleY(camera.camera)))+","+str(Round(GetObjectWorldAngleZ(camera.camera)))+")")
print("Internal ("+str(Round(camera.angle.x))+","+str(Round(camera.angle.y))+","+str(Round(camera.angle.z))+")")
Print( ScreenFPS() )
Sync()
loop
function saveData(objects as _object[],filename$ as string)
fw = OpenToWrite(filename$)
For num=0 to objects.length
writeline(fw,objects[num].name+" "+objects[num].imageName+" "+str(objects[num].scale)+" "+str(GetObjectAngleX(objects[num].ID))+" "+str(GetObjectAngleY(objects[num].ID))+" "+str(GetObjectAngleZ(objects[num].ID))+" "+str(GetObjectX(objects[num].ID))+" "+str(GetObjectY(objects[num].ID))+" "+str(GetObjectZ(objects[num].ID)))
next num
CloseFile ( fw )
endfunction
function loadObjects(objects ref as _object[])
local myObject as _object
fr=OpenToRead("test.data")
myString$=ReadLine(fr)
while FileEOF(fr)=0
temp$=GetStringToken(myString$," ",1)
myObject.ID=LoadObject(temp$)
myObject.name=temp$
temp$=GetStringToken(myString$," ",2)
myObject.imageID=LoadImage(temp$)
myObject.imageName=temp$
SetObjectImage(myObject.ID,myObject.imageID,0)
//SetObjectScale(myObject.ID,ValFloat(GetStringToken(myString$," ",3)),ValFloat(GetStringToken(myString$," ",3)),ValFloat(GetStringToken(myString$," ",3)))
SetObjectRotation(myObject.ID,ValFloat(GetStringToken(myString$," ",4)),ValFloat(GetStringToken(myString$," ",5)),ValFloat(GetStringToken(myString$," ",6)))
SetObjectPosition(myObject.ID,ValFloat(GetStringToken(myString$," ",7)),ValFloat(GetStringToken(myString$," ",8)),ValFloat(GetStringToken(myString$," ",9)))
objects.insert(myObject):inc current
myString$=ReadLine(fr)
endwhile
closefile(fr)
endfunction
function Gimbal(camera ref as camera)
d as point
v as float
a as float
p as point
dist as float
if GetPointerPressed() = 1
camera.last.x = GetPointerX()
camera.last.y = GetPointerY()
endif
if GetRawMouseRightPressed()
hit=checkCollision()
if hit<>0
camera.offset.x=GetObjectWorldX(hit)
camera.offset.y=GetObjectworldY(hit)
camera.offset.z=GetObjectWorldZ(hit)
else
camera.offset.x=0
camera.offset.y=0
camera.offset.z=0
endif
endif
if GetPointerState() = 1
p.y = GetPointerY() - camera.last.y
inc camera.angle.x, p.y
p.x = GetPointerX() - camera.last.x
inc camera.angle.y, p.x
camera.last.x = GetPointerX()
camera.last.y = GetPointerY()
endif
SetObjectRotation(camera.dolly, camera.angle.x, camera.angle.y, 0)
SetCameraPosition(1, GetObjectWorldX(camera.camera)+camera.offset.x, GetObjectWorldY(camera.camera)+camera.offset.y, GetObjectWorldZ(camera.camera)+camera.offset.z)
SetCameraRotation(1, camera.angle.x, camera.angle.y, 0)
endfunction
function checkCollision()
// get the position of the pointer (mouse)
pointer_x = GetPointerX()
pointer_y = GetPointerY()
// get the x, y and z unit vectors based on the pointer position
unit_x# = Get3DVectorXFromScreen(pointer_x,pointer_y)
unit_y# = Get3DVectorYFromScreen(pointer_x,pointer_y)
unit_z# = Get3DVectorZFromScreen(pointer_x,pointer_y)
// calculate the start of the ray cast, which is the unit vector + the camera position
start_x# = unit_x# + 0
start_y# = unit_y# + 10
start_z# = unit_z# - 20
// 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# + 0
end_y# = 800*unit_y# + 10
end_z# = 800*unit_z# - 20
// determine which object has been hit
object_hit = ObjectRayCast(0,start_x#,start_y#,start_z#,end_x#,end_y#,end_z#)
endfunction object_hit
Keys
F1 load an object and then an image to assign to it
f2 save test.data
L to delete all and load objects as set in test.data
<, > rotate object
+,- scale object
w,a,s,d,shift move camera
Clicking and holding mouse rotates mouse around its position
Right Clicking an Object moves camera to concentrate on that object (ie so it would rotate around that object)
arrow keys ,shift move current object
Function
creates a test.data file that can be later used in your program that can load a series of objects
saving there name, scale, xangle, yangle, zangle, xpos ypos, and zpos
Note: It will save the file test.data in the same directory as the last object loaded
Using the data You could then use this function in your program to load position rotate etc your objects
function loadObjects(objects ref as _object[])
local myObject as _object
fr=OpenToRead("test.data")
myString$=ReadLine(fr)
while FileEOF(fr)=0
temp$=GetStringToken(myString$," ",1)
myObject.ID=LoadObject(temp$)
myObject.name=temp$
temp$=GetStringToken(myString$," ",2)
myObject.imageID=LoadImage(temp$)
myObject.imageName=temp$
SetObjectImage(myObject.ID,myObject.imageID,0)
//SetObjectScale(myObject.ID,ValFloat(GetStringToken(myString$," ",3)),ValFloat(GetStringToken(myString$," ",3)),ValFloat(GetStringToken(myString$," ",3)))
SetObjectRotation(myObject.ID,ValFloat(GetStringToken(myString$," ",4)),ValFloat(GetStringToken(myString$," ",5)),ValFloat(GetStringToken(myString$," ",6)))
SetObjectPosition(myObject.ID,ValFloat(GetStringToken(myString$," ",7)),ValFloat(GetStringToken(myString$," ",8)),ValFloat(GetStringToken(myString$," ",9)))
objects.insert(myObject):inc current
myString$=ReadLine(fr)
endwhile
closefile(fr)
endfunction
fubar