replace set_velocity() with set_fluid_pos()
This commit is contained in:
parent
4650d62c0d
commit
3c3f2f4432
|
|
@ -7,11 +7,12 @@ class Mopath(PandaObject):
|
|||
|
||||
nameIndex = 1
|
||||
|
||||
def __init__(self, name = None):
|
||||
def __init__(self, name = None, fluid = 1):
|
||||
if (name == None):
|
||||
name = 'mopath%d' % self.nameIndex
|
||||
self.nameIndex = self.nameIndex + 1
|
||||
self.name = name
|
||||
self.fluid = fluid
|
||||
self.tPoint = Point3(0)
|
||||
self.posPoint = Point3(0)
|
||||
self.hprPoint = Point3(0)
|
||||
|
|
@ -97,7 +98,10 @@ class Mopath(PandaObject):
|
|||
self.playbackTime = self.calcTime(CLAMP(time, 0.0, self.maxT))
|
||||
if (self.xyzNurbsCurve != None):
|
||||
self.xyzNurbsCurve.getPoint(self.playbackTime, self.posPoint)
|
||||
node.setPos(self.posPoint)
|
||||
if self.fluid:
|
||||
node.setFluidPos(self.posPoint)
|
||||
else:
|
||||
node.setPos(self.posPoint)
|
||||
if (self.hprNurbsCurve != None):
|
||||
self.hprNurbsCurve.getPoint(self.playbackTime, self.hprPoint)
|
||||
node.setHpr(self.hprPoint)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ class LerpNodePathInterval(CLerpNodePathInterval):
|
|||
# affect a property on a NodePath, like pos or hpr.
|
||||
lerpNodePathNum = 1
|
||||
|
||||
def __init__(self, name, duration, blendType, bakeInStart, node, other):
|
||||
def __init__(self, name, duration, blendType, bakeInStart, fluid,
|
||||
node, other):
|
||||
if name == None:
|
||||
name = '%s-%d' % (self.__class__.__name__, self.lerpNodePathNum)
|
||||
LerpNodePathInterval.lerpNodePathNum += 1
|
||||
|
|
@ -29,7 +30,7 @@ class LerpNodePathInterval(CLerpNodePathInterval):
|
|||
other = NodePath()
|
||||
|
||||
CLerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
|
||||
def anyCallable(self, *params):
|
||||
# Returns true if any of the parameters listed is a callable
|
||||
|
|
@ -70,14 +71,21 @@ class LerpNodePathInterval(CLerpNodePathInterval):
|
|||
## delta since the last time the interval ran, which allows show code
|
||||
## to manipulate the node even while it is being lerped.
|
||||
##
|
||||
## If fluid is true for a LerpPos-style interval, then the pos is set
|
||||
## via NodePath.setFluidPos() instead of NodePath.setPos(), causing
|
||||
## the collision system to treat the motion as continuous and test
|
||||
## for collisions against the entire motion path, instead of as
|
||||
## discrete position updates. This has no meaning for Lerp intervals
|
||||
## that do not adjust pos.
|
||||
##
|
||||
#####################################################################
|
||||
|
||||
class LerpPosInterval(LerpNodePathInterval):
|
||||
def __init__(self, node, duration, pos, startPos = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
|
||||
# Check for functors in the input parameters.
|
||||
self.paramSetup = self.anyCallable(pos, startPos)
|
||||
|
|
@ -102,9 +110,9 @@ class LerpPosInterval(LerpNodePathInterval):
|
|||
class LerpHprInterval(LerpNodePathInterval):
|
||||
def __init__(self, node, duration, hpr, startHpr = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
|
||||
# Check for functors in the input parameters.
|
||||
self.paramSetup = self.anyCallable(hpr, startHpr)
|
||||
|
|
@ -128,9 +136,9 @@ class LerpHprInterval(LerpNodePathInterval):
|
|||
class LerpScaleInterval(LerpNodePathInterval):
|
||||
def __init__(self, node, duration, scale, startScale = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
# Check for functors in the input parameters.
|
||||
self.paramSetup = self.anyCallable(scale, startScale)
|
||||
if self.paramSetup:
|
||||
|
|
@ -153,9 +161,9 @@ class LerpScaleInterval(LerpNodePathInterval):
|
|||
class LerpShearInterval(LerpNodePathInterval):
|
||||
def __init__(self, node, duration, shear, startShear = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
# Check for functors in the input parameters.
|
||||
self.paramSetup = self.anyCallable(shear, startShear)
|
||||
if self.paramSetup:
|
||||
|
|
@ -179,9 +187,9 @@ class LerpPosHprInterval(LerpNodePathInterval):
|
|||
def __init__(self, node, duration, pos, hpr,
|
||||
startPos = None, startHpr = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
# Check for functors in the input parameters.
|
||||
self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr)
|
||||
if self.paramSetup:
|
||||
|
|
@ -212,9 +220,9 @@ class LerpHprScaleInterval(LerpNodePathInterval):
|
|||
def __init__(self, node, duration, hpr, scale,
|
||||
startHpr = None, startScale = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
|
||||
# Check for functors in the input parameters.
|
||||
self.paramSetup = self.anyCallable(hpr, startHpr, scale, startScale)
|
||||
|
|
@ -246,9 +254,9 @@ class LerpPosHprScaleInterval(LerpNodePathInterval):
|
|||
def __init__(self, node, duration, pos, hpr, scale,
|
||||
startPos = None, startHpr = None, startScale = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
# Check for functors in the input parameters.
|
||||
self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr, scale, startScale)
|
||||
if self.paramSetup:
|
||||
|
|
@ -286,9 +294,9 @@ class LerpPosHprScaleShearInterval(LerpNodePathInterval):
|
|||
def __init__(self, node, duration, pos, hpr, scale, shear,
|
||||
startPos = None, startHpr = None, startScale = None, startShear = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
# Check for functors in the input parameters.
|
||||
self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr, scale, startScale, shear, startShear)
|
||||
if self.paramSetup:
|
||||
|
|
@ -332,9 +340,9 @@ class LerpPosHprScaleShearInterval(LerpNodePathInterval):
|
|||
class LerpColorScaleInterval(LerpNodePathInterval):
|
||||
def __init__(self, node, duration, colorScale, startColorScale = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
self.setEndColorScale(colorScale)
|
||||
if startColorScale != None:
|
||||
self.setStartColorScale(startColorScale)
|
||||
|
|
@ -342,9 +350,9 @@ class LerpColorScaleInterval(LerpNodePathInterval):
|
|||
class LerpColorInterval(LerpNodePathInterval):
|
||||
def __init__(self, node, duration, color, startColor = None,
|
||||
other = None, blendType = 'noBlend',
|
||||
bakeInStart = 1, name = None):
|
||||
bakeInStart = 1, fluid = 0, name = None):
|
||||
LerpNodePathInterval.__init__(self, name, duration, blendType,
|
||||
bakeInStart, node, other)
|
||||
bakeInStart, fluid, node, other)
|
||||
self.setEndColor(color)
|
||||
if startColor != None:
|
||||
self.setStartColor(startColor)
|
||||
|
|
|
|||
|
|
@ -54,11 +54,14 @@ TypeHandle CLerpNodePathInterval::_type_handle;
|
|||
// "smart" behavior allows code to manipulate the object
|
||||
// event while it is being lerped, and the lerp
|
||||
// continues to apply in a sensible way.
|
||||
//
|
||||
// If fluid is true, the prev_transform is not adjusted
|
||||
// by the lerp; otherwise, it is reset.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CLerpNodePathInterval::
|
||||
CLerpNodePathInterval(const string &name, double duration,
|
||||
CLerpInterval::BlendType blend_type,
|
||||
bool bake_in_start,
|
||||
bool bake_in_start, bool fluid,
|
||||
const NodePath &node, const NodePath &other) :
|
||||
CLerpInterval(name, duration, blend_type),
|
||||
_node(node),
|
||||
|
|
@ -68,6 +71,9 @@ CLerpNodePathInterval(const string &name, double duration,
|
|||
if (bake_in_start) {
|
||||
_flags |= F_bake_in_start;
|
||||
}
|
||||
if (fluid) {
|
||||
_flags |= F_fluid;
|
||||
}
|
||||
_prev_d = 0.0;
|
||||
}
|
||||
|
||||
|
|
@ -119,6 +125,9 @@ priv_step(double t) {
|
|||
_state = S_started;
|
||||
double d = compute_delta(t);
|
||||
|
||||
// Save this in case we want to restore it later.
|
||||
CPT(TransformState) prev_transform = _node.get_prev_transform();
|
||||
|
||||
if ((_flags & (F_end_pos | F_end_hpr | F_end_scale | F_end_shear)) != 0) {
|
||||
// We have some transform lerp.
|
||||
CPT(TransformState) transform;
|
||||
|
|
@ -297,6 +306,13 @@ priv_step(double t) {
|
|||
}
|
||||
}
|
||||
|
||||
if ((_flags & F_fluid) != 0) {
|
||||
// If we have the fluid flag set, we shouldn't mess with the prev
|
||||
// transform. Therefore, restore it to what it was before we
|
||||
// started messing with it.
|
||||
_node.set_prev_transform(prev_transform);
|
||||
}
|
||||
|
||||
if ((_flags & (F_end_color | F_end_color_scale)) != 0) {
|
||||
// We have some render state lerp.
|
||||
CPT(RenderState) state;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class EXPCL_DIRECT CLerpNodePathInterval : public CLerpInterval {
|
|||
PUBLISHED:
|
||||
CLerpNodePathInterval(const string &name, double duration,
|
||||
BlendType blend_type, bool bake_in_start,
|
||||
bool fluid,
|
||||
const NodePath &node, const NodePath &other);
|
||||
|
||||
INLINE const NodePath &get_node() const;
|
||||
|
|
@ -79,6 +80,7 @@ private:
|
|||
F_start_color_scale = 0x1000,
|
||||
F_start_shear = 0x2000,
|
||||
|
||||
F_fluid = 0x4000,
|
||||
F_bake_in_start = 0x8000,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -179,13 +179,11 @@ class NonPhysicsWalker(DirectObject.DirectObject):
|
|||
# our previous heading.
|
||||
rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
|
||||
step=rotMat.xform(self.vel)
|
||||
self.avatarNodePath.setPos(Point3(self.avatarNodePath.getPos()+step))
|
||||
self.avatarNodePath.setFluidPos(Point3(self.avatarNodePath.getPos()+step))
|
||||
self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
|
||||
messenger.send("avatarMoving")
|
||||
else:
|
||||
self.vel.set(0.0, 0.0, 0.0)
|
||||
# Set collision sphere node:
|
||||
self.cSphereNode.setVelocity(self.vel)
|
||||
return Task.cont
|
||||
|
||||
def enableAvatarControls(self):
|
||||
|
|
|
|||
|
|
@ -305,17 +305,12 @@ class PhysicsWalker(DirectObject.DirectObject):
|
|||
self.__vel.set(0.0, 0.0, 0.0)
|
||||
# Clear the contact vector so we can tell if we contact something next frame:
|
||||
self.actorNode.setContactVector(Vec3.zero())
|
||||
# Set collision sphere node:
|
||||
v=physObject.getImplicitVelocity()
|
||||
v=rotAvatarToPhys.xform(v)
|
||||
self.cSphereNode.setVelocity(Vec3(v))
|
||||
return Task.cont
|
||||
|
||||
def resetPhys(self):
|
||||
assert(self.debugPrint("resetPhys()"))
|
||||
self.actorNode.getPhysicsObject().resetPosition(self.avatarNodePath.getPos())
|
||||
self.actorNode.setContactVector(Vec3.zero())
|
||||
self.cSphereNode.setVelocity(Vec3(0.0))
|
||||
|
||||
def enableAvatarControls(self):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -793,6 +793,18 @@ class ShowBase(DirectObject.DirectObject):
|
|||
music.setLoop(looping)
|
||||
music.play()
|
||||
|
||||
def resetPrevTransform(self, state):
|
||||
# Clear out the previous velocity deltas now, after we have
|
||||
# rendered (the previous frame). We do this after the render,
|
||||
# so that we have a chance to draw a representation of spheres
|
||||
# along with their velocities. At the beginning of the frame
|
||||
# really means after the command prompt, which allows the user
|
||||
# to interactively query these deltas meaningfully.
|
||||
|
||||
if self.cTrav:
|
||||
self.cTrav.resetPrevTransform(self.render)
|
||||
return Task.cont
|
||||
|
||||
def dataloop(self, state):
|
||||
# traverse the data graph. This reads all the control
|
||||
# inputs (from the mouse and keyboard, for instance) and also
|
||||
|
|
@ -845,6 +857,8 @@ class ShowBase(DirectObject.DirectObject):
|
|||
|
||||
def restart(self):
|
||||
self.shutdown()
|
||||
# resetPrevTransform goes at the very beginning of the frame.
|
||||
self.taskMgr.add(self.resetPrevTransform, 'resetPrevTransform', priority = -51)
|
||||
# give the dataloop task a reasonably "early" priority,
|
||||
# so that it will get run before most tasks
|
||||
self.taskMgr.add(self.dataloop, 'dataloop', priority = -50)
|
||||
|
|
@ -868,6 +882,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.taskMgr.remove('shadowCollisionLoop')
|
||||
self.taskMgr.remove('collisionloop')
|
||||
self.taskMgr.remove('dataloop')
|
||||
self.taskMgr.remove('resetPrevTransform')
|
||||
self.taskMgr.remove('ivalloop')
|
||||
self.eventMgr.shutdown()
|
||||
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ class TaskManagerWidget(PandaObject):
|
|||
name = self.currentTask.name
|
||||
ok = 1
|
||||
if ((name == 'dataloop') or
|
||||
(name == 'resetPrevTransform') or
|
||||
(name == 'tkloop') or
|
||||
(name == 'eventManager') or
|
||||
(name == 'igloop')):
|
||||
|
|
@ -195,6 +196,7 @@ class TaskManagerWidget(PandaObject):
|
|||
name = self.taskListBox.getcurselection()[0]
|
||||
ok = 1
|
||||
if ((name == 'dataloop') or
|
||||
(name == 'resetPrevTransform') or
|
||||
(name == 'tkloop') or
|
||||
(name == 'eventManager') or
|
||||
(name == 'igloop')):
|
||||
|
|
|
|||
|
|
@ -19,17 +19,21 @@
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::Constructor
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CollisionEntry::
|
||||
CollisionEntry() {
|
||||
_flags = 0;
|
||||
_from_space = TransformState::make_identity();
|
||||
_into_space = TransformState::make_identity();
|
||||
_wrt_space = TransformState::make_identity();
|
||||
_inv_wrt_space = TransformState::make_identity();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_from
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the CollisionSolid pointer for the particular
|
||||
// solid that triggered this collision.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -40,7 +44,7 @@ get_from() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::has_into
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns true if the "into" solid is, in fact, a
|
||||
// CollisionSolid, and its pointer is known (in which
|
||||
// case get_into() may be called to retrieve it). If
|
||||
|
|
@ -55,7 +59,7 @@ has_into() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_into
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the CollisionSolid pointer for the particular
|
||||
// solid was collided into. This pointer might be NULL
|
||||
// if the collision was into a piece of visible
|
||||
|
|
@ -69,7 +73,7 @@ get_into() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_from_node
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the node that contains the CollisionSolid
|
||||
// that triggered this collision. This will be a node
|
||||
// that has been added to a CollisionTraverser via
|
||||
|
|
@ -80,22 +84,9 @@ get_from_node() const {
|
|||
return _from_node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_from_space
|
||||
// Access: Public
|
||||
// Description: Returns the global coordinate space of the
|
||||
// CollisionNode returned by get_from_node(), as of the
|
||||
// time of the collision. This will be equivalent to a
|
||||
// wrt() from the node to render.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionEntry::
|
||||
get_from_space() const {
|
||||
return _from_space;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_into_node
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the node that contains the CollisionSolid
|
||||
// that was collided into. This returns a PandaNode
|
||||
// pointer instead of something more specific, because
|
||||
|
|
@ -110,7 +101,7 @@ get_into_node() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_into_node_path
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the NodePath that represents the specific
|
||||
// CollisionNode or GeomNode instance that was collided
|
||||
// into. This is the same node returned by
|
||||
|
|
@ -124,78 +115,139 @@ get_into_node_path() const {
|
|||
return _into_node_path;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_from_space
|
||||
// Access: Published
|
||||
// Description: Returns the global coordinate space of the
|
||||
// CollisionNode returned by get_from_node(), as of the
|
||||
// time of the collision. This will be equivalent to a
|
||||
// wrt() from the node to render.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TransformState *CollisionEntry::
|
||||
get_from_space() const {
|
||||
return _from_space;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_into_space
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the global coordinate space of the
|
||||
// CollisionNode or GeomNode returned by
|
||||
// get_into_node(), as of the time of the collision.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionEntry::
|
||||
INLINE const TransformState *CollisionEntry::
|
||||
get_into_space() const {
|
||||
return _into_space;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_wrt_space
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionEntry::
|
||||
INLINE const TransformState *CollisionEntry::
|
||||
get_wrt_space() const {
|
||||
return _wrt_space;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_inv_wrt_space
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionEntry::
|
||||
INLINE const TransformState *CollisionEntry::
|
||||
get_inv_wrt_space() const {
|
||||
return _inv_wrt_space;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::set_from_velocity
|
||||
// Access: Public
|
||||
// Description: Indicates the velocity associated with the "from"
|
||||
// Function: CollisionEntry::get_from_mat
|
||||
// Access: Published
|
||||
// Description: Returns the global coordinate space of the
|
||||
// CollisionNode returned by get_from_node(), as of the
|
||||
// time of the collision. This will be equivalent to a
|
||||
// wrt() from the node to render.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionEntry::
|
||||
get_from_mat() const {
|
||||
return _from_space->get_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_into_mat
|
||||
// Access: Published
|
||||
// Description: Returns the global coordinate space of the
|
||||
// CollisionNode or GeomNode returned by
|
||||
// get_into_node(), as of the time of the collision.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionEntry::
|
||||
get_into_mat() const {
|
||||
return _into_space->get_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_wrt_mat
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionEntry::
|
||||
get_wrt_mat() const {
|
||||
return _wrt_space->get_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_inv_wrt_mat
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionEntry::
|
||||
get_inv_wrt_mat() const {
|
||||
return _inv_wrt_space->get_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::set_from_pos_delta
|
||||
// Access: Published
|
||||
// Description: Indicates the pos_delta associated with the "from"
|
||||
// object, in the object's coordinate space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionEntry::
|
||||
set_from_velocity(const LVector3f &vel) {
|
||||
_from_velocity = vel;
|
||||
_flags |= F_has_from_velocity;
|
||||
set_from_pos_delta(const LVector3f &vel) {
|
||||
_from_pos_delta = vel;
|
||||
_flags |= F_has_from_pos_delta;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::has_from_velocity
|
||||
// Access: Public
|
||||
// Description: Returns true if the "from" object had an indicated
|
||||
// velocity, false otherwise.
|
||||
// Function: CollisionEntry::has_from_pos_delta
|
||||
// Access: Published
|
||||
// Description: Returns true if the objects appeared to be moving
|
||||
// relative to each other, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CollisionEntry::
|
||||
has_from_velocity() const {
|
||||
return (_flags & F_has_from_velocity) != 0;
|
||||
has_from_pos_delta() const {
|
||||
return (_flags & F_has_from_pos_delta) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_from_velocity
|
||||
// Access: Public
|
||||
// Description: Returns the instantaneous velocity of the "from"
|
||||
// object, in its own coordinate space. This represents
|
||||
// the delta between its current position and its
|
||||
// position last frame.
|
||||
// Function: CollisionEntry::get_from_pos_delta
|
||||
// Access: Published
|
||||
// Description: Returns the position delta between the two objects,
|
||||
// in the coordinate space of the "from" object. This
|
||||
// is the delta between their relative position in the
|
||||
// previous frame and their relative position this
|
||||
// frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVector3f &CollisionEntry::
|
||||
get_from_velocity() const {
|
||||
nassertr(has_from_velocity(), _from_velocity);
|
||||
return _from_velocity;
|
||||
get_from_pos_delta() const {
|
||||
if (!has_from_pos_delta()) {
|
||||
return LVector3f::zero();
|
||||
}
|
||||
return _from_pos_delta;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::set_into_intersection_point
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionEntry::
|
||||
|
|
@ -206,7 +258,7 @@ set_into_intersection_point(const LPoint3f &point) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::has_into_intersection_point
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns true if the detected collision knows its
|
||||
// intersection point in the coordinate space of the
|
||||
// collided-into object, false otherwise.
|
||||
|
|
@ -218,7 +270,7 @@ has_into_intersection_point() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_into_intersection_point
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the intersection point in the coordinate
|
||||
// space of the collided-into object. It is an error to
|
||||
// call this if has_into_intersection_point() returns
|
||||
|
|
@ -232,7 +284,7 @@ get_into_intersection_point() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::has_from_intersection_point
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns true if the detected collision knows its
|
||||
// intersection point in the coordinate space of the
|
||||
// colliding object, false otherwise.
|
||||
|
|
@ -246,7 +298,7 @@ has_from_intersection_point() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_from_intersection_point
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the intersection point in the coordinate
|
||||
// space of the colliding object. It is an error to
|
||||
// call this if has_from_intersection_point() returns
|
||||
|
|
@ -254,12 +306,12 @@ has_from_intersection_point() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LPoint3f CollisionEntry::
|
||||
get_from_intersection_point() const {
|
||||
return get_into_intersection_point() * get_inv_wrt_space();
|
||||
return get_into_intersection_point() * get_inv_wrt_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::set_into_surface_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionEntry::
|
||||
|
|
@ -270,7 +322,7 @@ set_into_surface_normal(const LVector3f &normal) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::has_into_surface_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns true if the detected collision knows the
|
||||
// surface normal of the collided-into object at the
|
||||
// point of the collision, false otherwise.
|
||||
|
|
@ -282,7 +334,7 @@ has_into_surface_normal() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_into_surface_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the surface normal of the collided-into
|
||||
// object at the point of the collision. It is an error
|
||||
// to call this if has_into_surface_normal() returns
|
||||
|
|
@ -296,7 +348,7 @@ get_into_surface_normal() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::set_from_surface_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionEntry::
|
||||
|
|
@ -307,7 +359,7 @@ set_from_surface_normal(const LVector3f &normal) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::has_from_surface_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns true if the detected collision knows the
|
||||
// surface normal of the collided-into object at the
|
||||
// point of the collision, false otherwise.
|
||||
|
|
@ -319,7 +371,7 @@ has_from_surface_normal() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_from_surface_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the surface normal of the collided-into
|
||||
// object at the point of the collision, in the space of
|
||||
// the collided-from object. It is an error to call
|
||||
|
|
@ -337,7 +389,7 @@ get_from_surface_normal() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::set_into_depth
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionEntry::
|
||||
|
|
@ -348,7 +400,7 @@ set_into_depth(float depth) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::has_into_depth
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns true if the collision entry knows how "deep"
|
||||
// the collision was into the collided-into object; that
|
||||
// is, how far into the surface of the collided-into
|
||||
|
|
@ -361,7 +413,7 @@ has_into_depth() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_into_depth
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns how "deep" the collision was into the
|
||||
// collided-into object; that is, how far into the
|
||||
// surface of the collided-into object the colliding
|
||||
|
|
@ -376,7 +428,7 @@ get_into_depth() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::set_from_depth
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionEntry::
|
||||
|
|
@ -387,7 +439,7 @@ set_from_depth(float depth) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::has_from_depth
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns true if the collision entry knows how "deep"
|
||||
// the collision was from the collided-from object; that
|
||||
// is, how far from the surface of the collided-from
|
||||
|
|
@ -400,7 +452,7 @@ has_from_depth() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionEntry::get_from_depth
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns how "deep" the collision was from the
|
||||
// collided-from object; that is, how far from the
|
||||
// surface of the collided-from object the colliding
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ CollisionEntry(const CollisionEntry ©) :
|
|||
_wrt_space(copy._wrt_space),
|
||||
_inv_wrt_space(copy._inv_wrt_space),
|
||||
_flags(copy._flags),
|
||||
_from_pos_delta(copy._from_pos_delta),
|
||||
_into_intersection_point(copy._into_intersection_point),
|
||||
_into_surface_normal(copy._into_surface_normal),
|
||||
_into_depth(copy._into_depth)
|
||||
|
|
@ -60,6 +61,7 @@ operator = (const CollisionEntry ©) {
|
|||
_wrt_space = copy._wrt_space;
|
||||
_inv_wrt_space = copy._inv_wrt_space;
|
||||
_flags = copy._flags;
|
||||
_from_pos_delta = copy._from_pos_delta;
|
||||
_into_intersection_point = copy._into_intersection_point;
|
||||
_into_surface_normal = copy._into_surface_normal;
|
||||
_into_depth = copy._into_depth;
|
||||
|
|
@ -74,6 +76,6 @@ operator = (const CollisionEntry ©) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CollisionEntry::
|
||||
compute_from_surface_normal() {
|
||||
_from_surface_normal = get_into_surface_normal() * get_inv_wrt_space();
|
||||
_from_surface_normal = get_into_surface_normal() * get_inv_wrt_mat();
|
||||
_flags |= F_has_from_surface_normal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "collisionNode.h"
|
||||
#include "collisionRecorder.h"
|
||||
|
||||
#include "transformState.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "luse.h"
|
||||
#include "pointerTo.h"
|
||||
|
|
@ -60,14 +61,19 @@ PUBLISHED:
|
|||
INLINE PandaNode *get_into_node() const;
|
||||
INLINE const NodePath &get_into_node_path() const;
|
||||
|
||||
INLINE const LMatrix4f &get_from_space() const;
|
||||
INLINE const LMatrix4f &get_into_space() const;
|
||||
INLINE const LMatrix4f &get_wrt_space() const;
|
||||
INLINE const LMatrix4f &get_inv_wrt_space() const;
|
||||
INLINE const TransformState *get_from_space() const;
|
||||
INLINE const TransformState *get_into_space() const;
|
||||
INLINE const TransformState *get_wrt_space() const;
|
||||
INLINE const TransformState *get_inv_wrt_space() const;
|
||||
|
||||
INLINE void set_from_velocity(const LVector3f &vel);
|
||||
INLINE bool has_from_velocity() const;
|
||||
INLINE const LVector3f &get_from_velocity() const;
|
||||
INLINE const LMatrix4f &get_from_mat() const;
|
||||
INLINE const LMatrix4f &get_into_mat() const;
|
||||
INLINE const LMatrix4f &get_wrt_mat() const;
|
||||
INLINE const LMatrix4f &get_inv_wrt_mat() const;
|
||||
|
||||
INLINE void set_from_pos_delta(const LVector3f &vel);
|
||||
INLINE bool has_from_pos_delta() const;
|
||||
INLINE const LVector3f &get_from_pos_delta() const;
|
||||
|
||||
INLINE void set_into_intersection_point(const LPoint3f &point);
|
||||
INLINE bool has_into_intersection_point() const;
|
||||
|
|
@ -103,10 +109,10 @@ private:
|
|||
PT(CollisionNode) _from_node;
|
||||
PT(PandaNode) _into_node;
|
||||
NodePath _into_node_path;
|
||||
LMatrix4f _from_space;
|
||||
LMatrix4f _into_space;
|
||||
LMatrix4f _wrt_space;
|
||||
LMatrix4f _inv_wrt_space;
|
||||
CPT(TransformState) _from_space;
|
||||
CPT(TransformState) _into_space;
|
||||
CPT(TransformState) _wrt_space;
|
||||
CPT(TransformState) _inv_wrt_space;
|
||||
|
||||
enum Flags {
|
||||
F_has_into_intersection_point = 0x0001,
|
||||
|
|
@ -114,12 +120,12 @@ private:
|
|||
F_has_from_surface_normal = 0x0004,
|
||||
F_has_into_depth = 0x0008,
|
||||
F_has_from_depth = 0x0010,
|
||||
F_has_from_velocity = 0x0020,
|
||||
F_has_from_pos_delta = 0x0020,
|
||||
};
|
||||
|
||||
int _flags;
|
||||
|
||||
LVector3f _from_velocity;
|
||||
LVector3f _from_pos_delta;
|
||||
LPoint3f _into_intersection_point;
|
||||
LVector3f _into_surface_normal;
|
||||
LVector3f _from_surface_normal;
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ handle_entries() {
|
|||
LVecBase3f pos = trans->get_pos();
|
||||
pos[2] += adjust;
|
||||
def._node->set_transform(trans->set_pos(pos));
|
||||
|
||||
} else {
|
||||
// Otherwise, go ahead and do the matrix math to do things
|
||||
// the old and clumsy way.
|
||||
|
|
|
|||
|
|
@ -167,10 +167,10 @@ get_node(int n) const {
|
|||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionLevelState::
|
||||
INLINE const TransformState *CollisionLevelState::
|
||||
get_space(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_colliders.size(), LMatrix4f::ident_mat());
|
||||
nassertr(has_collider(n), LMatrix4f::ident_mat());
|
||||
nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity());
|
||||
nassertr(has_collider(n), TransformState::make_identity());
|
||||
|
||||
return _colliders[n]._space;
|
||||
}
|
||||
|
|
@ -180,14 +180,40 @@ get_space(int n) const {
|
|||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &CollisionLevelState::
|
||||
INLINE const TransformState *CollisionLevelState::
|
||||
get_inv_space(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_colliders.size(), LMatrix4f::ident_mat());
|
||||
nassertr(has_collider(n), LMatrix4f::ident_mat());
|
||||
nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity());
|
||||
nassertr(has_collider(n), TransformState::make_identity());
|
||||
|
||||
return _colliders[n]._inv_space;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionLevelState::get_prev_space
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TransformState *CollisionLevelState::
|
||||
get_prev_space(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity());
|
||||
nassertr(has_collider(n), TransformState::make_identity());
|
||||
|
||||
return _colliders[n]._prev_space;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionLevelState::get_delta
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVector3f &CollisionLevelState::
|
||||
get_delta(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_colliders.size(), LVector3f::zero());
|
||||
nassertr(has_collider(n), LVector3f::zero());
|
||||
|
||||
return _colliders[n]._delta;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionLevelState::get_local_bound
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -64,20 +64,20 @@ prepare_collider(const ColliderDef &def) {
|
|||
GeometricBoundingVolume *gbv;
|
||||
DCAST_INTO_V(gbv, bv.make_copy());
|
||||
|
||||
if (def._node->has_velocity()) {
|
||||
// If the node has a velocity, we have to include the starting
|
||||
if (def._delta != LVector3f::zero()) {
|
||||
// If the node has a delta, we have to include the starting
|
||||
// point in the volume as well.
|
||||
|
||||
// Strictly speaking, we should actually transform gbv backward
|
||||
// by get_velocity(), and extend by *that* volume, instead of
|
||||
// by the delta(), and extend by *that* volume, instead of
|
||||
// just extending by the single point at -get_velocity().
|
||||
// However, assuming the solids within a moving CollisionNode
|
||||
// tend to be near the origin, this will generally produce the
|
||||
// same results, and is much easier to compute.
|
||||
gbv->extend_by(LPoint3f(-def._node->get_velocity()));
|
||||
gbv->extend_by(LPoint3f(-def._delta));
|
||||
}
|
||||
|
||||
gbv->xform(def._space);
|
||||
gbv->xform(def._space->get_mat());
|
||||
_local_bounds.push_back(gbv);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@
|
|||
#include "geometricBoundingVolume.h"
|
||||
#include "nodePath.h"
|
||||
#include "workingNodePath.h"
|
||||
|
||||
#include "transformState.h"
|
||||
#include "pointerTo.h"
|
||||
#include "plist.h"
|
||||
|
||||
class CollisionSolid;
|
||||
|
|
@ -44,8 +45,10 @@ public:
|
|||
public:
|
||||
CollisionSolid *_collider;
|
||||
CollisionNode *_node;
|
||||
LMatrix4f _space;
|
||||
LMatrix4f _inv_space;
|
||||
CPT(TransformState) _space;
|
||||
CPT(TransformState) _inv_space;
|
||||
CPT(TransformState) _prev_space;
|
||||
LVector3f _delta;
|
||||
};
|
||||
|
||||
INLINE CollisionLevelState(const NodePath &node_path);
|
||||
|
|
@ -72,8 +75,10 @@ public:
|
|||
|
||||
INLINE CollisionSolid *get_collider(int n) const;
|
||||
INLINE CollisionNode *get_node(int n) const;
|
||||
INLINE const LMatrix4f &get_space(int n) const;
|
||||
INLINE const LMatrix4f &get_inv_space(int n) const;
|
||||
INLINE const TransformState *get_space(int n) const;
|
||||
INLINE const TransformState *get_inv_space(int n) const;
|
||||
INLINE const TransformState *get_prev_space(int n) const;
|
||||
INLINE const LVector3f &get_delta(int n) const;
|
||||
INLINE const GeometricBoundingVolume *get_local_bound(int n) const;
|
||||
INLINE const GeometricBoundingVolume *get_parent_bound(int n) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -216,10 +216,15 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|||
trav->traverse(next_data);
|
||||
}
|
||||
|
||||
if (has_velocity()) {
|
||||
// Determine the previous frame's position, relative to the
|
||||
// current position.
|
||||
NodePath node_path = data._node_path.get_node_path();
|
||||
CPT(TransformState) transform = node_path.get_net_transform()->invert_compose(node_path.get_net_prev_transform());
|
||||
|
||||
if (!transform->is_identity()) {
|
||||
// If we have a velocity, also draw the previous frame's position,
|
||||
// ghosted.
|
||||
CPT(TransformState) transform = TransformState::make_pos(-get_velocity());
|
||||
|
||||
for (si = _solids.begin(); si != _solids.end(); ++si) {
|
||||
CollisionSolid *solid = (*si);
|
||||
PandaNode *node = solid->get_viz();
|
||||
|
|
|
|||
|
|
@ -108,9 +108,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
const CollisionSphere *sphere;
|
||||
DCAST_INTO_R(sphere, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_center = sphere->get_center() * entry.get_wrt_space();
|
||||
LPoint3f from_center = sphere->get_center() * entry.get_wrt_mat();
|
||||
LVector3f from_radius_v =
|
||||
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_space();
|
||||
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_mat();
|
||||
float from_radius = length(from_radius_v);
|
||||
|
||||
float dist = dist_to_plane(from_center);
|
||||
|
|
@ -126,7 +126,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
}
|
||||
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
|
||||
|
||||
LVector3f from_normal = get_normal() * entry.get_inv_wrt_space();
|
||||
LVector3f from_normal = get_normal() * entry.get_inv_wrt_mat();
|
||||
float from_depth = from_radius - dist;
|
||||
|
||||
new_entry->set_into_surface_normal(get_normal());
|
||||
|
|
@ -147,8 +147,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
|
|||
const CollisionRay *ray;
|
||||
DCAST_INTO_R(ray, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_origin = ray->get_origin() * entry.get_wrt_space();
|
||||
LVector3f from_direction = ray->get_direction() * entry.get_wrt_space();
|
||||
LPoint3f from_origin = ray->get_origin() * entry.get_wrt_mat();
|
||||
LVector3f from_direction = ray->get_direction() * entry.get_wrt_mat();
|
||||
|
||||
float t;
|
||||
if (!_plane.intersects_line(t, from_origin, from_direction)) {
|
||||
|
|
|
|||
|
|
@ -273,15 +273,15 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
const CollisionSphere *sphere;
|
||||
DCAST_INTO_R(sphere, entry.get_from(), 0);
|
||||
|
||||
LPoint3f orig_center = sphere->get_center() * entry.get_wrt_space();
|
||||
LPoint3f orig_center = sphere->get_center() * entry.get_wrt_mat();
|
||||
LPoint3f from_center = orig_center;
|
||||
bool moved_from_center = false;
|
||||
|
||||
if (entry.has_from_velocity()) {
|
||||
// If we have a velocity indication, we use that to determine some
|
||||
if (entry.has_from_pos_delta()) {
|
||||
// If we have a pos_delta indication, we use that to determine some
|
||||
// more properties of the collision.
|
||||
LPoint3f b = from_center;
|
||||
LPoint3f a = (sphere->get_center() - entry.get_from_velocity()) * entry.get_wrt_space();
|
||||
LPoint3f a = (sphere->get_center() - entry.get_from_pos_delta()) * entry.get_wrt_mat();
|
||||
|
||||
LVector3f delta = b - a;
|
||||
// First, there is no collision if the "from" object is moving in
|
||||
|
|
@ -316,7 +316,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
}
|
||||
|
||||
LVector3f from_radius_v =
|
||||
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_space();
|
||||
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_mat();
|
||||
float from_radius = length(from_radius_v);
|
||||
|
||||
float dist = dist_to_plane(from_center);
|
||||
|
|
@ -408,8 +408,8 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
new_entry->set_into_surface_normal(get_normal());
|
||||
new_entry->set_into_depth(into_depth);
|
||||
|
||||
LVector3f from_normal = get_normal() * entry.get_inv_wrt_space();
|
||||
LVector3f from_depth_vec = (get_normal() * into_depth) * entry.get_inv_wrt_space();
|
||||
LVector3f from_normal = get_normal() * entry.get_inv_wrt_mat();
|
||||
LVector3f from_depth_vec = (get_normal() * into_depth) * entry.get_inv_wrt_mat();
|
||||
new_entry->set_from_surface_normal(from_normal);
|
||||
new_entry->set_from_depth(from_depth_vec.length());
|
||||
|
||||
|
|
@ -434,8 +434,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
|
|||
const CollisionRay *ray;
|
||||
DCAST_INTO_R(ray, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_origin = ray->get_origin() * entry.get_wrt_space();
|
||||
LVector3f from_direction = ray->get_direction() * entry.get_wrt_space();
|
||||
LPoint3f from_origin = ray->get_origin() * entry.get_wrt_mat();
|
||||
LVector3f from_direction = ray->get_direction() * entry.get_wrt_mat();
|
||||
|
||||
float t;
|
||||
if (!get_plane().intersects_line(t, from_origin, from_direction)) {
|
||||
|
|
@ -483,8 +483,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
|
|||
const CollisionSegment *segment;
|
||||
DCAST_INTO_R(segment, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_a = segment->get_point_a() * entry.get_wrt_space();
|
||||
LPoint3f from_b = segment->get_point_b() * entry.get_wrt_space();
|
||||
LPoint3f from_a = segment->get_point_a() * entry.get_wrt_mat();
|
||||
LPoint3f from_b = segment->get_point_b() * entry.get_wrt_mat();
|
||||
LPoint3f from_direction = from_b - from_a;
|
||||
|
||||
float t;
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
const CollisionSphere *sphere;
|
||||
DCAST_INTO_R(sphere, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_center = sphere->get_center() * entry.get_wrt_space();
|
||||
LPoint3f from_center = sphere->get_center() * entry.get_wrt_mat();
|
||||
LVector3f from_radius_v =
|
||||
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_space();
|
||||
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_mat();
|
||||
float from_radius = length(from_radius_v);
|
||||
|
||||
LPoint3f into_center = _center;
|
||||
|
|
@ -161,7 +161,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
new_entry->set_into_intersection_point(into_intersection_point);
|
||||
new_entry->set_into_depth(into_depth);
|
||||
|
||||
LVector3f from_depth_vec = (into_normal * into_depth) * entry.get_inv_wrt_space();
|
||||
LVector3f from_depth_vec = (into_normal * into_depth) * entry.get_inv_wrt_mat();
|
||||
new_entry->set_from_depth(from_depth_vec.length());
|
||||
|
||||
return new_entry;
|
||||
|
|
@ -177,8 +177,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
|
|||
const CollisionRay *ray;
|
||||
DCAST_INTO_R(ray, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_origin = ray->get_origin() * entry.get_wrt_space();
|
||||
LVector3f from_direction = ray->get_direction() * entry.get_wrt_space();
|
||||
LPoint3f from_origin = ray->get_origin() * entry.get_wrt_mat();
|
||||
LVector3f from_direction = ray->get_direction() * entry.get_wrt_mat();
|
||||
|
||||
double t1, t2;
|
||||
if (!intersects_line(t1, t2, from_origin, from_direction)) {
|
||||
|
|
@ -223,8 +223,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
|
|||
const CollisionSegment *segment;
|
||||
DCAST_INTO_R(segment, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_a = segment->get_point_a() * entry.get_wrt_space();
|
||||
LPoint3f from_b = segment->get_point_b() * entry.get_wrt_space();
|
||||
LPoint3f from_a = segment->get_point_a() * entry.get_wrt_mat();
|
||||
LPoint3f from_b = segment->get_point_b() * entry.get_wrt_mat();
|
||||
LVector3f from_direction = from_b - from_a;
|
||||
|
||||
double t1, t2;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,36 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionTraverser::set_respect_prev_transform
|
||||
// Access: Public
|
||||
// Description: Sets the flag that indicates whether the
|
||||
// prev_transform stored on a node (as updated via
|
||||
// set_fluid_pos(), etc.) is respected to calculate
|
||||
// collisions. If this is true, certain types of
|
||||
// collision tests will be enhanced by the information
|
||||
// about objects in motion. If this is false, objects
|
||||
// are always considered to be static. The default is
|
||||
// false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionTraverser::
|
||||
set_respect_prev_transform(bool flag) {
|
||||
_respect_prev_transform = flag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionTraverser::get_respect_prev_transform
|
||||
// Access: Public
|
||||
// Description: Returns the flag that indicates whether the
|
||||
// prev_transform stored on a node is respected to
|
||||
// calculate collisions. See
|
||||
// set_respect_prev_transform().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CollisionTraverser::
|
||||
get_respect_prev_transform() const {
|
||||
return _respect_prev_transform;
|
||||
}
|
||||
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions");
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CollisionTraverser::
|
||||
CollisionTraverser() {
|
||||
_respect_prev_transform = false;
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
_recorder = (CollisionRecorder *)NULL;
|
||||
#endif
|
||||
|
|
@ -262,17 +263,6 @@ traverse(const NodePath &root) {
|
|||
}
|
||||
}
|
||||
|
||||
if (auto_clear_velocity) {
|
||||
// Clear all the velocities for next time.
|
||||
OrderedColliders::iterator ci;
|
||||
for (ci = _ordered_colliders.begin();
|
||||
ci != _ordered_colliders.end();
|
||||
++ci) {
|
||||
CollisionNode *node = (*ci);
|
||||
node->clear_velocity();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
if (has_recorder()) {
|
||||
get_recorder()->end_traversal();
|
||||
|
|
@ -280,6 +270,20 @@ traverse(const NodePath &root) {
|
|||
#endif // DO_COLLISION_RECORDING
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionTraverser::reset_prev_transform
|
||||
// Access: Public
|
||||
// Description: Once the collision traversal has finished, resets all
|
||||
// of the velocity deltas in the scene graph by setting
|
||||
// the "previous" transform to the current transform.
|
||||
// This must be called at least once per frame for
|
||||
// collisions to respect this velocity setting properly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CollisionTraverser::
|
||||
reset_prev_transform(const NodePath &root) {
|
||||
r_reset_prev_transform(root.node());
|
||||
}
|
||||
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionTraverser::set_recorder
|
||||
|
|
@ -381,16 +385,22 @@ prepare_colliders(CollisionLevelState &level_state) {
|
|||
|
||||
CollisionLevelState::ColliderDef def;
|
||||
def._node = cnode;
|
||||
NodePath root;
|
||||
NodePath cnode_path(cnode);
|
||||
def._space = cnode_path.get_mat(root);
|
||||
def._inv_space = root.get_mat(cnode_path);
|
||||
def._space = cnode_path.get_net_transform();
|
||||
def._inv_space = def._space->invert_compose(TransformState::make_identity());
|
||||
def._prev_space = cnode_path.get_net_prev_transform();
|
||||
if (_respect_prev_transform) {
|
||||
def._delta = cnode_path.get_pos_delta();
|
||||
} else {
|
||||
def._delta = LVector3f::zero();
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (def._space.is_nan()) {
|
||||
if (def._space->is_invalid()) {
|
||||
collide_cat.error()
|
||||
<< "Collider " << *cnode
|
||||
<< " has become NaN. Dropping from traverser.\n";
|
||||
<< " has become invalid. Dropping from traverser.\n";
|
||||
// This is safe to do while traversing the list of colliders,
|
||||
// because we do not increment i in this case.
|
||||
remove_collider(cnode);
|
||||
|
|
@ -435,7 +445,7 @@ r_traverse(CollisionLevelState &level_state) {
|
|||
CollisionEntry entry;
|
||||
entry._into_node = cnode;
|
||||
entry._into_node_path = level_state.get_node_path();
|
||||
entry._into_space = entry._into_node_path.get_mat(NodePath());
|
||||
entry._into_space = entry._into_node_path.get_net_transform();
|
||||
|
||||
int num_colliders = level_state.get_num_colliders();
|
||||
for (int c = 0; c < num_colliders; c++) {
|
||||
|
|
@ -447,16 +457,26 @@ r_traverse(CollisionLevelState &level_state) {
|
|||
entry._from = level_state.get_collider(c);
|
||||
entry._from_space = level_state.get_space(c);
|
||||
|
||||
if (entry._from_node->has_velocity()) {
|
||||
entry.set_from_velocity(entry._from_node->get_velocity());
|
||||
}
|
||||
LVector3f from_delta = level_state.get_delta(c);
|
||||
|
||||
NodePath root;
|
||||
const LMatrix4f &into_space_inv =
|
||||
root.get_mat(entry._into_node_path);
|
||||
entry._wrt_space = entry._from_space * into_space_inv;
|
||||
entry._inv_wrt_space =
|
||||
entry._into_space * level_state.get_inv_space(c);
|
||||
entry._wrt_space = entry._into_space->invert_compose(entry._from_space);
|
||||
entry._inv_wrt_space = entry._from_space->invert_compose(entry._into_space);
|
||||
if (_respect_prev_transform) {
|
||||
CPT(TransformState) from_prev_space = level_state.get_prev_space(c);
|
||||
CPT(TransformState) inv_wrt_prev_space = from_prev_space->invert_compose(entry._into_node_path.get_net_prev_transform());
|
||||
|
||||
LVector3f into_delta = entry._inv_wrt_space->get_pos() - inv_wrt_prev_space->get_pos();
|
||||
LVector3f delta = from_delta - into_delta;
|
||||
if (delta != LVector3f::zero()) {
|
||||
/*
|
||||
if (entry._from_node->get_name() == "cSphereNode" && entry._into_node->get_name() == "MickeyBlatherSphere") {
|
||||
cerr << "from_delta = " << from_delta << " into_delta = "
|
||||
<< into_delta << " delta = " << delta << "\n";
|
||||
}
|
||||
*/
|
||||
entry.set_from_pos_delta(delta);
|
||||
}
|
||||
}
|
||||
|
||||
compare_collider_to_node(entry,
|
||||
level_state.get_parent_bound(c),
|
||||
|
|
@ -485,7 +505,7 @@ r_traverse(CollisionLevelState &level_state) {
|
|||
CollisionEntry entry;
|
||||
entry._into_node = gnode;
|
||||
entry._into_node_path = level_state.get_node_path();
|
||||
entry._into_space = entry._into_node_path.get_mat(NodePath());
|
||||
entry._into_space = entry._into_node_path.get_net_transform();
|
||||
|
||||
int num_colliders = level_state.get_num_colliders();
|
||||
for (int c = 0; c < num_colliders; c++) {
|
||||
|
|
@ -495,12 +515,8 @@ r_traverse(CollisionLevelState &level_state) {
|
|||
entry._from = level_state.get_collider(c);
|
||||
entry._from_space = level_state.get_space(c);
|
||||
|
||||
NodePath root;
|
||||
const LMatrix4f &into_space_inv =
|
||||
root.get_mat(entry._into_node_path);
|
||||
entry._wrt_space = entry._from_space * into_space_inv;
|
||||
entry._inv_wrt_space =
|
||||
entry._into_space * level_state.get_inv_space(c);
|
||||
entry._wrt_space = entry._into_space->invert_compose(entry._from_space);
|
||||
entry._inv_wrt_space = entry._from_space->invert_compose(entry._into_space);
|
||||
|
||||
compare_collider_to_geom_node(entry,
|
||||
level_state.get_parent_bound(c),
|
||||
|
|
@ -716,12 +732,6 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
|
|||
|
||||
nassertr(_ordered_colliders.size() == _colliders.size(), false);
|
||||
|
||||
if (auto_clear_velocity) {
|
||||
// Clear the velocity on the removed node, to be consistent
|
||||
// with nodes that were not removed.
|
||||
node->clear_velocity();
|
||||
}
|
||||
|
||||
} else {
|
||||
// This collider references some other handler; keep it.
|
||||
++ci;
|
||||
|
|
@ -730,3 +740,17 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
|
|||
|
||||
return hi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionTraverser::r_reset_prev_transform
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CollisionTraverser::
|
||||
r_reset_prev_transform(PandaNode *node) {
|
||||
node->reset_prev_transform();
|
||||
int num_children = node->get_num_children();
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
r_reset_prev_transform(node->get_child(i));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ PUBLISHED:
|
|||
CollisionTraverser();
|
||||
~CollisionTraverser();
|
||||
|
||||
INLINE void set_respect_prev_transform(bool flag);
|
||||
INLINE bool get_respect_prev_transform() const;
|
||||
|
||||
void add_collider(CollisionNode *node, CollisionHandler *handler);
|
||||
bool remove_collider(CollisionNode *node);
|
||||
bool has_collider(CollisionNode *node) const;
|
||||
|
|
@ -62,6 +65,7 @@ PUBLISHED:
|
|||
void clear_colliders();
|
||||
|
||||
void traverse(const NodePath &root);
|
||||
void reset_prev_transform(const NodePath &root);
|
||||
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
void set_recorder(CollisionRecorder *recorder);
|
||||
|
|
@ -93,6 +97,8 @@ private:
|
|||
const GeometricBoundingVolume *from_node_gbv,
|
||||
const GeometricBoundingVolume *solid_gbv);
|
||||
|
||||
void r_reset_prev_transform(PandaNode *node);
|
||||
|
||||
private:
|
||||
PT(CollisionHandler) _default_handler;
|
||||
TypeHandle _graph_type;
|
||||
|
|
@ -107,6 +113,7 @@ private:
|
|||
|
||||
Handlers::iterator remove_handler(Handlers::iterator hi);
|
||||
|
||||
bool _respect_prev_transform;
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
CollisionRecorder *_recorder;
|
||||
#endif // DO_COLLISION_RECORDING
|
||||
|
|
|
|||
|
|
@ -130,17 +130,17 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||
const CollisionSphere *sphere;
|
||||
DCAST_INTO_R(sphere, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_a = sphere->get_center() * entry.get_wrt_space();
|
||||
LPoint3f from_a = sphere->get_center() * entry.get_wrt_mat();
|
||||
LPoint3f from_b = from_a;
|
||||
|
||||
if (entry.has_from_velocity()) {
|
||||
from_a = (sphere->get_center() - entry.get_from_velocity()) * entry.get_wrt_space();
|
||||
if (entry.has_from_pos_delta()) {
|
||||
from_a = (sphere->get_center() - entry.get_from_pos_delta()) * entry.get_wrt_mat();
|
||||
}
|
||||
|
||||
LVector3f from_direction = from_b - from_a;
|
||||
|
||||
LVector3f from_radius_v =
|
||||
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_space();
|
||||
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_mat();
|
||||
float from_radius = length(from_radius_v);
|
||||
|
||||
double t1, t2;
|
||||
|
|
@ -187,8 +187,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
|
|||
const CollisionRay *ray;
|
||||
DCAST_INTO_R(ray, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_origin = ray->get_origin() * entry.get_wrt_space();
|
||||
LVector3f from_direction = ray->get_direction() * entry.get_wrt_space();
|
||||
LPoint3f from_origin = ray->get_origin() * entry.get_wrt_mat();
|
||||
LVector3f from_direction = ray->get_direction() * entry.get_wrt_mat();
|
||||
|
||||
double t1, t2;
|
||||
if (!intersects_line(t1, t2, from_origin, from_direction, 0.0f)) {
|
||||
|
|
@ -233,8 +233,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
|
|||
const CollisionSegment *segment;
|
||||
DCAST_INTO_R(segment, entry.get_from(), 0);
|
||||
|
||||
LPoint3f from_a = segment->get_point_a() * entry.get_wrt_space();
|
||||
LPoint3f from_b = segment->get_point_b() * entry.get_wrt_space();
|
||||
LPoint3f from_a = segment->get_point_a() * entry.get_wrt_mat();
|
||||
LPoint3f from_b = segment->get_point_b() * entry.get_wrt_mat();
|
||||
LVector3f from_direction = from_b - from_a;
|
||||
|
||||
double t1, t2;
|
||||
|
|
@ -689,7 +689,7 @@ set_intersection_point(CollisionEntry *new_entry,
|
|||
new_entry->set_into_surface_normal(normal);
|
||||
new_entry->set_into_depth(depth);
|
||||
|
||||
LVector3f from_depth_vec = (normal * depth) * new_entry->get_inv_wrt_space();
|
||||
LVector3f from_depth_vec = (normal * depth) * new_entry->get_inv_wrt_mat();
|
||||
new_entry->set_from_depth(from_depth_vec.length());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,11 +43,6 @@ ConfigureFn(config_collide) {
|
|||
init_libcollide();
|
||||
}
|
||||
|
||||
// Set this false to stop the CollisionTraverser from automatically
|
||||
// clearing the velocity associated with its CollisionNodes after it
|
||||
// has traversed them. Mainly useful for visualizing the velocities.
|
||||
const bool auto_clear_velocity = config_collide.GetBool("auto-clear-velocity", true);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libcollide
|
||||
// Description: Initializes the library. This must be called at
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
|
||||
NotifyCategoryDecl(collide, EXPCL_PANDA, EXPTP_PANDA);
|
||||
|
||||
extern const bool auto_clear_velocity;
|
||||
|
||||
extern EXPCL_PANDA void init_libcollide();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ collect(PandaNode *node, int attrib_types) {
|
|||
nassertv(_transform != (TransformState *)NULL);
|
||||
_transform = _transform->compose(node->get_transform());
|
||||
node->set_transform(TransformState::make_identity());
|
||||
node->reset_prev_transform();
|
||||
}
|
||||
|
||||
if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
|
||||
|
|
@ -141,6 +142,7 @@ void AccumulatedAttribs::
|
|||
apply_to_node(PandaNode *node, int attrib_types) {
|
||||
if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
|
||||
node->set_transform(_transform->compose(node->get_transform()));
|
||||
node->reset_prev_transform();
|
||||
_transform = TransformState::make_identity();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -417,7 +417,7 @@ get_state() const {
|
|||
// Description: Changes the complete state object on this node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_state(const RenderState *state) const {
|
||||
set_state(const RenderState *state) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_state(state);
|
||||
}
|
||||
|
|
@ -450,7 +450,7 @@ get_transform() const {
|
|||
// Description: Changes the complete transform object on this node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_transform(const TransformState *transform) const {
|
||||
set_transform(const TransformState *transform) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_transform(transform);
|
||||
}
|
||||
|
|
@ -466,17 +466,73 @@ get_net_transform() const {
|
|||
return r_get_net_transform(_head);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_prev_transform
|
||||
// Access: Published
|
||||
// Description: Returns the transform that has been set as this
|
||||
// node's "previous" position. See
|
||||
// set_prev_transform().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TransformState *NodePath::
|
||||
get_prev_transform() const {
|
||||
nassertr_always(!is_empty(), TransformState::make_identity());
|
||||
return node()->get_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_prev_transform
|
||||
// Access: Published
|
||||
// Description: Sets the transform that represents this node's
|
||||
// "previous" position, one frame ago, for the purposes
|
||||
// of detecting motion for accurate collision
|
||||
// calculations.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_prev_transform(const TransformState *transform) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_prev_transform(transform);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_net_prev_transform
|
||||
// Access: Published
|
||||
// Description: Returns the net "previous" transform on this node
|
||||
// from the root. See set_prev_transform().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(TransformState) NodePath::
|
||||
get_net_prev_transform() const {
|
||||
uncollapse_head();
|
||||
return r_get_net_prev_transform(_head);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_pos
|
||||
// Access: Published
|
||||
// Description: Sets the translation component of the transform,
|
||||
// leaving rotation and scale untouched.
|
||||
// leaving rotation and scale untouched. This also
|
||||
// resets the node's "previous" position, so that the
|
||||
// collision system will see the node as having suddenly
|
||||
// appeared in the new position, without passing any
|
||||
// points in between.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_pos(float x, float y, float z) {
|
||||
set_pos(LPoint3f(x, y, z));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_fluid_pos
|
||||
// Access: Published
|
||||
// Description: Sets the translation component, without changing the
|
||||
// "previous" position, so that the collision system
|
||||
// will see the node as moving fluidly from its previous
|
||||
// position to its new position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_fluid_pos(float x, float y, float z) {
|
||||
set_fluid_pos(LPoint3f(x, y, z));
|
||||
}
|
||||
|
||||
INLINE float NodePath::
|
||||
get_x() const {
|
||||
return get_pos()[0];
|
||||
|
|
@ -870,59 +926,6 @@ get_distance(const NodePath &other) const {
|
|||
return length(LVector3f(pos));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_velocity
|
||||
// Access: Published
|
||||
// Description: Sets the velocity of this node. This is a delta from
|
||||
// the position of this node in the previous frame,
|
||||
// relative to the node's parent. The value should not
|
||||
// be transformed by the node's transformation (it is in
|
||||
// the coordinate system of the node's parent). This
|
||||
// has meaning only to the collision subsystem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_velocity(const LVector3f &velocity) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_velocity(velocity);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_velocity
|
||||
// Access: Published
|
||||
// Description: Resets the velocity of this node to zero. See
|
||||
// set_velocity().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
clear_velocity() {
|
||||
nassertv_always(!is_empty());
|
||||
node()->clear_velocity();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_velocity
|
||||
// Access: Published
|
||||
// Description: Returns true if a nonzero velocity has been set on
|
||||
// this node, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodePath::
|
||||
has_velocity() const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
return node()->has_velocity();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_velocity
|
||||
// Access: Published
|
||||
// Description: Returns the velocity previously set on this node via
|
||||
// set_velocity(), or LVector3f::zero() if no velocity
|
||||
// has been set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVector3f &NodePath::
|
||||
get_velocity() const {
|
||||
nassertr_always(!is_empty(), LVector3f::zero());
|
||||
return node()->get_velocity();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_color_scale
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -291,6 +291,9 @@ reparent_to(const NodePath &other, int sort) {
|
|||
uncollapse_head();
|
||||
other.uncollapse_head();
|
||||
PandaNode::reparent(other._head, _head, sort);
|
||||
|
||||
// Reparenting implicitly resents the delta vector.
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -309,7 +312,14 @@ wrt_reparent_to(const NodePath &other, int sort) {
|
|||
nassertv_always(!is_empty());
|
||||
nassertv_always(!other.is_empty());
|
||||
|
||||
set_transform(get_transform(other));
|
||||
if (get_transform() == get_prev_transform()) {
|
||||
set_transform(get_transform(other));
|
||||
node()->reset_prev_transform();
|
||||
} else {
|
||||
set_transform(get_transform(other));
|
||||
set_prev_transform(get_prev_transform(other));
|
||||
}
|
||||
|
||||
reparent_to(other, sort);
|
||||
}
|
||||
|
||||
|
|
@ -343,6 +353,11 @@ instance_to(const NodePath &other, int sort) const {
|
|||
NodePath new_instance;
|
||||
new_instance._head = PandaNode::attach(other._head, node(), sort);
|
||||
|
||||
// instance_to() doesn't reset the velocity delta, unlike most of
|
||||
// the other reparenting operations. The reasoning is that
|
||||
// instance_to() is not necessarily a reparenting operation, since
|
||||
// it doesn't change the original instance.
|
||||
|
||||
return new_instance;
|
||||
}
|
||||
|
||||
|
|
@ -369,7 +384,7 @@ instance_under_node(const NodePath &other, const string &name, int sort) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::copy_to
|
||||
// Access: Published
|
||||
// Description: Functions exactly like instance_to(), except a deep
|
||||
// Description: Functions like instance_to(), except a deep
|
||||
// copy is made of the referenced node and all of its
|
||||
// descendents, which is then parented to the indicated
|
||||
// node. A NodePath to the newly created copy is
|
||||
|
|
@ -386,6 +401,8 @@ copy_to(const NodePath &other, int sort) const {
|
|||
PT(PandaNode) copy_node = source_node->copy_subgraph();
|
||||
nassertr(copy_node != (PandaNode *)NULL, fail());
|
||||
|
||||
copy_node->reset_prev_transform();
|
||||
|
||||
return other.attach_new_node(copy_node, sort);
|
||||
}
|
||||
|
||||
|
|
@ -444,6 +461,7 @@ remove_node() {
|
|||
// In either case, quietly do nothing except to ensure the
|
||||
// NodePath is clear.
|
||||
if (!is_empty() && !is_singleton()) {
|
||||
node()->reset_prev_transform();
|
||||
uncollapse_head();
|
||||
PandaNode::detach(_head);
|
||||
}
|
||||
|
|
@ -474,6 +492,7 @@ void NodePath::
|
|||
detach_node() {
|
||||
nassertv(_error_type != ET_not_found);
|
||||
if (!is_empty() && !is_singleton()) {
|
||||
node()->reset_prev_transform();
|
||||
uncollapse_head();
|
||||
PandaNode::detach(_head);
|
||||
}
|
||||
|
|
@ -546,7 +565,7 @@ get_state(const NodePath &other) const {
|
|||
// the other node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_state(const NodePath &other, const RenderState *state) const {
|
||||
set_state(const NodePath &other, const RenderState *state) {
|
||||
nassertv(_error_type == ET_ok && other._error_type == ET_ok);
|
||||
nassertv_always(!is_empty());
|
||||
|
||||
|
|
@ -594,7 +613,7 @@ get_transform(const NodePath &other) const {
|
|||
// other node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_transform(const NodePath &other, const TransformState *transform) const {
|
||||
set_transform(const NodePath &other, const TransformState *transform) {
|
||||
nassertv(_error_type == ET_ok && other._error_type == ET_ok);
|
||||
nassertv_always(!is_empty());
|
||||
|
||||
|
|
@ -610,16 +629,74 @@ set_transform(const NodePath &other, const TransformState *transform) const {
|
|||
set_transform(new_trans);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_prev_transform
|
||||
// Access: Published
|
||||
// Description: Returns the relative "previous" transform to this
|
||||
// node from the other node; i.e. the position of this
|
||||
// node in the previous frame, as seen by the other node
|
||||
// in the previous frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) NodePath::
|
||||
get_prev_transform(const NodePath &other) const {
|
||||
if (other.is_empty()) {
|
||||
return get_net_prev_transform();
|
||||
}
|
||||
if (is_empty()) {
|
||||
return other.get_net_prev_transform()->invert_compose(TransformState::make_identity());
|
||||
}
|
||||
|
||||
nassertr(verify_complete(), TransformState::make_identity());
|
||||
nassertr(other.verify_complete(), TransformState::make_identity());
|
||||
|
||||
int a_count, b_count;
|
||||
find_common_ancestor(*this, other, a_count, b_count);
|
||||
|
||||
CPT(TransformState) a_prev_transform = r_get_partial_prev_transform(_head, a_count);
|
||||
CPT(TransformState) b_prev_transform = r_get_partial_prev_transform(other._head, b_count);
|
||||
return b_prev_transform->invert_compose(a_prev_transform);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_prev_transform
|
||||
// Access: Published
|
||||
// Description: Sets the "previous" transform object on this node,
|
||||
// relative to the other node. This computes a new
|
||||
// transform object that will have the indicated value
|
||||
// when seen from the other node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_prev_transform(const NodePath &other, const TransformState *transform) {
|
||||
nassertv(_error_type == ET_ok && other._error_type == ET_ok);
|
||||
nassertv_always(!is_empty());
|
||||
|
||||
// First, we perform a wrt to the parent, to get the conversion.
|
||||
CPT(TransformState) rel_trans;
|
||||
if (has_parent()) {
|
||||
rel_trans = other.get_prev_transform(get_parent());
|
||||
} else {
|
||||
rel_trans = other.get_prev_transform(NodePath());
|
||||
}
|
||||
|
||||
CPT(TransformState) new_trans = rel_trans->compose(transform);
|
||||
set_prev_transform(new_trans);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_pos
|
||||
// Access: Published
|
||||
// Description: Sets the translation component of the transform,
|
||||
// leaving rotation and scale untouched.
|
||||
// leaving rotation and scale untouched. This also
|
||||
// resets the node's "previous" position, so that the
|
||||
// collision system will see the node as having suddenly
|
||||
// appeared in the new position, without passing any
|
||||
// points in between.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_pos(const LVecBase3f &pos) {
|
||||
nassertv_always(!is_empty());
|
||||
set_transform(get_transform()->set_pos(pos));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
void NodePath::
|
||||
|
|
@ -646,6 +723,44 @@ set_z(float z) {
|
|||
set_pos(pos);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_fluid_pos
|
||||
// Access: Published
|
||||
// Description: Sets the translation component, without changing the
|
||||
// "previous" position, so that the collision system
|
||||
// will see the node as moving fluidly from its previous
|
||||
// position to its new position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_fluid_pos(const LVecBase3f &pos) {
|
||||
nassertv_always(!is_empty());
|
||||
set_transform(get_transform()->set_pos(pos));
|
||||
}
|
||||
|
||||
void NodePath::
|
||||
set_fluid_x(float x) {
|
||||
nassertv_always(!is_empty());
|
||||
LPoint3f pos = get_pos();
|
||||
pos[0] = x;
|
||||
set_fluid_pos(pos);
|
||||
}
|
||||
|
||||
void NodePath::
|
||||
set_fluid_y(float y) {
|
||||
nassertv_always(!is_empty());
|
||||
LPoint3f pos = get_pos();
|
||||
pos[1] = y;
|
||||
set_fluid_pos(pos);
|
||||
}
|
||||
|
||||
void NodePath::
|
||||
set_fluid_z(float z) {
|
||||
nassertv_always(!is_empty());
|
||||
LPoint3f pos = get_pos();
|
||||
pos[2] = z;
|
||||
set_fluid_pos(pos);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_pos
|
||||
// Access: Published
|
||||
|
|
@ -657,6 +772,26 @@ get_pos() const {
|
|||
return get_transform()->get_pos();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_pos_delta
|
||||
// Access: Published
|
||||
// Description: Returns the delta vector from this node's position in
|
||||
// the previous frame (according to
|
||||
// set_prev_transform(), typically set via the use of
|
||||
// set_fluid_pos()) and its position in the current
|
||||
// frame. This is the vector used to determine
|
||||
// collisions. Generally, if the node was last
|
||||
// repositioned via set_pos(), the delta will be zero;
|
||||
// if it was adjusted via set_fluid_pos(), the delta
|
||||
// will represent the change from the previous frame's
|
||||
// position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LVector3f NodePath::
|
||||
get_pos_delta() const {
|
||||
nassertr_always(!is_empty(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||
return get_transform()->get_pos() - get_prev_transform()->get_pos();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_hpr
|
||||
// Access: Published
|
||||
|
|
@ -856,6 +991,7 @@ set_pos_hpr(const LVecBase3f &pos, const LVecBase3f &hpr) {
|
|||
transform = TransformState::make_pos_hpr_scale_shear
|
||||
(pos, hpr, transform->get_scale(), transform->get_shear());
|
||||
set_transform(transform);
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -885,6 +1021,7 @@ set_pos_hpr_scale(const LVecBase3f &pos, const LVecBase3f &hpr,
|
|||
nassertv_always(!is_empty());
|
||||
set_transform(TransformState::make_pos_hpr_scale
|
||||
(pos, hpr, scale));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -899,6 +1036,7 @@ set_pos_quat_scale(const LVecBase3f &pos, const LQuaternionf &quat,
|
|||
nassertv_always(!is_empty());
|
||||
set_transform(TransformState::make_pos_quat_scale
|
||||
(pos, quat, scale));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -913,6 +1051,7 @@ set_pos_hpr_scale_shear(const LVecBase3f &pos, const LVecBase3f &hpr,
|
|||
nassertv_always(!is_empty());
|
||||
set_transform(TransformState::make_pos_hpr_scale_shear
|
||||
(pos, hpr, scale, shear));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -927,6 +1066,7 @@ set_pos_quat_scale_shear(const LVecBase3f &pos, const LQuaternionf &quat,
|
|||
nassertv_always(!is_empty());
|
||||
set_transform(TransformState::make_pos_quat_scale_shear
|
||||
(pos, quat, scale, shear));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -938,6 +1078,7 @@ void NodePath::
|
|||
set_mat(const LMatrix4f &mat) {
|
||||
nassertv_always(!is_empty());
|
||||
set_transform(TransformState::make_mat(mat));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1003,6 +1144,7 @@ set_pos(const NodePath &other, const LVecBase3f &pos) {
|
|||
// If we didn't have a componentwise transform already, never
|
||||
// mind.
|
||||
set_transform(other, rel_transform->set_pos(pos));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1042,6 +1184,27 @@ get_pos(const NodePath &other) const {
|
|||
return get_transform(other)->get_pos();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_pos_delta
|
||||
// Access: Published
|
||||
// Description: Returns the delta vector from this node's position in
|
||||
// the previous frame (according to
|
||||
// set_prev_transform(), typically set via the use of
|
||||
// set_fluid_pos()) and its position in the current
|
||||
// frame, as seen in the indicated node's coordinate
|
||||
// space. This is the vector used to determine
|
||||
// collisions. Generally, if the node was last
|
||||
// repositioned via set_pos(), the delta will be zero;
|
||||
// if it was adjusted via set_fluid_pos(), the delta
|
||||
// will represent the change from the previous frame's
|
||||
// position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LVector3f NodePath::
|
||||
get_pos_delta(const NodePath &other) const {
|
||||
nassertr_always(!is_empty(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||
return get_transform(other)->get_pos() - get_prev_transform(other)->get_pos();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_hpr
|
||||
// Access: Published
|
||||
|
|
@ -1067,7 +1230,8 @@ set_hpr(const NodePath &other, const LVecBase3f &hpr) {
|
|||
set_transform(other, rel_transform->set_hpr(hpr));
|
||||
const TransformState *new_transform = get_transform();
|
||||
if (new_transform->has_components()) {
|
||||
set_pos_hpr_scale_shear(orig_pos, new_transform->get_hpr(), orig_scale, orig_shear);
|
||||
set_transform(TransformState::make_pos_hpr_scale_shear
|
||||
(orig_pos, new_transform->get_hpr(), orig_scale, orig_shear));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -1139,7 +1303,8 @@ set_quat(const NodePath &other, const LQuaternionf &quat) {
|
|||
set_transform(other, rel_transform->set_quat(quat));
|
||||
const TransformState *new_transform = get_transform();
|
||||
if (new_transform->has_components()) {
|
||||
set_pos_quat_scale_shear(orig_pos, new_transform->get_quat(), orig_scale, orig_shear);
|
||||
set_transform(TransformState::make_pos_quat_scale_shear
|
||||
(orig_pos, new_transform->get_quat(), orig_scale, orig_shear));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -1186,7 +1351,8 @@ set_scale(const NodePath &other, const LVecBase3f &scale) {
|
|||
set_transform(other, rel_transform->set_scale(scale));
|
||||
const TransformState *new_transform = get_transform();
|
||||
if (new_transform->has_components()) {
|
||||
set_pos_hpr_scale_shear(orig_pos, orig_hpr, new_transform->get_scale(), orig_shear);
|
||||
set_transform(TransformState::make_pos_hpr_scale_shear
|
||||
(orig_pos, orig_hpr, new_transform->get_scale(), orig_shear));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -1257,7 +1423,8 @@ set_shear(const NodePath &other, const LVecBase3f &shear) {
|
|||
set_transform(other, rel_transform->set_shear(shear));
|
||||
const TransformState *new_transform = get_transform();
|
||||
if (new_transform->has_components()) {
|
||||
set_pos_hpr_scale_shear(orig_pos, orig_hpr, orig_scale, new_transform->get_shear());
|
||||
set_transform(TransformState::make_pos_hpr_scale_shear
|
||||
(orig_pos, orig_hpr, orig_scale, new_transform->get_shear()));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -1338,6 +1505,7 @@ set_pos_hpr(const NodePath &other, const LVecBase3f &pos,
|
|||
// mind.
|
||||
set_transform(other, TransformState::make_pos_hpr_scale_shear
|
||||
(pos, hpr, rel_transform->get_scale(), rel_transform->get_shear()));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1376,6 +1544,7 @@ set_pos_hpr_scale(const NodePath &other,
|
|||
nassertv_always(!is_empty());
|
||||
set_transform(other, TransformState::make_pos_hpr_scale
|
||||
(pos, hpr, scale));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1392,6 +1561,7 @@ set_pos_quat_scale(const NodePath &other,
|
|||
nassertv_always(!is_empty());
|
||||
set_transform(other, TransformState::make_pos_quat_scale
|
||||
(pos, quat, scale));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1408,6 +1578,7 @@ set_pos_hpr_scale_shear(const NodePath &other,
|
|||
nassertv_always(!is_empty());
|
||||
set_transform(other, TransformState::make_pos_hpr_scale_shear
|
||||
(pos, hpr, scale, shear));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1424,6 +1595,7 @@ set_pos_quat_scale_shear(const NodePath &other,
|
|||
nassertv_always(!is_empty());
|
||||
set_transform(other, TransformState::make_pos_quat_scale_shear
|
||||
(pos, quat, scale, shear));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1455,6 +1627,7 @@ void NodePath::
|
|||
set_mat(const NodePath &other, const LMatrix4f &mat) {
|
||||
nassertv_always(!is_empty());
|
||||
set_transform(other, TransformState::make_mat(mat));
|
||||
node()->reset_prev_transform();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1525,106 +1698,6 @@ heads_up(const NodePath &other, const LPoint3f &point, const LVector3f &up) {
|
|||
set_quat(quat);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_velocity
|
||||
// Access: Published
|
||||
// Description: Returns the relative velocity to this node from the
|
||||
// other node; i.e. the velocity of this node as seen
|
||||
// from the other node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LVector3f NodePath::
|
||||
get_velocity(const NodePath &other) const {
|
||||
if (other.is_empty()) {
|
||||
return get_net_velocity();
|
||||
}
|
||||
if (is_empty()) {
|
||||
other.uncollapse_head();
|
||||
CPT(TransformState) net_transform = TransformState::make_identity();
|
||||
CPT(TransformState) parent_transform = net_transform;
|
||||
LVector3f net_velocity = LVector3f::zero();
|
||||
r_get_net_velocity(other._head, net_velocity, net_transform, parent_transform);
|
||||
return -net_velocity;
|
||||
}
|
||||
|
||||
nassertr(verify_complete(), LVector3f::zero());
|
||||
nassertr(other.verify_complete(), LVector3f::zero());
|
||||
|
||||
int a_count, b_count;
|
||||
find_common_ancestor(*this, other, a_count, b_count);
|
||||
|
||||
// Now compute the net velocity of each node, by working down from
|
||||
// the common ancestor.
|
||||
CPT(TransformState) a_transform = TransformState::make_identity();
|
||||
CPT(TransformState) a_parent_transform = a_transform;
|
||||
LVector3f a_velocity = LVector3f::zero();
|
||||
r_get_partial_velocity(_head, a_count, a_velocity, a_transform,
|
||||
a_parent_transform);
|
||||
|
||||
CPT(TransformState) b_transform = TransformState::make_identity();
|
||||
CPT(TransformState) b_parent_transform = b_transform;
|
||||
LVector3f b_velocity = LVector3f::zero();
|
||||
r_get_partial_velocity(other._head, b_count, b_velocity, b_transform,
|
||||
b_parent_transform);
|
||||
|
||||
LVector3f net_velocity = a_velocity - b_velocity;
|
||||
|
||||
// Finally, convert the net velocity back into the parent's
|
||||
// coordinate space.
|
||||
CPT(TransformState) a_parent_inverse =
|
||||
a_parent_transform->invert_compose(TransformState::make_identity());
|
||||
return net_velocity * a_parent_inverse->get_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_velocity
|
||||
// Access: Published
|
||||
// Description: Sets the velocity of this node, relative to the other
|
||||
// node. This computes a new velocity that will have
|
||||
// the indicated value when seen from the other node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_velocity(const NodePath &other, const LVector3f &velocity) {
|
||||
nassertv(_error_type == ET_ok && other._error_type == ET_ok);
|
||||
nassertv_always(!is_empty());
|
||||
|
||||
// First, we perform a wrt to the parent, to get the conversion.
|
||||
LVector3f rel_velocity;
|
||||
if (has_parent()) {
|
||||
rel_velocity = other.get_velocity(get_parent());
|
||||
} else {
|
||||
rel_velocity = other.get_velocity(NodePath());
|
||||
}
|
||||
|
||||
LVector3f new_velocity = velocity + rel_velocity;
|
||||
set_velocity(new_velocity);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_net_velocity
|
||||
// Access: Published
|
||||
// Description: Returns the relative "velocity" of this node (as
|
||||
// reported by get_velocity()) from the root of the
|
||||
// scene graph, accumulating all velocity values set on
|
||||
// ancestor nodes. The result is returned in the
|
||||
// coordinate space of the node's parent (the same
|
||||
// coordinate space in which get_velocity() is
|
||||
// returned).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LVector3f NodePath::
|
||||
get_net_velocity() const {
|
||||
uncollapse_head();
|
||||
CPT(TransformState) net_transform = TransformState::make_identity();
|
||||
CPT(TransformState) parent_transform = net_transform;
|
||||
LVector3f net_velocity = LVector3f::zero();
|
||||
r_get_net_velocity(_head, net_velocity, net_transform, parent_transform);
|
||||
|
||||
// Convert the net velocity back from global coordinates into the
|
||||
// parent's coordinate space.
|
||||
CPT(TransformState) parent_inverse =
|
||||
parent_transform->invert_compose(TransformState::make_identity());
|
||||
return net_velocity * parent_inverse->get_mat();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_color
|
||||
|
|
@ -3442,58 +3515,38 @@ r_get_partial_transform(NodePathComponent *comp, int n) const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::r_get_net_velocity
|
||||
// Function: NodePath::r_get_net_prev_transform
|
||||
// Access: Private
|
||||
// Description: Recursively determines the net velocity of the
|
||||
// indicated node; the result is returned in the global
|
||||
// coordinate space.
|
||||
// Description: Recursively determines the net "previous" transform
|
||||
// to the indicated component node from the root of the
|
||||
// graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
r_get_net_velocity(NodePathComponent *comp, LVector3f &net_vel,
|
||||
CPT(TransformState) &net_transform,
|
||||
CPT(TransformState) &parent_net_transform) const {
|
||||
if (comp != (NodePathComponent *)NULL) {
|
||||
r_get_net_velocity(comp->get_next(), net_vel, net_transform,
|
||||
parent_net_transform);
|
||||
|
||||
PandaNode *node = comp->get_node();
|
||||
if (node->has_velocity()) {
|
||||
LVector3f vel = node->get_velocity();
|
||||
net_vel += vel * net_transform->get_mat();
|
||||
}
|
||||
|
||||
CPT(TransformState) transform = node->get_transform();
|
||||
parent_net_transform = net_transform;
|
||||
net_transform = net_transform->compose(transform);
|
||||
CPT(TransformState) NodePath::
|
||||
r_get_net_prev_transform(NodePathComponent *comp) const {
|
||||
if (comp == (NodePathComponent *)NULL) {
|
||||
return TransformState::make_identity();
|
||||
} else {
|
||||
CPT(TransformState) transform = comp->get_node()->get_prev_transform();
|
||||
return r_get_net_prev_transform(comp->get_next())->compose(transform);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::r_get_partial_velocity
|
||||
// Function: NodePath::r_get_partial_prev_transform
|
||||
// Access: Private
|
||||
// Description: Recursively determines the net velocity of the
|
||||
// indicated component node from the nth node above it.
|
||||
// If n exceeds the length of the path, this returns the
|
||||
// net velocity from the root of the graph.
|
||||
// Description: Recursively determines the net "previous" transform
|
||||
// to the indicated component node from the nth node
|
||||
// above it. If n exceeds the length of the path, this
|
||||
// returns the net previous transform from the root of
|
||||
// the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
r_get_partial_velocity(NodePathComponent *comp, int n,
|
||||
LVector3f &net_vel,
|
||||
CPT(TransformState) &net_transform,
|
||||
CPT(TransformState) &parent_net_transform) const {
|
||||
if (n != 0 && comp != (NodePathComponent *)NULL) {
|
||||
r_get_partial_velocity(comp->get_next(), n - 1, net_vel, net_transform,
|
||||
parent_net_transform);
|
||||
|
||||
PandaNode *node = comp->get_node();
|
||||
if (node->has_velocity()) {
|
||||
LVector3f vel = node->get_velocity();
|
||||
net_vel += vel * net_transform->get_mat();
|
||||
}
|
||||
|
||||
CPT(TransformState) transform = node->get_transform();
|
||||
parent_net_transform = net_transform;
|
||||
net_transform = net_transform->compose(transform);
|
||||
CPT(TransformState) NodePath::
|
||||
r_get_partial_prev_transform(NodePathComponent *comp, int n) const {
|
||||
if (n == 0 || comp == (NodePathComponent *)NULL) {
|
||||
return TransformState::make_identity();
|
||||
} else {
|
||||
CPT(TransformState) transform = comp->get_node()->get_prev_transform();
|
||||
return r_get_partial_prev_transform(comp->get_next(), n - 1)->compose(transform);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,17 +225,23 @@ PUBLISHED:
|
|||
|
||||
// Aggregate transform and state information.
|
||||
INLINE const RenderState *get_state() const;
|
||||
INLINE void set_state(const RenderState *state) const;
|
||||
INLINE void set_state(const RenderState *state);
|
||||
CPT(RenderState) get_state(const NodePath &other) const;
|
||||
void set_state(const NodePath &other, const RenderState *state) const;
|
||||
void set_state(const NodePath &other, const RenderState *state);
|
||||
INLINE CPT(RenderState) get_net_state() const;
|
||||
|
||||
INLINE const TransformState *get_transform() const;
|
||||
INLINE void set_transform(const TransformState *transform) const;
|
||||
INLINE void set_transform(const TransformState *transform);
|
||||
CPT(TransformState) get_transform(const NodePath &other) const;
|
||||
void set_transform(const NodePath &other, const TransformState *transform) const;
|
||||
void set_transform(const NodePath &other, const TransformState *transform);
|
||||
INLINE CPT(TransformState) get_net_transform() const;
|
||||
|
||||
INLINE const TransformState *get_prev_transform() const;
|
||||
INLINE void set_prev_transform(const TransformState *transform);
|
||||
CPT(TransformState) get_prev_transform(const NodePath &other) const;
|
||||
void set_prev_transform(const NodePath &other, const TransformState *transform);
|
||||
INLINE CPT(TransformState) get_net_prev_transform() const;
|
||||
|
||||
|
||||
// Methods that get and set the matrix transform: pos, hpr, scale,
|
||||
// in the local coordinate system.
|
||||
|
|
@ -245,11 +251,18 @@ PUBLISHED:
|
|||
void set_x(float x);
|
||||
void set_y(float y);
|
||||
void set_z(float z);
|
||||
INLINE void set_fluid_pos(float x, float y, float z);
|
||||
void set_fluid_pos(const LVecBase3f &pos);
|
||||
void set_fluid_x(float x);
|
||||
void set_fluid_y(float y);
|
||||
void set_fluid_z(float z);
|
||||
LPoint3f get_pos() const;
|
||||
INLINE float get_x() const;
|
||||
INLINE float get_y() const;
|
||||
INLINE float get_z() const;
|
||||
|
||||
LVector3f get_pos_delta() const;
|
||||
|
||||
INLINE void set_hpr(float h, float p, float r);
|
||||
void set_hpr(const LVecBase3f &hpr);
|
||||
void set_h(float h);
|
||||
|
|
@ -334,6 +347,8 @@ PUBLISHED:
|
|||
INLINE float get_y(const NodePath &other) const;
|
||||
INLINE float get_z(const NodePath &other) const;
|
||||
|
||||
LVector3f get_pos_delta(const NodePath &other) const;
|
||||
|
||||
INLINE void set_hpr(const NodePath &other, float h, float p, float r);
|
||||
void set_hpr(const NodePath &other, const LVecBase3f &hpr);
|
||||
void set_h(const NodePath &other, float h);
|
||||
|
|
@ -421,17 +436,6 @@ PUBLISHED:
|
|||
|
||||
INLINE float get_distance(const NodePath &other) const;
|
||||
|
||||
INLINE void set_velocity(const LVector3f &velocity);
|
||||
INLINE void clear_velocity();
|
||||
INLINE bool has_velocity() const;
|
||||
INLINE const LVector3f &get_velocity() const;
|
||||
|
||||
LVector3f get_velocity(const NodePath &other) const;
|
||||
void set_velocity(const NodePath &other, const LVector3f &velocity);
|
||||
|
||||
LVector3f get_net_velocity() const;
|
||||
|
||||
|
||||
// Methods that affect appearance of geometry: color, texture, etc.
|
||||
// These affect the state at the bottom level only.
|
||||
|
||||
|
|
@ -595,14 +599,8 @@ private:
|
|||
CPT(RenderState) r_get_partial_state(NodePathComponent *comp, int n) const;
|
||||
CPT(TransformState) r_get_net_transform(NodePathComponent *comp) const;
|
||||
CPT(TransformState) r_get_partial_transform(NodePathComponent *comp, int n) const;
|
||||
|
||||
void r_get_net_velocity(NodePathComponent *comp, LVector3f &net_vel,
|
||||
CPT(TransformState) &net_transform,
|
||||
CPT(TransformState) &parent_net_transform) const;
|
||||
void r_get_partial_velocity(NodePathComponent *comp, int n,
|
||||
LVector3f &net_vel,
|
||||
CPT(TransformState) &net_transform,
|
||||
CPT(TransformState) &parent_net_transform) const;
|
||||
CPT(TransformState) r_get_net_prev_transform(NodePathComponent *comp) const;
|
||||
CPT(TransformState) r_get_partial_prev_transform(NodePathComponent *comp, int n) const;
|
||||
|
||||
void find_matches(NodePathCollection &result,
|
||||
const string &approx_path_str,
|
||||
|
|
|
|||
|
|
@ -118,9 +118,8 @@ CData() {
|
|||
_state = RenderState::make_empty();
|
||||
_effects = RenderEffects::make_empty();
|
||||
_transform = TransformState::make_identity();
|
||||
_prev_transform = TransformState::make_identity();
|
||||
_draw_mask = DrawMask::all_on();
|
||||
_velocity = LVector3f::zero();
|
||||
_has_velocity = false;
|
||||
_net_collide_mask = CollideMask::all_off();
|
||||
_fixed_internal_bound = false;
|
||||
}
|
||||
|
|
@ -139,10 +138,9 @@ CData(const PandaNode::CData ©) :
|
|||
_state(copy._state),
|
||||
_effects(copy._effects),
|
||||
_transform(copy._transform),
|
||||
_prev_transform(copy._prev_transform),
|
||||
_tag_data(copy._tag_data),
|
||||
_draw_mask(copy._draw_mask),
|
||||
_velocity(copy._velocity),
|
||||
_has_velocity(copy._has_velocity),
|
||||
_fixed_internal_bound(copy._fixed_internal_bound)
|
||||
{
|
||||
_net_collide_mask = CollideMask::all_off();
|
||||
|
|
@ -662,6 +660,46 @@ clear_transform() {
|
|||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::set_prev_transform
|
||||
// Access: Published
|
||||
// Description: Sets the transform that represents this node's
|
||||
// "previous" position, one frame ago, for the purposes
|
||||
// of detecting motion for accurate collision
|
||||
// calculations.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
set_prev_transform(const TransformState *transform) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_prev_transform = transform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_prev_transform
|
||||
// Access: Published
|
||||
// Description: Returns the transform that has been set as this
|
||||
// node's "previous" position. See
|
||||
// set_prev_transform().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TransformState *PandaNode::
|
||||
get_prev_transform() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_prev_transform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::reset_prev_transform
|
||||
// Access: Published
|
||||
// Description: Resets the "previous" transform on this node to be
|
||||
// the same as the current transform. This is not the
|
||||
// same as clearing it to identity.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
reset_prev_transform() {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_prev_transform = cdata->_transform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::set_tag
|
||||
// Access: Published
|
||||
|
|
@ -784,61 +822,6 @@ get_net_collide_mask() const {
|
|||
return cdata->_net_collide_mask;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::set_velocity
|
||||
// Access: Published
|
||||
// Description: Sets the velocity of this node. This is a delta from
|
||||
// the position of this node in the previous frame,
|
||||
// relative to the node's parent. The value should not
|
||||
// be transformed by the node's transformation (it is in
|
||||
// the coordinate system of the node's parent). This
|
||||
// has meaning only to the collision subsystem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
set_velocity(const LVector3f &velocity) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_velocity = velocity;
|
||||
cdata->_has_velocity = (!velocity.almost_equal(LVector3f::zero()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::clear_velocity
|
||||
// Access: Published
|
||||
// Description: Resets the velocity of this node to zero. See
|
||||
// set_velocity().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
clear_velocity() {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_velocity = LVector3f::zero();
|
||||
cdata->_has_velocity = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::has_velocity
|
||||
// Access: Published
|
||||
// Description: Returns true if a nonzero velocity has been set on
|
||||
// this node, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PandaNode::
|
||||
has_velocity() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_has_velocity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_velocity
|
||||
// Access: Published
|
||||
// Description: Returns the velocity previously set on this node via
|
||||
// set_velocity(), or LVector3f::zero() if no velocity
|
||||
// has been set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVector3f &PandaNode::
|
||||
get_velocity() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_velocity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::set_bound
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -150,6 +150,10 @@ PUBLISHED:
|
|||
INLINE const TransformState *get_transform() const;
|
||||
INLINE void clear_transform();
|
||||
|
||||
INLINE void set_prev_transform(const TransformState *transform);
|
||||
INLINE const TransformState *get_prev_transform() const;
|
||||
INLINE void reset_prev_transform();
|
||||
|
||||
INLINE void set_tag(const string &key, const string &value);
|
||||
INLINE string get_tag(const string &key) const;
|
||||
INLINE bool has_tag(const string &key) const;
|
||||
|
|
@ -162,11 +166,6 @@ PUBLISHED:
|
|||
|
||||
INLINE CollideMask get_net_collide_mask() const;
|
||||
|
||||
INLINE void set_velocity(const LVector3f &velocity);
|
||||
INLINE void clear_velocity();
|
||||
INLINE bool has_velocity() const;
|
||||
INLINE const LVector3f &get_velocity() const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
|
|
@ -314,15 +313,13 @@ private:
|
|||
CPT(RenderState) _state;
|
||||
CPT(RenderEffects) _effects;
|
||||
CPT(TransformState) _transform;
|
||||
CPT(TransformState) _prev_transform;
|
||||
|
||||
TagData _tag_data;
|
||||
|
||||
// This is the draw_mask of this particular node.
|
||||
DrawMask _draw_mask;
|
||||
|
||||
LVector3f _velocity;
|
||||
bool _has_velocity;
|
||||
|
||||
// This is the union of all into_collide_mask bits for any
|
||||
// CollisionNodes at and below this level. It's conceptually
|
||||
// similar to a bounding volume--it represents the bounding volume
|
||||
|
|
|
|||
|
|
@ -32,10 +32,8 @@ Transform2SG(const string &name) :
|
|||
DataNode(name)
|
||||
{
|
||||
_transform_input = define_input("transform", EventStoreTransform::get_class_type());
|
||||
_velocity_input = define_input("velocity", EventStoreVec3::get_class_type());
|
||||
|
||||
_node = NULL;
|
||||
_velocity_node = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -59,33 +57,6 @@ get_node() const {
|
|||
return _node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Transform2SG::set_velocity_node
|
||||
// Access: Public
|
||||
// Description: Sets the node that this object will assign the
|
||||
// computed velocity to. Normally this is a
|
||||
// CollisionNode parented below the node indicated by
|
||||
// set_node(). Setting this node allows the collision
|
||||
// system to track the velocity imparted to the
|
||||
// CollisionNode by the data graph object that set its
|
||||
// transform, if that data is available.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Transform2SG::
|
||||
set_velocity_node(PandaNode *node) {
|
||||
_velocity_node = node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Transform2SG::get_velocity_node
|
||||
// Access: Public
|
||||
// Description: Returns the node that this object will assign the
|
||||
// computed velocity to. See set_velocity_node().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *Transform2SG::
|
||||
get_velocity_node() const {
|
||||
return _velocity_node;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Transform2SG::do_transmit_data
|
||||
|
|
@ -110,13 +81,4 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &) {
|
|||
_node->set_transform(ts);
|
||||
}
|
||||
}
|
||||
|
||||
if (input.has_data(_velocity_input)) {
|
||||
const EventStoreVec3 *velocity;
|
||||
DCAST_INTO_V(velocity, input.get_data(_velocity_input).get_ptr());
|
||||
LVector3f vel = velocity->get_value();
|
||||
if (_velocity_node != (PandaNode *)NULL) {
|
||||
_velocity_node->set_velocity(vel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,12 +38,8 @@ PUBLISHED:
|
|||
void set_node(PandaNode *node);
|
||||
PandaNode *get_node() const;
|
||||
|
||||
void set_velocity_node(PandaNode *node);
|
||||
PandaNode *get_velocity_node() const;
|
||||
|
||||
private:
|
||||
PandaNode *_node;
|
||||
PandaNode *_velocity_node;
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
|
|
@ -53,7 +49,6 @@ protected:
|
|||
private:
|
||||
// inputs
|
||||
int _transform_input;
|
||||
int _velocity_input;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue