Cheers Guy
Okay, got the core math done, just need to refine this further... but I'm thinking the blender-ish approach Chris is talking about might be better. I'll have to compare the two when this is finished to see which looks better considering I'm actually already using that method.
Here's where I'm at so far, as I said, needs refinement. Hold RMB to control camera, WASD and Mouse look:
sync on : sync rate 75
autocam off : set text font "Tahoma" : set text size 13
color backdrop rgb(92,92,92)
position camera -15,15,-20
point camera 0,0,0
_vMousePos = new vector3()
_vMouseVelocity = new vector3()
_vLastCamPos = new vector3()
_vCamPos = new vector3(-20,15,20)
_vCamAng = new vector3(camera angle x(),camera angle y(),camera angle z())
cameraAngX# = camera angle x()
cameraAngY# = camera angle y()
global _oldMouseclick as byte
global _mouseclick as byte
global _rayP0 as dword
global _rayP1 as dword
global _PlanePosition as dword
global _PlaneNormal as dword
global _Position as dword
global _LastPosition as dword
global _Displacement as dword
global _intersectPoint as dword
global ZERO_VECTOR3 as dword
global _pickVector as dword
ZERO_VECTOR3 = new vector3()
_intersectPoint = new vector3()
_rayP0 = new vector3()
_rayP1 = new vector3()
_PlanePosition = new vector3()
_PlaneNormal = new vector3(0,1,0)
_Position = new vector3()
_LastPosition = new vector3()
_Displacement = new vector3()
_pickVector = new vector3()
_transConstraint = new vector3()
#constant TRANS_X 0
#constant TRANS_Y 1
#constant TRANS_Z 2
global _gizmoTransMethod as integer = -1
global _gizmoLastPosition as dword
global _gizmoPosition as dword
global _gizmoAngle as dword
global _gizmoScale as float
_gizmoLastPosition = new vector3(0,0,0)
_gizmoPosition = new vector3(0,0,0)
_gizmoAngle = new vector3(0,0,0)
_gizmoScale = 1.3
_gizmoCentre = find free object()
make object cube _gizmoCentre, 1
set object diffuse _gizmoCentre, rgb(0, 128, 192)
set object emissive _gizmoCentre, rgb(0, 128, 192)
SC_setupObject _gizmoCentre, 0, 2
SC_allowObjectScaling _gizmoCentre
_gizmoX = find free object()
make object box _gizmoX,15,1,1
set object diffuse _gizmoX, rgb(255, 0, 0)
set object emissive _gizmoX, rgb(255, 0, 0)
offset limb _gizmoX,0,8,0,0
SC_setupObject _gizmoX, 0, 2
SC_allowObjectScaling _gizmoX
_gizmoY = find free object()
make object box _gizmoY,1,15,1
set object diffuse _gizmoY, rgb(0, 255, 0)
set object emissive _gizmoY, rgb(0, 255, 0)
offset limb _gizmoY,0,0,8,0
SC_setupObject _gizmoY, 0, 2
SC_allowObjectScaling _gizmoY
_gizmoZ = find free object()
make object box _gizmoZ,1,1,15
set object diffuse _gizmoZ, rgb(0, 0, 255)
set object emissive _gizmoZ, rgb(0, 0, 255)
offset limb _gizmoZ,0,0,0,8
SC_setupObject _gizmoZ, 0, 2
SC_allowObjectScaling _gizmoZ
do
// update mouse and input
_oldMouseclick = _mouseclick
_mouseclick = mouseclick()
set vector3 _vMousePos, mousex(), mousey(), mousez()
set vector3 _vMouseVelocity, mousemovex(), mousemovey(), mousemovez()
// update camera
if mouseclick() = 2
hide mouse
cameraAngX# = clamp(cameraAngX# + (y vector3(_vMouseVelocity) * .24),-89.9,89.9)
cameraAngY# = wrapvalue(cameraAngY# + (x vector3(_vMouseVelocity) *.24))
rotate camera cameraAngX#, cameraAngY#, 0
if (upkey() || keystate(17)) then move camera 0.24
if (downkey() || keystate(31)) then move camera -0.24
if (leftkey() || keystate(30)) then move camera right -0.24
if (rightkey() || keystate(32)) then move camera right 0.24
else
show mouse
endif
copy vector3 _vLastCamPos, _vCamPos
set vector3 _vCamPos,camera position x(),camera position y(),camera position z()
set vector3 _vCamAng,camera angle x(),camera angle y(),camera angle z()
if _gizmoTransMethod = 0
generate3DRay( mousex(), mousey(), 3000.0 )
// this needs changing
if SC_rayCast(0,camera position x(),camera position y(),camera position z(),x vector3(_rayP1),y vector3(_rayP1),z vector3(_rayP1),0)
hit = SC_getObjectHit()
set vector3 _pickVector, SC_getStaticCollisionX(), SC_getStaticCollisionY(), SC_getStaticCollisionZ()
if _mouseclick = 1 and _oldMouseclick <> _mouseclick
Initialize( mousex(), mousey(), _pickVector )
copy vector3 _gizmoLastPosition, _gizmoPosition
if hit = _gizmoX
set vector3 _transConstraint, 1,0,0
set vector3 _PlaneNormal,0,1,0
endif
if hit = _gizmoY
set vector3 _transConstraint, 0,1,0
set vector3 _PlaneNormal,1,0,0
endif
if hit = _gizmoZ
set vector3 _transConstraint, 0,0,1
set vector3 _PlaneNormal,0,1,0
endif
_gizmoTransMethod = 1
endif
endif
endif
if _mouseclick = 0
_gizmoTransMethod = 0
endif
if _mouseclick = 1 and _oldMouseclick = _mouseclick and _gizmoTransMethod = 1
Update( mousex(), mousey() )
scaleVector3ByVector( _Displacement, _transConstraint )
add vector3 _gizmoPosition, _gizmoPosition, _Displacement
position object at vector3 _gizmoCentre, _gizmoPosition
position object at vector3 _gizmoX, _gizmoPosition
position object at vector3 _gizmoY, _gizmoPosition
position object at vector3 _gizmoZ, _gizmoPosition
SC_updateObject _gizmoCentre
SC_updateObject _gizmoX
SC_updateObject _gizmoY
SC_updateObject _gizmoZ
endif
if vector3NotEqual( _gizmoPosition, _gizmoLastPosition ) || vector3NotEqual( _vCamPos, _vLastCamPos )
vTemp = new vector3()
vCamPos = new vector3(camera position x(),camera position y(),camera position z())
subtract vector3 vTemp, vCamPos, _gizmoPosition
dist# = length vector3(vTemp)*_gizmoScale
delete vector3 vTemp : delete vector3 vCamPos
scale object _gizmoCentre,dist#,dist#,dist#
scale object _gizmoX,dist#,dist#,dist#
scale object _gizmoY,dist#,dist#,dist#
scale object _gizmoZ,dist#,dist#,dist#
SC_updateObject _gizmoCentre
SC_updateObject _gizmoX
SC_updateObject _gizmoY
SC_updateObject _gizmoZ
copy vector3 _gizmoLastPosition, _gizmoPosition
endif
i = 40
printVector3( 40, i, _vCamPos, "Camera Pos - " )
inc i,14
printVector3( 40, i, _vCamAng, "Camera Ang - " )
inc i,32
printVector3( 40, i, _PlanePosition, "Plane Position - " )
inc i,14
printVector3( 40, i, _PlaneNormal, "Plane Normal - " )
inc i,32
printVector3( 40, i, _Displacement, "Displacement - " )
sync
loop
function scaleVector3ByVector( v0 as dword, v1 as dword )
x# = x vector3(v0) * x vector3(v1)
y# = y vector3(v0) * y vector3(v1)
z# = z vector3(v0) * z vector3(v1)
set vector3 v0, x#, y#, z#
endfunction
function vector3NotEqual( v0 as dword, v1 as dword )
if x vector3(v0) <> x vector3(v1) then exitfunction 1
if y vector3(v0) <> y vector3(v1) then exitfunction 1
if z vector3(v0) <> z vector3(v1) then exitfunction 1
endfunction 0
function Initialize( x, y, planePos as dword )
generate3DRay( x, y, 3000.0 )
copy vector3 _PlanePosition, planePos
copy vector3 _Position, planePos
copy vector3 _LastPosition, _Position
copy vector3 _Displacement, ZERO_VECTOR3
endfunction
function Update( x, y )
generate3DRay( x, y, 3000.0 )
intersects( _PlaneNormal, _PlanePosition, _rayP0, _rayP1 )
// < work out constraints should go here >
copy vector3 _Position, _intersectPoint
copy vector3 _PlanePosition, _Position
subtract vector3 _Displacement, _Position, _LastPosition
copy vector3 _LastPosition, _Position
endfunction
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 _rayP0, 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 _rayP1, 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
function printVector3( x, y, v as dword, ext as string )
text x, y, ext+" "+str$(x vector3(v),2)+", "+str$(y vector3(v),2)+", "+str$(z vector3(v),2)
endfunction
I'll sort out the constraints better and handle special cases for errors with intersection.
Note: I never knew offset limb doesn't scale when the object scales, hence why they disappear when the offset limb points go outs the camera. I'll change all this anyway
"Get in the Van!" - Van B