|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
import math
|
|
|
|
|
from panda3d.core import BitMask32, Mat4, NodePath, Point3, VBase3, Vec3, Vec4, rad2Deg
|
|
|
|
|
from direct.showbase.DirectObject import DirectObject
|
|
|
|
|
from direct.showbase import ShowBaseGlobal
|
|
|
|
|
from .DirectUtil import CLAMP, useDirectRenderStyle
|
|
|
|
|
from .DirectGeometry import getCrankAngle, getScreenXY
|
|
|
|
|
from . import DirectGlobals as DG
|
|
|
|
@ -26,7 +27,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.orthoViewRoll = 0.0
|
|
|
|
|
self.lastView = 0
|
|
|
|
|
self.coa = Point3(0, 100, 0)
|
|
|
|
|
self.coaMarker = base.loader.loadModel('models/misc/sphere')
|
|
|
|
|
self.coaMarker = ShowBaseGlobal.loader.loadModel('models/misc/sphere')
|
|
|
|
|
self.coaMarker.setName('DirectCameraCOAMarker')
|
|
|
|
|
self.coaMarker.setTransparency(1)
|
|
|
|
|
self.coaMarker.setColor(1, 0, 0, 0)
|
|
|
|
@ -37,8 +38,8 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.fLockCOA = 0
|
|
|
|
|
self.nullHitPointCount = 0
|
|
|
|
|
self.cqEntries = []
|
|
|
|
|
self.coaMarkerRef = base.direct.group.attachNewNode('coaMarkerRef')
|
|
|
|
|
self.camManipRef = base.direct.group.attachNewNode('camManipRef')
|
|
|
|
|
self.coaMarkerRef = ShowBaseGlobal.direct.group.attachNewNode('coaMarkerRef')
|
|
|
|
|
self.camManipRef = ShowBaseGlobal.direct.group.attachNewNode('camManipRef')
|
|
|
|
|
self.switchDirBelowZero = True
|
|
|
|
|
self.manipulateCameraTask = None
|
|
|
|
|
self.manipulateCameraInterval = None
|
|
|
|
@ -112,11 +113,6 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.perspCollPlane2 = None # [gjeon] used for new LE
|
|
|
|
|
|
|
|
|
|
def toggleMarkerVis(self):
|
|
|
|
|
## if base.direct.cameraControl.coaMarker.isHidden():
|
|
|
|
|
## base.direct.cameraControl.coaMarker.show()
|
|
|
|
|
## else:
|
|
|
|
|
## base.direct.cameraControl.coaMarker.hide()
|
|
|
|
|
|
|
|
|
|
if self.coaMarker.isHidden():
|
|
|
|
|
self.coaMarker.show()
|
|
|
|
|
else:
|
|
|
|
@ -132,11 +128,14 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
# Hide the marker for this kind of motion
|
|
|
|
|
self.coaMarker.hide()
|
|
|
|
|
# Record time of start of mouse interaction
|
|
|
|
|
base = ShowBaseGlobal.base
|
|
|
|
|
self.startT = base.clock.getFrameTime()
|
|
|
|
|
self.startF = base.clock.getFrameCount()
|
|
|
|
|
# If the cam is orthogonal, spawn differentTask
|
|
|
|
|
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView and\
|
|
|
|
|
base.direct.camera.getName() != 'persp':
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
if hasattr(direct, "manipulationControl") and \
|
|
|
|
|
direct.manipulationControl.fMultiView and \
|
|
|
|
|
direct.camera.getName() != 'persp':
|
|
|
|
|
self.spawnOrthoZoom()
|
|
|
|
|
else:
|
|
|
|
|
# Start manipulation
|
|
|
|
@ -167,7 +166,9 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
|
|
|
|
|
def mouseFlyStart(self, modifiers):
|
|
|
|
|
# Record undo point
|
|
|
|
|
# base.direct.pushUndo([base.direct.camera]) # Wasteful use of undo
|
|
|
|
|
base = ShowBaseGlobal.base
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
#direct.pushUndo([direct.camera]) # Wasteful use of undo
|
|
|
|
|
if self.useMayaCamControls and modifiers == 4: # alt is down, use maya controls
|
|
|
|
|
# Hide the marker for this kind of motion
|
|
|
|
|
self.coaMarker.hide()
|
|
|
|
@ -176,15 +177,16 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.startF = base.clock.getFrameCount()
|
|
|
|
|
# Start manipulation
|
|
|
|
|
# If the cam is orthogonal, spawn differentTask
|
|
|
|
|
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView and\
|
|
|
|
|
base.direct.camera.getName() != 'persp':
|
|
|
|
|
if hasattr(direct, "manipulationControl") and \
|
|
|
|
|
direct.manipulationControl.fMultiView and \
|
|
|
|
|
direct.camera.getName() != 'persp':
|
|
|
|
|
self.spawnOrthoTranslate()
|
|
|
|
|
else:
|
|
|
|
|
self.spawnXZTranslate()
|
|
|
|
|
self.altDown = 1
|
|
|
|
|
elif not self.useMayaCamControls:
|
|
|
|
|
# Where are we in the display region?
|
|
|
|
|
if ((abs(base.direct.dr.mouseX) < 0.9) and (abs(base.direct.dr.mouseY) < 0.9)):
|
|
|
|
|
if abs(direct.dr.mouseX) < 0.9 and abs(direct.dr.mouseY) < 0.9:
|
|
|
|
|
# MOUSE IS IN CENTRAL REGION
|
|
|
|
|
# Hide the marker for this kind of motion
|
|
|
|
|
self.coaMarker.hide()
|
|
|
|
@ -194,19 +196,18 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
# Start manipulation
|
|
|
|
|
self.spawnXZTranslateOrHPanYZoom()
|
|
|
|
|
# END MOUSE IN CENTRAL REGION
|
|
|
|
|
elif abs(direct.dr.mouseX) > 0.9 and abs(direct.dr.mouseY) > 0.9:
|
|
|
|
|
# Mouse is in corners, spawn roll task
|
|
|
|
|
self.spawnMouseRollTask()
|
|
|
|
|
else:
|
|
|
|
|
if ((abs(base.direct.dr.mouseX) > 0.9) and
|
|
|
|
|
(abs(base.direct.dr.mouseY) > 0.9)):
|
|
|
|
|
# Mouse is in corners, spawn roll task
|
|
|
|
|
self.spawnMouseRollTask()
|
|
|
|
|
else:
|
|
|
|
|
# Mouse is in outer frame, spawn mouseRotateTask
|
|
|
|
|
self.spawnMouseRotateTask()
|
|
|
|
|
# Mouse is in outer frame, spawn mouseRotateTask
|
|
|
|
|
self.spawnMouseRotateTask()
|
|
|
|
|
if not modifiers == 4:
|
|
|
|
|
self.altDown = 0
|
|
|
|
|
|
|
|
|
|
def mouseFlyStop(self):
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
base = ShowBaseGlobal.base
|
|
|
|
|
stopT = base.clock.getFrameTime()
|
|
|
|
|
deltaT = stopT - self.startT
|
|
|
|
|
stopF = base.clock.getFrameCount()
|
|
|
|
@ -215,7 +216,8 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
# if not self.useMayaCamControls and (deltaT <= 0.25) or (deltaF <= 1):
|
|
|
|
|
|
|
|
|
|
# Do this when not trying to manipulate camera
|
|
|
|
|
if not self.altDown and len(base.direct.selected.getSelectedAsList()) == 0:
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
if not self.altDown and len(direct.selected.getSelectedAsList()) == 0:
|
|
|
|
|
# Check for a hit point based on
|
|
|
|
|
# current mouse position
|
|
|
|
|
# Allow intersection with unpickable objects
|
|
|
|
@ -224,13 +226,13 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
skipFlags = DG.SKIP_HIDDEN | DG.SKIP_BACKFACE
|
|
|
|
|
# Skip camera (and its children), unless control key is pressed
|
|
|
|
|
skipFlags |= DG.SKIP_CAMERA * (1 - base.getControl())
|
|
|
|
|
self.computeCOA(base.direct.iRay.pickGeom(skipFlags = skipFlags))
|
|
|
|
|
self.computeCOA(direct.iRay.pickGeom(skipFlags = skipFlags))
|
|
|
|
|
# Record reference point
|
|
|
|
|
self.coaMarkerRef.setPosHprScale(base.cam, 0, 0, 0, 0, 0, 0, 1, 1, 1)
|
|
|
|
|
# Record entries
|
|
|
|
|
self.cqEntries = []
|
|
|
|
|
for i in range(base.direct.iRay.getNumEntries()):
|
|
|
|
|
self.cqEntries.append(base.direct.iRay.getEntry(i))
|
|
|
|
|
for i in range(direct.iRay.getNumEntries()):
|
|
|
|
|
self.cqEntries.append(direct.iRay.getEntry(i))
|
|
|
|
|
# Show the marker
|
|
|
|
|
self.coaMarker.show()
|
|
|
|
|
# Resize it
|
|
|
|
@ -251,7 +253,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
# Spawn the new task
|
|
|
|
|
t = Task.Task(self.XZTranslateOrHPanYZoomTask)
|
|
|
|
|
# For HPanYZoom
|
|
|
|
|
t.zoomSF = Vec3(self.coaMarker.getPos(base.direct.camera)).length()
|
|
|
|
|
t.zoomSF = Vec3(self.coaMarker.getPos(ShowBaseGlobal.direct.camera)).length()
|
|
|
|
|
self.__startManipulateCamera(task = t)
|
|
|
|
|
|
|
|
|
|
def spawnXZTranslateOrHPPan(self):
|
|
|
|
@ -277,7 +279,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
# Spawn new task
|
|
|
|
|
t = Task.Task(self.HPanYZoomTask)
|
|
|
|
|
t.zoomSF = Vec3(self.coaMarker.getPos(base.direct.camera)).length()
|
|
|
|
|
t.zoomSF = Vec3(self.coaMarker.getPos(ShowBaseGlobal.direct.camera)).length()
|
|
|
|
|
self.__startManipulateCamera(task = t)
|
|
|
|
|
|
|
|
|
|
def spawnOrthoZoom(self):
|
|
|
|
@ -294,13 +296,13 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.__startManipulateCamera(func = self.HPPanTask)
|
|
|
|
|
|
|
|
|
|
def XZTranslateOrHPanYZoomTask(self, state):
|
|
|
|
|
if base.direct.fShift:
|
|
|
|
|
if ShowBaseGlobal.direct.fShift:
|
|
|
|
|
return self.XZTranslateTask(state)
|
|
|
|
|
else:
|
|
|
|
|
return self.HPanYZoomTask(state)
|
|
|
|
|
|
|
|
|
|
def XZTranslateOrHPPanTask(self, state):
|
|
|
|
|
if base.direct.fShift:
|
|
|
|
|
if ShowBaseGlobal.direct.fShift:
|
|
|
|
|
# Panning action
|
|
|
|
|
return self.HPPanTask(state)
|
|
|
|
|
else:
|
|
|
|
@ -308,43 +310,46 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
return self.XZTranslateTask(state)
|
|
|
|
|
|
|
|
|
|
def XZTranslateTask(self, state):
|
|
|
|
|
coaDist = Vec3(self.coaMarker.getPos(base.direct.camera)).length()
|
|
|
|
|
xlateSF = coaDist / base.direct.dr.near
|
|
|
|
|
base.direct.camera.setPos(base.direct.camera,
|
|
|
|
|
(-0.5 * base.direct.dr.mouseDeltaX *
|
|
|
|
|
base.direct.dr.nearWidth *
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
coaDist = Vec3(self.coaMarker.getPos(direct.camera)).length()
|
|
|
|
|
xlateSF = coaDist / direct.dr.near
|
|
|
|
|
direct.camera.setPos(direct.camera,
|
|
|
|
|
(-0.5 * direct.dr.mouseDeltaX *
|
|
|
|
|
direct.dr.nearWidth *
|
|
|
|
|
xlateSF),
|
|
|
|
|
0.0,
|
|
|
|
|
(-0.5 * base.direct.dr.mouseDeltaY *
|
|
|
|
|
base.direct.dr.nearHeight *
|
|
|
|
|
(-0.5 * direct.dr.mouseDeltaY *
|
|
|
|
|
direct.dr.nearHeight *
|
|
|
|
|
xlateSF))
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
|
|
def OrthoTranslateTask(self, state):
|
|
|
|
|
# create ray from the camera to detect 3d position
|
|
|
|
|
iRay = SelectionRay(base.direct.camera)
|
|
|
|
|
iRay.collider.setFromLens(base.direct.camNode, base.direct.dr.mouseX, base.direct.dr.mouseY)
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
iRay = SelectionRay(direct.camera)
|
|
|
|
|
iRay.collider.setFromLens(direct.camNode, direct.dr.mouseX, direct.dr.mouseY)
|
|
|
|
|
#iRay.collideWithBitMask(1)
|
|
|
|
|
iRay.collideWithBitMask(BitMask32.bit(21))
|
|
|
|
|
iRay.ct.traverse(base.direct.grid)
|
|
|
|
|
iRay.ct.traverse(direct.grid)
|
|
|
|
|
|
|
|
|
|
entry = iRay.getEntry(0)
|
|
|
|
|
hitPt = entry.getSurfacePoint(entry.getFromNodePath())
|
|
|
|
|
iRay.collisionNodePath.removeNode()
|
|
|
|
|
del iRay
|
|
|
|
|
if hasattr(state, 'prevPt'):
|
|
|
|
|
base.direct.camera.setPos(base.direct.camera, (state.prevPt - hitPt))
|
|
|
|
|
direct.camera.setPos(direct.camera, (state.prevPt - hitPt))
|
|
|
|
|
state.prevPt = hitPt
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
|
|
def HPanYZoomTask(self, state):
|
|
|
|
|
# If the cam is orthogonal, don't rotate or zoom.
|
|
|
|
|
if (hasattr(base.direct.cam.node(), "getLens") and
|
|
|
|
|
base.direct.cam.node().getLens().__class__.__name__ == "OrthographicLens"):
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
if (hasattr(direct.cam.node(), "getLens") and
|
|
|
|
|
direct.cam.node().getLens().__class__.__name__ == "OrthographicLens"):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if base.direct.fControl:
|
|
|
|
|
moveDir = Vec3(self.coaMarker.getPos(base.direct.camera))
|
|
|
|
|
if direct.fControl:
|
|
|
|
|
moveDir = Vec3(self.coaMarker.getPos(direct.camera))
|
|
|
|
|
# If marker is behind camera invert vector
|
|
|
|
|
if moveDir[1] < 0.0:
|
|
|
|
|
moveDir.assign(moveDir * -1)
|
|
|
|
@ -353,18 +358,18 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
moveDir = Vec3(Y_AXIS)
|
|
|
|
|
|
|
|
|
|
if self.useMayaCamControls: # use maya controls
|
|
|
|
|
moveDir.assign(moveDir * ((base.direct.dr.mouseDeltaX -1.0 * base.direct.dr.mouseDeltaY)
|
|
|
|
|
moveDir.assign(moveDir * ((direct.dr.mouseDeltaX -1.0 * direct.dr.mouseDeltaY)
|
|
|
|
|
* state.zoomSF))
|
|
|
|
|
hVal = 0.0
|
|
|
|
|
else:
|
|
|
|
|
moveDir.assign(moveDir * (-1.0 * base.direct.dr.mouseDeltaY *
|
|
|
|
|
moveDir.assign(moveDir * (-1.0 * direct.dr.mouseDeltaY *
|
|
|
|
|
state.zoomSF))
|
|
|
|
|
if base.direct.dr.mouseDeltaY > 0.0:
|
|
|
|
|
if direct.dr.mouseDeltaY > 0.0:
|
|
|
|
|
moveDir.setY(moveDir[1] * 1.0)
|
|
|
|
|
|
|
|
|
|
hVal = 0.5 * base.direct.dr.mouseDeltaX * base.direct.dr.fovH
|
|
|
|
|
hVal = 0.5 * direct.dr.mouseDeltaX * direct.dr.fovH
|
|
|
|
|
|
|
|
|
|
base.direct.camera.setPosHpr(base.direct.camera,
|
|
|
|
|
direct.camera.setPosHpr(direct.camera,
|
|
|
|
|
moveDir[0],
|
|
|
|
|
moveDir[1],
|
|
|
|
|
moveDir[2],
|
|
|
|
@ -372,39 +377,42 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
0.0, 0.0)
|
|
|
|
|
if self.lockRoll:
|
|
|
|
|
# flatten roll
|
|
|
|
|
base.direct.camera.setR(0)
|
|
|
|
|
direct.camera.setR(0)
|
|
|
|
|
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
|
|
def OrthoZoomTask(self, state):
|
|
|
|
|
filmSize = base.direct.camNode.getLens().getFilmSize()
|
|
|
|
|
factor = (base.direct.dr.mouseDeltaX -1.0 * base.direct.dr.mouseDeltaY) * 0.1
|
|
|
|
|
x = base.direct.dr.getWidth()
|
|
|
|
|
y = base.direct.dr.getHeight()
|
|
|
|
|
base.direct.dr.orthoFactor -= factor
|
|
|
|
|
if base.direct.dr.orthoFactor < 0:
|
|
|
|
|
base.direct.dr.orthoFactor = 0.0001
|
|
|
|
|
base.direct.dr.updateFilmSize(x, y)
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
filmSize = direct.camNode.getLens().getFilmSize()
|
|
|
|
|
factor = (direct.dr.mouseDeltaX -1.0 * direct.dr.mouseDeltaY) * 0.1
|
|
|
|
|
x = direct.dr.getWidth()
|
|
|
|
|
y = direct.dr.getHeight()
|
|
|
|
|
direct.dr.orthoFactor -= factor
|
|
|
|
|
if direct.dr.orthoFactor < 0:
|
|
|
|
|
direct.dr.orthoFactor = 0.0001
|
|
|
|
|
direct.dr.updateFilmSize(x, y)
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
|
|
def HPPanTask(self, state):
|
|
|
|
|
base.direct.camera.setHpr(base.direct.camera,
|
|
|
|
|
(0.5 * base.direct.dr.mouseDeltaX *
|
|
|
|
|
base.direct.dr.fovH),
|
|
|
|
|
(-0.5 * base.direct.dr.mouseDeltaY *
|
|
|
|
|
base.direct.dr.fovV),
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
direct.camera.setHpr(direct.camera,
|
|
|
|
|
(0.5 * direct.dr.mouseDeltaX *
|
|
|
|
|
direct.dr.fovH),
|
|
|
|
|
(-0.5 * direct.dr.mouseDeltaY *
|
|
|
|
|
direct.dr.fovV),
|
|
|
|
|
0.0)
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
|
|
def spawnMouseRotateTask(self):
|
|
|
|
|
# Kill any existing tasks
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
if self.perspCollPlane:
|
|
|
|
|
iRay = SelectionRay(base.direct.camera)
|
|
|
|
|
iRay.collider.setFromLens(base.direct.camNode, 0.0, 0.0)
|
|
|
|
|
iRay = SelectionRay(direct.camera)
|
|
|
|
|
iRay.collider.setFromLens(direct.camNode, 0.0, 0.0)
|
|
|
|
|
iRay.collideWithBitMask(1)
|
|
|
|
|
|
|
|
|
|
if base.direct.camera.getPos().getZ() >=0:
|
|
|
|
|
if direct.camera.getPos().getZ() >=0:
|
|
|
|
|
iRay.ct.traverse(self.perspCollPlane)
|
|
|
|
|
else:
|
|
|
|
|
iRay.ct.traverse(self.perspCollPlane2)
|
|
|
|
@ -415,7 +423,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
|
|
|
|
|
# create a temp nodePath to get the position
|
|
|
|
|
np = NodePath('temp')
|
|
|
|
|
np.setPos(base.direct.camera, hitPt)
|
|
|
|
|
np.setPos(direct.camera, hitPt)
|
|
|
|
|
self.coaMarkerPos = np.getPos()
|
|
|
|
|
np.removeNode()
|
|
|
|
|
self.coaMarker.setPos(self.coaMarkerPos)
|
|
|
|
@ -425,9 +433,9 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
|
|
|
|
|
# Set at markers position in render coordinates
|
|
|
|
|
self.camManipRef.setPos(self.coaMarkerPos)
|
|
|
|
|
self.camManipRef.setHpr(base.direct.camera, DG.ZERO_POINT)
|
|
|
|
|
self.camManipRef.setHpr(direct.camera, DG.ZERO_POINT)
|
|
|
|
|
t = Task.Task(self.mouseRotateTask)
|
|
|
|
|
if abs(base.direct.dr.mouseX) > 0.9:
|
|
|
|
|
if abs(direct.dr.mouseX) > 0.9:
|
|
|
|
|
t.constrainedDir = 'y'
|
|
|
|
|
else:
|
|
|
|
|
t.constrainedDir = 'x'
|
|
|
|
@ -435,36 +443,37 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
|
|
|
|
|
def mouseRotateTask(self, state):
|
|
|
|
|
# If the cam is orthogonal, don't rotate.
|
|
|
|
|
if (hasattr(base.direct.cam.node(), "getLens") and
|
|
|
|
|
base.direct.cam.node().getLens().__class__.__name__ == "OrthographicLens"):
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
if (hasattr(direct.cam.node(), "getLens") and
|
|
|
|
|
direct.cam.node().getLens().__class__.__name__ == "OrthographicLens"):
|
|
|
|
|
return
|
|
|
|
|
# If moving outside of center, ignore motion perpendicular to edge
|
|
|
|
|
if ((state.constrainedDir == 'y') and (abs(base.direct.dr.mouseX) > 0.9)):
|
|
|
|
|
if ((state.constrainedDir == 'y') and (abs(direct.dr.mouseX) > 0.9)):
|
|
|
|
|
deltaX = 0
|
|
|
|
|
deltaY = base.direct.dr.mouseDeltaY
|
|
|
|
|
elif ((state.constrainedDir == 'x') and (abs(base.direct.dr.mouseY) > 0.9)):
|
|
|
|
|
deltaX = base.direct.dr.mouseDeltaX
|
|
|
|
|
deltaY = direct.dr.mouseDeltaY
|
|
|
|
|
elif ((state.constrainedDir == 'x') and (abs(direct.dr.mouseY) > 0.9)):
|
|
|
|
|
deltaX = direct.dr.mouseDeltaX
|
|
|
|
|
deltaY = 0
|
|
|
|
|
else:
|
|
|
|
|
deltaX = base.direct.dr.mouseDeltaX
|
|
|
|
|
deltaY = base.direct.dr.mouseDeltaY
|
|
|
|
|
if base.direct.fShift:
|
|
|
|
|
base.direct.camera.setHpr(base.direct.camera,
|
|
|
|
|
(deltaX * base.direct.dr.fovH),
|
|
|
|
|
(-deltaY * base.direct.dr.fovV),
|
|
|
|
|
deltaX = direct.dr.mouseDeltaX
|
|
|
|
|
deltaY = direct.dr.mouseDeltaY
|
|
|
|
|
if direct.fShift:
|
|
|
|
|
direct.camera.setHpr(direct.camera,
|
|
|
|
|
(deltaX * direct.dr.fovH),
|
|
|
|
|
(-deltaY * direct.dr.fovV),
|
|
|
|
|
0.0)
|
|
|
|
|
if self.lockRoll:
|
|
|
|
|
# flatten roll
|
|
|
|
|
base.direct.camera.setR(0)
|
|
|
|
|
direct.camera.setR(0)
|
|
|
|
|
self.camManipRef.setPos(self.coaMarkerPos)
|
|
|
|
|
self.camManipRef.setHpr(base.direct.camera, DG.ZERO_POINT)
|
|
|
|
|
self.camManipRef.setHpr(direct.camera, DG.ZERO_POINT)
|
|
|
|
|
else:
|
|
|
|
|
if base.direct.camera.getPos().getZ() >=0 or not self.switchDirBelowZero:
|
|
|
|
|
if direct.camera.getPos().getZ() >=0 or not self.switchDirBelowZero:
|
|
|
|
|
dirX = -1
|
|
|
|
|
else:
|
|
|
|
|
dirX = 1
|
|
|
|
|
|
|
|
|
|
wrt = base.direct.camera.getTransform(self.camManipRef)
|
|
|
|
|
wrt = direct.camera.getTransform(self.camManipRef)
|
|
|
|
|
self.camManipRef.setHpr(self.camManipRef,
|
|
|
|
|
(dirX * deltaX * 180.0),
|
|
|
|
|
(deltaY * 180.0),
|
|
|
|
@ -473,20 +482,21 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
if self.lockRoll:
|
|
|
|
|
# flatten roll
|
|
|
|
|
self.camManipRef.setR(0)
|
|
|
|
|
base.direct.camera.setTransform(self.camManipRef, wrt)
|
|
|
|
|
direct.camera.setTransform(self.camManipRef, wrt)
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
|
|
def spawnMouseRollTask(self):
|
|
|
|
|
# Kill any existing tasks
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
# Set at markers position in render coordinates
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
self.camManipRef.setPos(self.coaMarkerPos)
|
|
|
|
|
self.camManipRef.setHpr(base.direct.camera, DG.ZERO_POINT)
|
|
|
|
|
self.camManipRef.setHpr(direct.camera, DG.ZERO_POINT)
|
|
|
|
|
t = Task.Task(self.mouseRollTask)
|
|
|
|
|
t.coaCenter = getScreenXY(self.coaMarker)
|
|
|
|
|
t.lastAngle = getCrankAngle(t.coaCenter)
|
|
|
|
|
# Store the camera/manipRef offset transform
|
|
|
|
|
t.wrt = base.direct.camera.getTransform(self.camManipRef)
|
|
|
|
|
t.wrt = direct.camera.getTransform(self.camManipRef)
|
|
|
|
|
self.__startManipulateCamera(task = t)
|
|
|
|
|
|
|
|
|
|
def mouseRollTask(self, state):
|
|
|
|
@ -498,23 +508,23 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
if self.lockRoll:
|
|
|
|
|
# flatten roll
|
|
|
|
|
self.camManipRef.setR(0)
|
|
|
|
|
base.direct.camera.setTransform(self.camManipRef, wrt)
|
|
|
|
|
ShowBaseGlobal.direct.camera.setTransform(self.camManipRef, wrt)
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
|
|
def lockCOA(self):
|
|
|
|
|
self.fLockCOA = 1
|
|
|
|
|
base.direct.message('COA Lock On')
|
|
|
|
|
ShowBaseGlobal.direct.message('COA Lock On')
|
|
|
|
|
|
|
|
|
|
def unlockCOA(self):
|
|
|
|
|
self.fLockCOA = 0
|
|
|
|
|
base.direct.message('COA Lock Off')
|
|
|
|
|
ShowBaseGlobal.direct.message('COA Lock Off')
|
|
|
|
|
|
|
|
|
|
def toggleCOALock(self):
|
|
|
|
|
self.fLockCOA = 1 - self.fLockCOA
|
|
|
|
|
if self.fLockCOA:
|
|
|
|
|
base.direct.message('COA Lock On')
|
|
|
|
|
ShowBaseGlobal.direct.message('COA Lock On')
|
|
|
|
|
else:
|
|
|
|
|
base.direct.message('COA Lock Off')
|
|
|
|
|
ShowBaseGlobal.direct.message('COA Lock Off')
|
|
|
|
|
|
|
|
|
|
def pickNextCOA(self):
|
|
|
|
|
""" Cycle through collision handler entries """
|
|
|
|
@ -524,7 +534,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.cqEntries = self.cqEntries[1:] + self.cqEntries[:1]
|
|
|
|
|
# Filter out object's under camera
|
|
|
|
|
nodePath = entry.getIntoNodePath()
|
|
|
|
|
if base.direct.camera not in nodePath.getAncestors():
|
|
|
|
|
if ShowBaseGlobal.direct.camera not in nodePath.getAncestors():
|
|
|
|
|
# Compute new hit point
|
|
|
|
|
hitPt = entry.getSurfacePoint(entry.getFromNodePath())
|
|
|
|
|
# Move coa marker to new point
|
|
|
|
@ -536,11 +546,11 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
|
|
|
|
|
def computeCOA(self, entry):
|
|
|
|
|
coa = Point3(0)
|
|
|
|
|
dr = base.direct.drList.getCurrentDr()
|
|
|
|
|
dr = ShowBaseGlobal.direct.drList.getCurrentDr()
|
|
|
|
|
if self.fLockCOA:
|
|
|
|
|
# COA is locked, use existing point
|
|
|
|
|
# Use existing point
|
|
|
|
|
coa.assign(self.coaMarker.getPos(base.direct.camera))
|
|
|
|
|
coa.assign(self.coaMarker.getPos(ShowBaseGlobal.direct.camera))
|
|
|
|
|
# Reset hit point count
|
|
|
|
|
self.nullHitPointCount = 0
|
|
|
|
|
elif entry:
|
|
|
|
@ -553,7 +563,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
if ((hitPtDist < (1.1 * dr.near)) or
|
|
|
|
|
(hitPtDist > dr.far)):
|
|
|
|
|
# Just use existing point
|
|
|
|
|
coa.assign(self.coaMarker.getPos(base.direct.camera))
|
|
|
|
|
coa.assign(self.coaMarker.getPos(ShowBaseGlobal.direct.camera))
|
|
|
|
|
# Reset hit point count
|
|
|
|
|
self.nullHitPointCount = 0
|
|
|
|
|
else:
|
|
|
|
@ -565,7 +575,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
# MRM: Would be nice to be able to control this
|
|
|
|
|
# At least display it
|
|
|
|
|
dist = pow(10.0, self.nullHitPointCount)
|
|
|
|
|
base.direct.message('COA Distance: ' + repr(dist))
|
|
|
|
|
ShowBaseGlobal.direct.message('COA Distance: ' + repr(dist))
|
|
|
|
|
coa.set(0, dist, 0)
|
|
|
|
|
# Compute COA Dist
|
|
|
|
|
coaDist = Vec3(coa - DG.ZERO_POINT).length()
|
|
|
|
@ -583,7 +593,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
if ref is None:
|
|
|
|
|
# KEH: use the current display region
|
|
|
|
|
# ref = base.cam
|
|
|
|
|
ref = base.direct.drList.getCurrentDr().cam
|
|
|
|
|
ref = ShowBaseGlobal.direct.drList.getCurrentDr().cam
|
|
|
|
|
self.coaMarker.setPos(ref, self.coa)
|
|
|
|
|
pos = self.coaMarker.getPos()
|
|
|
|
|
self.coaMarker.setPosHprScale(pos, Vec3(0), Vec3(1))
|
|
|
|
@ -598,10 +608,10 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
|
|
|
|
|
def updateCoaMarkerSize(self, coaDist = None):
|
|
|
|
|
if not coaDist:
|
|
|
|
|
coaDist = Vec3(self.coaMarker.getPos(base.direct.camera)).length()
|
|
|
|
|
coaDist = Vec3(self.coaMarker.getPos(ShowBaseGlobal.direct.camera)).length()
|
|
|
|
|
# Nominal size based on default 30 degree vertical FOV
|
|
|
|
|
# Need to adjust size based on distance and current FOV
|
|
|
|
|
sf = COA_MARKER_SF * coaDist * (base.direct.drList.getCurrentDr().fovV/30.0)
|
|
|
|
|
sf = COA_MARKER_SF * coaDist * (ShowBaseGlobal.direct.drList.getCurrentDr().fovV/30.0)
|
|
|
|
|
if sf == 0.0:
|
|
|
|
|
sf = 0.1
|
|
|
|
|
self.coaMarker.setScale(sf)
|
|
|
|
@ -619,32 +629,36 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
|
|
|
|
|
def homeCam(self):
|
|
|
|
|
# Record undo point
|
|
|
|
|
base.direct.pushUndo([base.direct.camera])
|
|
|
|
|
base.direct.camera.reparentTo(render)
|
|
|
|
|
base.direct.camera.clearMat()
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
direct.pushUndo([direct.camera])
|
|
|
|
|
direct.camera.reparentTo(ShowBaseGlobal.base.render)
|
|
|
|
|
direct.camera.clearMat()
|
|
|
|
|
# Resize coa marker
|
|
|
|
|
self.updateCoaMarkerSize()
|
|
|
|
|
|
|
|
|
|
def uprightCam(self):
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
# Record undo point
|
|
|
|
|
base.direct.pushUndo([base.direct.camera])
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
direct.pushUndo([direct.camera])
|
|
|
|
|
# Pitch camera till upright
|
|
|
|
|
currH = base.direct.camera.getH()
|
|
|
|
|
ival = base.direct.camera.hprInterval(CAM_MOVE_DURATION,
|
|
|
|
|
(currH, 0, 0),
|
|
|
|
|
other = render,
|
|
|
|
|
blendType = 'easeInOut',
|
|
|
|
|
name = 'manipulateCamera')
|
|
|
|
|
self.__startManipulateCamera(ival = ival)
|
|
|
|
|
currH = direct.camera.getH()
|
|
|
|
|
ival = direct.camera.hprInterval(CAM_MOVE_DURATION,
|
|
|
|
|
(currH, 0, 0),
|
|
|
|
|
other=ShowBaseGlobal.base.render,
|
|
|
|
|
blendType='easeInOut',
|
|
|
|
|
name='manipulateCamera')
|
|
|
|
|
self.__startManipulateCamera(ival=ival)
|
|
|
|
|
|
|
|
|
|
def orbitUprightCam(self):
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
# Record undo point
|
|
|
|
|
base.direct.pushUndo([base.direct.camera])
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
direct.pushUndo([direct.camera])
|
|
|
|
|
# Transform camera z axis to render space
|
|
|
|
|
render = ShowBaseGlobal.base.render
|
|
|
|
|
mCam2Render = Mat4(Mat4.identMat()) # [gjeon] fixed to give required argument
|
|
|
|
|
mCam2Render.assign(base.direct.camera.getMat(render))
|
|
|
|
|
mCam2Render.assign(direct.camera.getMat(render))
|
|
|
|
|
zAxis = Vec3(mCam2Render.xformVec(DG.Z_AXIS))
|
|
|
|
|
zAxis.normalize()
|
|
|
|
|
# Compute rotation angle needed to upright cam
|
|
|
|
@ -665,8 +679,8 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.camManipRef.setPos(self.coaMarker, Vec3(0))
|
|
|
|
|
self.camManipRef.setHpr(render, rotAngle, 0, 0)
|
|
|
|
|
# Reparent Cam to ref Coordinate system
|
|
|
|
|
parent = base.direct.camera.getParent()
|
|
|
|
|
base.direct.camera.wrtReparentTo(self.camManipRef)
|
|
|
|
|
parent = direct.camera.getParent()
|
|
|
|
|
direct.camera.wrtReparentTo(self.camManipRef)
|
|
|
|
|
# Rotate ref CS to final orientation
|
|
|
|
|
ival = self.camManipRef.hprInterval(CAM_MOVE_DURATION,
|
|
|
|
|
(rotAngle, orbitAngle, 0),
|
|
|
|
@ -685,17 +699,18 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
def centerCamIn(self, t):
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
# Record undo point
|
|
|
|
|
base.direct.pushUndo([base.direct.camera])
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
direct.pushUndo([direct.camera])
|
|
|
|
|
# Determine marker location
|
|
|
|
|
markerToCam = self.coaMarker.getPos(base.direct.camera)
|
|
|
|
|
markerToCam = self.coaMarker.getPos(direct.camera)
|
|
|
|
|
dist = Vec3(markerToCam - DG.ZERO_POINT).length()
|
|
|
|
|
scaledCenterVec = Y_AXIS * dist
|
|
|
|
|
delta = markerToCam - scaledCenterVec
|
|
|
|
|
self.camManipRef.setPosHpr(base.direct.camera, Point3(0), Point3(0))
|
|
|
|
|
ival = base.direct.camera.posInterval(CAM_MOVE_DURATION,
|
|
|
|
|
Point3(delta),
|
|
|
|
|
other = self.camManipRef,
|
|
|
|
|
blendType = 'easeInOut')
|
|
|
|
|
self.camManipRef.setPosHpr(direct.camera, Point3(0), Point3(0))
|
|
|
|
|
ival = direct.camera.posInterval(CAM_MOVE_DURATION,
|
|
|
|
|
Point3(delta),
|
|
|
|
|
other=self.camManipRef,
|
|
|
|
|
blendType='easeInOut')
|
|
|
|
|
ival = Sequence(ival, Func(self.updateCoaMarkerSizeOnDeath),
|
|
|
|
|
name = 'manipulateCamera')
|
|
|
|
|
self.__startManipulateCamera(ival = ival)
|
|
|
|
@ -703,17 +718,18 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
def zoomCam(self, zoomFactor, t):
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
# Record undo point
|
|
|
|
|
base.direct.pushUndo([base.direct.camera])
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
direct.pushUndo([direct.camera])
|
|
|
|
|
# Find a point zoom factor times the current separation
|
|
|
|
|
# of the widget and cam
|
|
|
|
|
zoomPtToCam = self.coaMarker.getPos(base.direct.camera) * zoomFactor
|
|
|
|
|
zoomPtToCam = self.coaMarker.getPos(direct.camera) * zoomFactor
|
|
|
|
|
# Put a target nodePath there
|
|
|
|
|
self.camManipRef.setPos(base.direct.camera, zoomPtToCam)
|
|
|
|
|
self.camManipRef.setPos(direct.camera, zoomPtToCam)
|
|
|
|
|
# Move to that point
|
|
|
|
|
ival = base.direct.camera.posInterval(CAM_MOVE_DURATION,
|
|
|
|
|
DG.ZERO_POINT,
|
|
|
|
|
other = self.camManipRef,
|
|
|
|
|
blendType = 'easeInOut')
|
|
|
|
|
ival = direct.camera.posInterval(CAM_MOVE_DURATION,
|
|
|
|
|
DG.ZERO_POINT,
|
|
|
|
|
other=self.camManipRef,
|
|
|
|
|
blendType='easeInOut')
|
|
|
|
|
ival = Sequence(ival, Func(self.updateCoaMarkerSizeOnDeath),
|
|
|
|
|
name = 'manipulateCamera')
|
|
|
|
|
self.__startManipulateCamera(ival = ival)
|
|
|
|
@ -722,7 +738,8 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
# Kill any existing tasks
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
# Record undo point
|
|
|
|
|
base.direct.pushUndo([base.direct.camera])
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
direct.pushUndo([direct.camera])
|
|
|
|
|
# Calc hprOffset
|
|
|
|
|
hprOffset = VBase3()
|
|
|
|
|
if view == 8:
|
|
|
|
@ -751,7 +768,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.camManipRef.setPosHpr(self.coaMarker, DG.ZERO_VEC,
|
|
|
|
|
hprOffset)
|
|
|
|
|
# Scale center vec by current distance to target
|
|
|
|
|
offsetDistance = Vec3(base.direct.camera.getPos(self.camManipRef) -
|
|
|
|
|
offsetDistance = Vec3(direct.camera.getPos(self.camManipRef) -
|
|
|
|
|
DG.ZERO_POINT).length()
|
|
|
|
|
scaledCenterVec = Y_AXIS * (-1.0 * offsetDistance)
|
|
|
|
|
# Now put the camManipRef at that point
|
|
|
|
@ -760,11 +777,11 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
DG.ZERO_VEC)
|
|
|
|
|
# Record view for next time around
|
|
|
|
|
self.lastView = view
|
|
|
|
|
ival = base.direct.camera.posHprInterval(CAM_MOVE_DURATION,
|
|
|
|
|
pos = DG.ZERO_POINT,
|
|
|
|
|
hpr = VBase3(0, 0, self.orthoViewRoll),
|
|
|
|
|
other = self.camManipRef,
|
|
|
|
|
blendType = 'easeInOut')
|
|
|
|
|
ival = direct.camera.posHprInterval(CAM_MOVE_DURATION,
|
|
|
|
|
pos=DG.ZERO_POINT,
|
|
|
|
|
hpr=VBase3(0, 0, self.orthoViewRoll),
|
|
|
|
|
other=self.camManipRef,
|
|
|
|
|
blendType='easeInOut')
|
|
|
|
|
ival = Sequence(ival, Func(self.updateCoaMarkerSizeOnDeath),
|
|
|
|
|
name = 'manipulateCamera')
|
|
|
|
|
self.__startManipulateCamera(ival = ival)
|
|
|
|
@ -774,15 +791,16 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
|
|
|
|
|
# Record undo point
|
|
|
|
|
base.direct.pushUndo([base.direct.camera])
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
direct.pushUndo([direct.camera])
|
|
|
|
|
|
|
|
|
|
# Coincident with widget
|
|
|
|
|
self.camManipRef.setPos(self.coaMarker, DG.ZERO_POINT)
|
|
|
|
|
# But aligned with render space
|
|
|
|
|
self.camManipRef.setHpr(DG.ZERO_POINT)
|
|
|
|
|
|
|
|
|
|
parent = base.direct.camera.getParent()
|
|
|
|
|
base.direct.camera.wrtReparentTo(self.camManipRef)
|
|
|
|
|
parent = direct.camera.getParent()
|
|
|
|
|
direct.camera.wrtReparentTo(self.camManipRef)
|
|
|
|
|
|
|
|
|
|
ival = self.camManipRef.hprInterval(CAM_MOVE_DURATION,
|
|
|
|
|
VBase3(degrees, 0, 0),
|
|
|
|
@ -792,7 +810,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
self.__startManipulateCamera(ival = ival)
|
|
|
|
|
|
|
|
|
|
def reparentCam(self, parent):
|
|
|
|
|
base.direct.camera.wrtReparentTo(parent)
|
|
|
|
|
ShowBaseGlobal.direct.camera.wrtReparentTo(parent)
|
|
|
|
|
self.updateCoaMarkerSize()
|
|
|
|
|
|
|
|
|
|
def fitOnWidget(self, nodePath = 'None Given'):
|
|
|
|
@ -800,75 +818,78 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
# stop any ongoing tasks
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|
# How big is the node?
|
|
|
|
|
nodeScale = base.direct.widget.scalingNode.getScale(render)
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
nodeScale = direct.widget.scalingNode.getScale(ShowBaseGlobal.base.render)
|
|
|
|
|
maxScale = max(nodeScale[0], nodeScale[1], nodeScale[2])
|
|
|
|
|
maxDim = min(base.direct.dr.nearWidth, base.direct.dr.nearHeight)
|
|
|
|
|
maxDim = min(direct.dr.nearWidth, direct.dr.nearHeight)
|
|
|
|
|
|
|
|
|
|
# At what distance does the object fill 30% of the screen?
|
|
|
|
|
# Assuming radius of 1 on widget
|
|
|
|
|
camY = base.direct.dr.near * (2.0 * maxScale)/(0.3 * maxDim)
|
|
|
|
|
camY = direct.dr.near * (2.0 * maxScale) / (0.3 * maxDim)
|
|
|
|
|
|
|
|
|
|
# What is the vector through the center of the screen?
|
|
|
|
|
centerVec = Y_AXIS * camY
|
|
|
|
|
|
|
|
|
|
# Where is the node relative to the viewpoint
|
|
|
|
|
vWidget2Camera = base.direct.widget.getPos(base.direct.camera)
|
|
|
|
|
vWidget2Camera = direct.widget.getPos(direct.camera)
|
|
|
|
|
|
|
|
|
|
# How far do you move the camera to be this distance from the node?
|
|
|
|
|
deltaMove = vWidget2Camera - centerVec
|
|
|
|
|
|
|
|
|
|
# Move a target there
|
|
|
|
|
try:
|
|
|
|
|
self.camManipRef.setPos(base.direct.camera, deltaMove)
|
|
|
|
|
self.camManipRef.setPos(direct.camera, deltaMove)
|
|
|
|
|
except Exception:
|
|
|
|
|
#self.notify.debug
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
parent = base.direct.camera.getParent()
|
|
|
|
|
base.direct.camera.wrtReparentTo(self.camManipRef)
|
|
|
|
|
ival = base.direct.camera.posInterval(CAM_MOVE_DURATION,
|
|
|
|
|
Point3(0, 0, 0),
|
|
|
|
|
blendType = 'easeInOut')
|
|
|
|
|
parent = direct.camera.getParent()
|
|
|
|
|
direct.camera.wrtReparentTo(self.camManipRef)
|
|
|
|
|
ival = direct.camera.posInterval(CAM_MOVE_DURATION,
|
|
|
|
|
Point3(0, 0, 0),
|
|
|
|
|
blendType='easeInOut')
|
|
|
|
|
ival = Sequence(ival, Func(self.reparentCam, parent),
|
|
|
|
|
name = 'manipulateCamera')
|
|
|
|
|
self.__startManipulateCamera(ival = ival)
|
|
|
|
|
name='manipulateCamera')
|
|
|
|
|
self.__startManipulateCamera(ival=ival)
|
|
|
|
|
|
|
|
|
|
def moveToFit(self):
|
|
|
|
|
# How big is the active widget?
|
|
|
|
|
widgetScale = base.direct.widget.scalingNode.getScale(render)
|
|
|
|
|
direct = ShowBaseGlobal.direct
|
|
|
|
|
widgetScale = direct.widget.scalingNode.getScale(ShowBaseGlobal.base.render)
|
|
|
|
|
maxScale = max(widgetScale[0], widgetScale[1], widgetScale[2])
|
|
|
|
|
# At what distance does the widget fill 50% of the screen?
|
|
|
|
|
camY = ((2 * base.direct.dr.near * (1.5 * maxScale)) /
|
|
|
|
|
min(base.direct.dr.nearWidth, base.direct.dr.nearHeight))
|
|
|
|
|
camY = ((2 * direct.dr.near * (1.5 * maxScale)) /
|
|
|
|
|
min(direct.dr.nearWidth, direct.dr.nearHeight))
|
|
|
|
|
# Find a point this distance along the Y axis
|
|
|
|
|
# MRM: This needs to be generalized to support non uniform frusta
|
|
|
|
|
centerVec = Y_AXIS * camY
|
|
|
|
|
# Before moving, record the relationship between the selected nodes
|
|
|
|
|
# and the widget, so that this can be maintained
|
|
|
|
|
base.direct.selected.getWrtAll()
|
|
|
|
|
direct.selected.getWrtAll()
|
|
|
|
|
# Push state onto undo stack
|
|
|
|
|
base.direct.pushUndo(base.direct.selected)
|
|
|
|
|
direct.pushUndo(direct.selected)
|
|
|
|
|
# Remove the task to keep the widget attached to the object
|
|
|
|
|
taskMgr.remove('followSelectedNodePath')
|
|
|
|
|
# Spawn a task to keep the selected objects with the widget
|
|
|
|
|
taskMgr.add(self.stickToWidgetTask, 'stickToWidget')
|
|
|
|
|
# Spawn a task to move the widget
|
|
|
|
|
ival = base.direct.widget.posInterval(CAM_MOVE_DURATION,
|
|
|
|
|
Point3(centerVec),
|
|
|
|
|
other = base.direct.camera,
|
|
|
|
|
blendType = 'easeInOut')
|
|
|
|
|
ival = direct.widget.posInterval(CAM_MOVE_DURATION,
|
|
|
|
|
Point3(centerVec),
|
|
|
|
|
other=direct.camera,
|
|
|
|
|
blendType='easeInOut')
|
|
|
|
|
ival = Sequence(ival, Func(lambda: taskMgr.remove('stickToWidget')),
|
|
|
|
|
name = 'moveToFit')
|
|
|
|
|
ival.start()
|
|
|
|
|
|
|
|
|
|
def stickToWidgetTask(self, state):
|
|
|
|
|
# Move the objects with the widget
|
|
|
|
|
base.direct.selected.moveWrtWidgetAll()
|
|
|
|
|
ShowBaseGlobal.direct.selected.moveWrtWidgetAll()
|
|
|
|
|
# Continue
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
|
|
def enableMouseFly(self, fKeyEvents = 1):
|
|
|
|
|
# disable C++ fly interface
|
|
|
|
|
base = ShowBaseGlobal.base
|
|
|
|
|
base.disableMouse()
|
|
|
|
|
# Enable events
|
|
|
|
|
for event in self.actionEvents:
|
|
|
|
@ -877,11 +898,11 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
for event in self.keyEvents:
|
|
|
|
|
self.accept(event[0], event[1], extraArgs = event[2:])
|
|
|
|
|
# Show marker
|
|
|
|
|
self.coaMarker.reparentTo(base.direct.group)
|
|
|
|
|
self.coaMarker.reparentTo(ShowBaseGlobal.direct.group)
|
|
|
|
|
|
|
|
|
|
def disableMouseFly(self):
|
|
|
|
|
# Hide the marker
|
|
|
|
|
self.coaMarker.reparentTo(hidden)
|
|
|
|
|
self.coaMarker.reparentTo(ShowBaseGlobal.hidden)
|
|
|
|
|
# Ignore events
|
|
|
|
|
for event in self.actionEvents:
|
|
|
|
|
self.ignore(event[0])
|
|
|
|
@ -890,7 +911,7 @@ class DirectCameraControl(DirectObject):
|
|
|
|
|
# Kill tasks
|
|
|
|
|
self.removeManipulateCameraTask()
|
|
|
|
|
taskMgr.remove('stickToWidget')
|
|
|
|
|
base.enableMouse()
|
|
|
|
|
ShowBaseGlobal.base.enableMouse()
|
|
|
|
|
|
|
|
|
|
def removeManipulateCameraTask(self):
|
|
|
|
|
self.__stopManipulateCamera()
|
|
|
|
|