diff --git a/direct/src/directutil/Mopath.py b/direct/src/directutil/Mopath.py index f08b986cef..b8fa37e242 100644 --- a/direct/src/directutil/Mopath.py +++ b/direct/src/directutil/Mopath.py @@ -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) diff --git a/direct/src/interval/LerpInterval.py b/direct/src/interval/LerpInterval.py index 898ff7952d..c3a1e73e66 100644 --- a/direct/src/interval/LerpInterval.py +++ b/direct/src/interval/LerpInterval.py @@ -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) diff --git a/direct/src/interval/cLerpNodePathInterval.cxx b/direct/src/interval/cLerpNodePathInterval.cxx index e991f1ca09..54228c8f9d 100644 --- a/direct/src/interval/cLerpNodePathInterval.cxx +++ b/direct/src/interval/cLerpNodePathInterval.cxx @@ -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; diff --git a/direct/src/interval/cLerpNodePathInterval.h b/direct/src/interval/cLerpNodePathInterval.h index 339bb36db1..cbaaf11710 100644 --- a/direct/src/interval/cLerpNodePathInterval.h +++ b/direct/src/interval/cLerpNodePathInterval.h @@ -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, }; diff --git a/direct/src/showbase/NonPhysicsWalker.py b/direct/src/showbase/NonPhysicsWalker.py index 9554ef9a2f..0f308612bc 100755 --- a/direct/src/showbase/NonPhysicsWalker.py +++ b/direct/src/showbase/NonPhysicsWalker.py @@ -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): diff --git a/direct/src/showbase/PhysicsWalker.py b/direct/src/showbase/PhysicsWalker.py index 47063c3b70..07129068bf 100755 --- a/direct/src/showbase/PhysicsWalker.py +++ b/direct/src/showbase/PhysicsWalker.py @@ -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): """ diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 7e4491ad22..76e512a8f8 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -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() diff --git a/direct/src/tkpanels/TaskManagerPanel.py b/direct/src/tkpanels/TaskManagerPanel.py index 6a30a24b73..776e22fc34 100644 --- a/direct/src/tkpanels/TaskManagerPanel.py +++ b/direct/src/tkpanels/TaskManagerPanel.py @@ -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')): diff --git a/panda/src/collide/collisionEntry.I b/panda/src/collide/collisionEntry.I index 7f34b5cff9..2b0b35be86 100644 --- a/panda/src/collide/collisionEntry.I +++ b/panda/src/collide/collisionEntry.I @@ -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 diff --git a/panda/src/collide/collisionEntry.cxx b/panda/src/collide/collisionEntry.cxx index cc039afabd..4d4fe60a1c 100644 --- a/panda/src/collide/collisionEntry.cxx +++ b/panda/src/collide/collisionEntry.cxx @@ -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; } diff --git a/panda/src/collide/collisionEntry.h b/panda/src/collide/collisionEntry.h index 4fd34981c2..ee43fd639d 100644 --- a/panda/src/collide/collisionEntry.h +++ b/panda/src/collide/collisionEntry.h @@ -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; diff --git a/panda/src/collide/collisionHandlerFloor.cxx b/panda/src/collide/collisionHandlerFloor.cxx index 257afe1b42..5fe7c4a055 100644 --- a/panda/src/collide/collisionHandlerFloor.cxx +++ b/panda/src/collide/collisionHandlerFloor.cxx @@ -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. diff --git a/panda/src/collide/collisionLevelState.I b/panda/src/collide/collisionLevelState.I index 1b8862718a..c0dca83e45 100644 --- a/panda/src/collide/collisionLevelState.I +++ b/panda/src/collide/collisionLevelState.I @@ -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 diff --git a/panda/src/collide/collisionLevelState.cxx b/panda/src/collide/collisionLevelState.cxx index ca5d1680c3..ddb8bb03e6 100644 --- a/panda/src/collide/collisionLevelState.cxx +++ b/panda/src/collide/collisionLevelState.cxx @@ -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); } diff --git a/panda/src/collide/collisionLevelState.h b/panda/src/collide/collisionLevelState.h index a986cbd2c3..0735b3bd64 100644 --- a/panda/src/collide/collisionLevelState.h +++ b/panda/src/collide/collisionLevelState.h @@ -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; diff --git a/panda/src/collide/collisionNode.cxx b/panda/src/collide/collisionNode.cxx index 656f439ac3..0fda1e0907 100644 --- a/panda/src/collide/collisionNode.cxx +++ b/panda/src/collide/collisionNode.cxx @@ -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(); diff --git a/panda/src/collide/collisionPlane.cxx b/panda/src/collide/collisionPlane.cxx index fed899083f..d680e59a74 100644 --- a/panda/src/collide/collisionPlane.cxx +++ b/panda/src/collide/collisionPlane.cxx @@ -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)) { diff --git a/panda/src/collide/collisionPolygon.cxx b/panda/src/collide/collisionPolygon.cxx index 96d8c2b174..063c0933c5 100644 --- a/panda/src/collide/collisionPolygon.cxx +++ b/panda/src/collide/collisionPolygon.cxx @@ -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; diff --git a/panda/src/collide/collisionSphere.cxx b/panda/src/collide/collisionSphere.cxx index 21f61f4bcb..981b6da17a 100644 --- a/panda/src/collide/collisionSphere.cxx +++ b/panda/src/collide/collisionSphere.cxx @@ -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; diff --git a/panda/src/collide/collisionTraverser.I b/panda/src/collide/collisionTraverser.I index cf250ae567..a12b68f76b 100644 --- a/panda/src/collide/collisionTraverser.I +++ b/panda/src/collide/collisionTraverser.I @@ -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 //////////////////////////////////////////////////////////////////// diff --git a/panda/src/collide/collisionTraverser.cxx b/panda/src/collide/collisionTraverser.cxx index 82601bca6a..5f4dc92385 100644 --- a/panda/src/collide/collisionTraverser.cxx +++ b/panda/src/collide/collisionTraverser.cxx @@ -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)); + } +} diff --git a/panda/src/collide/collisionTraverser.h b/panda/src/collide/collisionTraverser.h index cf304d67e5..613d624f47 100644 --- a/panda/src/collide/collisionTraverser.h +++ b/panda/src/collide/collisionTraverser.h @@ -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 diff --git a/panda/src/collide/collisionTube.cxx b/panda/src/collide/collisionTube.cxx index c423021b72..4d16594e26 100644 --- a/panda/src/collide/collisionTube.cxx +++ b/panda/src/collide/collisionTube.cxx @@ -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()); } diff --git a/panda/src/collide/config_collide.cxx b/panda/src/collide/config_collide.cxx index 12d9ec1519..495a047a23 100644 --- a/panda/src/collide/config_collide.cxx +++ b/panda/src/collide/config_collide.cxx @@ -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 diff --git a/panda/src/collide/config_collide.h b/panda/src/collide/config_collide.h index a659bdcb02..0465ec209c 100644 --- a/panda/src/collide/config_collide.h +++ b/panda/src/collide/config_collide.h @@ -24,8 +24,6 @@ NotifyCategoryDecl(collide, EXPCL_PANDA, EXPTP_PANDA); -extern const bool auto_clear_velocity; - extern EXPCL_PANDA void init_libcollide(); #endif diff --git a/panda/src/pgraph/accumulatedAttribs.cxx b/panda/src/pgraph/accumulatedAttribs.cxx index 28fc4aa2da..8426429df6 100644 --- a/panda/src/pgraph/accumulatedAttribs.cxx +++ b/panda/src/pgraph/accumulatedAttribs.cxx @@ -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(); } diff --git a/panda/src/pgraph/nodePath.I b/panda/src/pgraph/nodePath.I index 4012fd11e9..012bd64870 100644 --- a/panda/src/pgraph/nodePath.I +++ b/panda/src/pgraph/nodePath.I @@ -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 diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 2ecef422fd..f7002659d7 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -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); } } diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 94502f44bb..75c165be9e 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -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, diff --git a/panda/src/pgraph/pandaNode.I b/panda/src/pgraph/pandaNode.I index 7b376403b4..3264884652 100644 --- a/panda/src/pgraph/pandaNode.I +++ b/panda/src/pgraph/pandaNode.I @@ -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 diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h index fb04f67d21..03033ea23e 100644 --- a/panda/src/pgraph/pandaNode.h +++ b/panda/src/pgraph/pandaNode.h @@ -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 diff --git a/panda/src/tform/transform2sg.cxx b/panda/src/tform/transform2sg.cxx index 86961eea35..f2e8f27533 100644 --- a/panda/src/tform/transform2sg.cxx +++ b/panda/src/tform/transform2sg.cxx @@ -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); - } - } } diff --git a/panda/src/tform/transform2sg.h b/panda/src/tform/transform2sg.h index df71c452b4..074746e6b6 100644 --- a/panda/src/tform/transform2sg.h +++ b/panda/src/tform/transform2sg.h @@ -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() {