I swear this is something to do with display modes Fullscreen vs Windowed Fullscreen and for some people it throws an error!
Here's the code instead, requires IanM's Matrix plugin to run (taken the gui out coz it uses advanced2d)
`set display mode display width(), display height(), display depth()
randomize timer()
gosub declare_math
gosub declare_input
gosub declare_viewportCamera
gosub declare_raycasting
sync on : sync rate 60
set text font "Tahoma" : set text size 13
autocam off : color backdrop rgb(64,64,64)
position camera -64,64,-64
point camera 0,0,0
create3dViewportGrid()
// so lightning isn't destoryed when scaling
set normalization on
do
update_input()
update_viewportCamera()
// needs a little editing, just want it to work first
`if not debugGUI_overGUI()
generate3DRay( _mouse.position.x, _mouse.position.y, 3000.0 )
// hightlight grid point
if _mouseOnjectDrag = 0
set vector3 _planeNormal,0,1,0
set vector3 _planePos,0,0,0
intersects( _planeNormal, _planePos, _rayFrom, _rayTo )
snapVectorToGridXZ( _intersectPoint, 8.0 )
positionViewportHighlight( _intersectPoint )
if _mouse.click = 1 and _mouse.oldclick <> _mouse.click
copy vector3 _lastIntersect, _intersectPoint
newObjectId = find free object()
make object cube newObjectId,1
hide object newObjectId
color object newObjectId, rgb(rnd(255),rnd(255),rnd(255))
_mouseOnjectDrag = 1
dragType = 1
endif
endif
if _mouseOnjectDrag = 1
select dragType
case 1 // XZ plane
if _mouse.click = 0 and _mouse.oldclick <> _mouse.click
set vector3 _planeNormal,0,0,1
copy vector3 _planePos, _intersectPoint
copy vector3 _lastIntersect, _intersectPoint
dragType = 2
endif
if _mouse.click = 1 and _mouse.oldclick = _mouse.click
intersects( _planeNormal, _planePos, _rayFrom, _rayTo )
snapVectorToGridXZ( _intersectPoint, 8.0 )
xScale# = x vector3(_lastIntersect)-x vector3(_intersectPoint)
zScale# = z vector3(_lastIntersect)-z vector3(_intersectPoint)
x# = x vector3(_lastIntersect)-(xScale#/2)
z# = z vector3(_lastIntersect)-(zScale#/2)
show object newObjectID
position object newObjectId,x#,0,z#
scale object newObjectId, abs(xScale#)*100.0.5,0,abs(zScale#)*100.0
endif
endcase
case 2 // Y plane
if _mouse.click = 1 and _mouse.oldclick <> _mouse.click
dragType = 0
_mouseOnjectDrag = 0
else
intersects( _planeNormal, _planePos, _rayFrom, _rayTo )
snapVectorToGridY( _intersectPoint, 8.0 )
xScale# = object scale x(newObjectId)
yScale# = y vector3(_lastIntersect)-y vector3(_intersectPoint)
zScale# = object scale z(newObjectId)
x# = object position x(newObjectId)
y# = y vector3(_lastIntersect)-(yScale#/2)
z# = object position z(newObjectId)
position object newObjectId,x#,y#,z#
scale object newObjectId,xScale#,abs(yScale#)*100.0,zScale#
endif
endcase
endselect
endif
`endif
i = 12
text 0,i*0,"Hold right click to rotate camera and WSAD to move"
text 0,i*1,"Mousewheel to zoom"
text 0,i*2,"Hold mousewheel Click to drag camera"
text 0,i*4,"To Create Objects:"
text 0,i*5," 1. hold left click and drag for the XZ size"
text 0,i*6," 2. release left click then drag up/down for the Y size"
text 0,i*7," 3. release mouse to finish"
sleep 1
sync
loop
// math class
type rect2
x, y, w, h
endtype
type point2
x, y
endtype
type point3
x, y, z
endtype
type point4
x, y, z, w
endtype
type vector2
x as float
y as float
endtype
type vector3
x as float
y as float
z as float
endtype
type vector4
x as float
y as float
z as float
w as float
endtype
type uniformInt
_min, _max
endtype
type uniformFloat
_min as float
_max as float
endtype
type uniformVector3
x as uniformFloat
y as uniformFloat
z as uniformFloat
endtype
declare_math:
global _point3 as point3
global _vector3 as vector3
return
function setPoint3( x, y, z )
_point3.x = x : _point3.y = y : _point3.z = z
endfunction
function setVector3( x as float, y as float, z as float )
_vector3.x = x : _vector3.y = y : _vector3.z = z
endfunction
// mouse
type mouse
position as point3
oldPosition as point3
velocity as point3
oldclick, click
endtype
declare_input:
global _mouse as mouse
global _left
global _right
global _forward
global _backward
return
function update_input()
_mouse.oldclick = _mouse.click
_mouse.click = mouseclick()
setPoint3( mousex(), mousey(), mousez() ) : _mouse.position = _point3
if _mouse.click > 0 and _mouse.oldclick <> _mouse.click
setPoint3( mousex(), mousey(), mousez() ) : _mouse.oldPosition = _point3
endif
if _mouse.click = 0 and _mouse.oldclick = 2
setPoint3( 0,0,0 ) : _mouse.velocity = _point3
endif
percentOfNew# = 1.0 / 10.0
percentOfOld# = 1.0 - percentOfNew#
_mouse.velocity.x = _mouse.velocity.x * percentOfOld# + mousemovex() * percentOfNew#
_mouse.velocity.y = _mouse.velocity.y * percentOfOld# + mousemovey() * percentOfNew#
_mouse.velocity.z = _mouse.velocity.z * percentOfOld# + mousemovez() * percentOfNew#
_left = keystate(30) || leftkey()
_right = keystate(32) || rightkey()
_forward = keystate(17) || upkey()
_backward = keystate(31) || downkey()
endfunction
// camera class
type camera
position as vector3
angle as vector3
endtype
declare_viewportCamera:
global _camera as camera
return
function update_viewportCamera()
local x as float : local y as float : local z as float
// pop variables with camera properties
view = new matrix4() : view matrix4 view
null = inverse matrix4( view, view )
look = new vector3( get matrix4 element(view, 8),get matrix4 element(view, 9),get matrix4 element(view, 10) )
up = new vector3( get matrix4 element(view, 4),get matrix4 element(view, 5),get matrix4 element(view, 6) )
right = new vector3( get matrix4 element(view, 0),get matrix4 element(view, 1),get matrix4 element(view, 2) )
pos = new vector3( camera position x(), camera position y(), camera position z() )
ang = new vector3( camera angle x(), camera angle y(), camera angle z() )
// mouse drag camera
if _mouse.click = 4
scale vector3 up, up, (_mouse.velocity.y *.25)
add vector3 pos, pos, up
scale vector3 right, right, (_mouse.velocity.x *.25)
subtract vector3 pos, pos, right
position mouse _mouse.oldPosition.x, _mouse.oldPosition.y
else
// camera rotation, movement
if _mouse.click = 2
x = clamp(x vector3(ang) + (_mouse.velocity.y * .25),-90.0,90.0)
y = y vector3(ang) + (_mouse.velocity.x * .25)
z = 0.0
set vector3 ang, x, y, z
scale vector3 look, look, 3.5 * (_backward-_forward)
subtract vector3 pos, pos, look
scale vector3 right, right, 3.5 * (_right-_left)
add vector3 pos, pos, right
position mouse _mouse.oldPosition.x, _mouse.oldPosition.y
endif
// mouse wheel zooming
scale vector3 look, look, (_mouse.velocity.z *.25)
add vector3 pos, pos, look
endif
// update camera
position camera at vector3 0, pos
rotate camera to vector3 0, ang
// clear math
delete vector4 view : delete vector3 look : delete vector3 up : delete vector3 right : delete vector3 pos : delete vector3 ang
endfunction
// viewport
function create3dViewportGrid()
local p0 as dword : local p1 as dword
global _gridSize as float : global _gridCount as float
global dim _3dViewportGrid() as integer
p0 = new vector3() : p1 = new vector3()
_gridSize = 128.0 : _gridCount = 16
for r = 0 to _gridCount
set vector3 p0, -(_gridSize*.5), 0.0, (r*(_gridSize/_gridCount))-(_gridSize*.5)
set vector3 p1, (_gridSize*.5), 0.0, (r*(_gridSize/_gridCount))-(_gridSize*.5)
array insert at bottom _3dViewportGrid()
if r = _gridCount/2
_3dViewportGrid() = createLineObject( p0, p1, rgb(255,0,0) )
else
_3dViewportGrid() = createLineObject( p0, p1, rgb(32,32,32) )
endif
next
for c = 0 to _gridCount
set vector3 p0, (c*(_gridSize/_gridCount))-(_gridSize*.5), 0.0, -(_gridSize*.5)
set vector3 p1, (c*(_gridSize/_gridCount))-(_gridSize*.5), 0.0, (_gridSize*.5)
array insert at bottom _3dViewportGrid()
if c = _gridCount/2
_3dViewportGrid() = createLineObject( p0, p1, rgb(255,0,0) )
else
_3dViewportGrid() = createLineObject( p0, p1, rgb(32,32,32) )
endif
next
set vector3 p0,0,0,0 : set vector3 p1,16,0,0
array insert at bottom _3dViewportGrid()
_3dViewportGrid() = createLineObject( p0, p1, rgb(0, 255, 255) )
disable object zdepth _3dViewportGrid()
set vector3 p0,0,0,0 : set vector3 p1,0,0,16
array insert at bottom _3dViewportGrid()
_3dViewportGrid() = createLineObject( p0, p1, rgb(0, 255, 255) )
disable object zdepth _3dViewportGrid()
delete vector3 p0 : delete vector3 p1
endfunction
function positionViewportHighlight( p as dword )
local x as float : local y as float : local z as float
c = array count(_3dViewportGrid())
x = x vector3(p) - 8 : y = y vector3(p) : z = z vector3(p)
position object _3dViewportGrid(c-1),x,y,z
x = x vector3(p) : y = y vector3(p) : z = z vector3(p)-8
position object _3dViewportGrid(c),x,y,z
endfunction
function snapVectorToGridXZ( v as dword, size as float )
local x as float : local y as float : local z as float
local d0 as float : local d1 as float
x = floor(x vector3(v) / size) * size
y = 0
z = floor(z vector3(v) / size) * size
d0 = abs(x vector3(v)-x) : d1 = abs(x vector3(v)-(x+size))
if d0 > d1 then inc x, size
d0 = abs(z vector3(v)-z) : d1 = abs(z vector3(v)-(z+size))
if d0 > d1 then inc z, size
set vector3 v, x, y, z
endfunction
function snapVectorToGridY( v as dword, size as float )
local x as float : local y as float : local z as float
local d0 as float : local d1 as float
x = x vector3(v)
y = floor(y vector3(v) / size) * size
z = z vector3(v)
d0 = abs(y vector3(v)-y) : d1 = abs(y vector3(v)-(y+size))
if d0 > d1 then inc y, size
set vector3 v, x, y, z
endfunction
// misc
function createLineObject( p0 as dword, p1 as dword, color as dword )
local v as dword : local d as float
v = new vector3() : subtract vector3 v, p0, p1
d = length vector3(v) : delete vector3 v
id = find free object()
make object triangle id,0,0,0 ,0,0,0 ,0,0,1
position object at vector3 id, p0
point object at vector3 id, p1
scale object id,0,0,100.0*d
set object diffuse id, color
set object emissive id, color
set object wireframe id, 1
endfunction id
// ray casting
// admittedly we want to ray cast to the plane of distance which pick screen doesn't, so this is just a cheap ray
declare_raycasting:
global _rayFrom as dword : global _rayTo as dword
_rayFrom = new vector3() : _rayTo = new vector3()
global _intersectPoint as dword : global _lastIntersect as dword
_intersectPoint = new vector3() : _lastIntersect = new vector3()
global _planeNormal as dword : global _planePos as dword
_planeNormal = new vector3() : _planePos = new vector3()
global _ZERO_VECTOR3 as dword
_ZERO_VECTOR3 = new vector3()
return
function generate3DRay( x, y, dist as float )
local nx as float : local ny as float : local nz as float
// the near ray needs changing
set vector3 _rayFrom, camera position x(),camera position y(),camera position z()
pick screen x, y, dist/2
nx = (get pick vector x() * 2) + camera position x()
ny = (get pick vector y() * 2) + camera position y()
nz = (get pick vector z() * 2) + camera position z()
set vector3 _rayTo, nx, ny, nz
endfunction
function intersects( normal as dword, pos as dword, p0 as dword, p1 as dword )
local d as float : local n as float : local s as float
local u as dword : local w as dword
copy vector3 _intersectPoint, _ZERO_VECTOR3
u = new vector3() : w = new vector3()
subtract vector3 u, p1, p0
subtract vector3 w, p0, pos
d = dot product vector3( normal, u )
n = -dot product vector3( normal, w )
// segment is parallel to plane
if abs( d ) < 0
// segment lies in plane
if n = 0
exitfunction 2
else
// no intersection
exitfunction 0
endif
endif
s = n / d
if (s < 0 || s > 1)
// no intersection
exitfunction 0
endif
// compute segment intersect point
scale vector3 u, u, s : add vector3 _intersectPoint, p0, u
delete vector3 u : delete vector3 w
endfunction 1
Note: I'm just getting everything to work, so it's alittle unoptimized.
"Get in the Van!" - Van B