remove old scene graph code

This commit is contained in:
David Rose 2002-04-09 18:33:48 +00:00
parent 83cfae1ab3
commit a38e063667
739 changed files with 1213 additions and 85939 deletions

View File

@ -19,35 +19,11 @@
#include "showBase.h"
#include "throw_event.h"
#include "camera.h"
#include "renderRelation.h"
#include "namedNode.h"
#include "renderModeTransition.h"
#include "textureTransition.h"
#include "textureTransition.h"
#include "interactiveGraphicsPipe.h"
#include "graphicsWindow.h"
#include "chancfg.h"
#include "cullFaceTransition.h"
#include "dftraverser.h"
#include "renderBuffer.h"
#include "clockObject.h"
#include "animControl.h"
#include "nodeRelation.h"
#include "dataGraphTraversal.h"
#include "depthTestTransition.h"
#include "depthWriteTransition.h"
#include "materialTransition.h"
#include "camera.h"
#include "orthographicLens.h"
#include "appTraverser.h"
#include "get_config_path.h"
#include "allTransitionsWrapper.h"
#include "dataGraphTraversal.h"
#include "depthTestAttrib.h"
#include "depthWriteAttrib.h"
#include "cullFaceAttrib.h"
#include "materialAttrib.h"
#include "qpcamera.h"
ConfigureDef(config_showbase);
@ -65,7 +41,8 @@ std::string chan_config = "single";
std::string window_title = "Panda3D";
PT(GraphicsPipe) make_graphics_pipe() {
PT(GraphicsPipe)
make_graphics_pipe() {
PT(GraphicsPipe) main_pipe;
// load display modules
@ -88,35 +65,6 @@ PT(GraphicsPipe) make_graphics_pipe() {
return main_pipe;
}
ChanConfig make_graphics_window(GraphicsPipe *pipe, NodeRelation *render_arc) {
PT(GraphicsWindow) main_win;
ChanCfgOverrides override;
// Turn on backface culling and depth buffer
CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_clockwise);
render_arc->set_transition(cfa);
DepthTestTransition *dta = new DepthTestTransition;
render_arc->set_transition(dta);
DepthWriteTransition *dwa = new DepthWriteTransition;
render_arc->set_transition(dwa);
// Now use ChanConfig to create the window.
Node *render_top = render_arc->get_parent();
override.setField(ChanCfgOverrides::Mask,
((unsigned int)(W_DOUBLE|W_DEPTH|W_MULTISAMPLE)));
std::string title = config_showbase.GetString("window-title", window_title);
override.setField(ChanCfgOverrides::Title, title);
std::string conf = config_showbase.GetString("chan-config", chan_config);
ChanConfig chan_config(pipe, conf, render_top, override);
main_win = chan_config.get_win();
assert(main_win != (GraphicsWindow*)0L);
return chan_config;
}
qpChanConfig
qpmake_graphics_window(GraphicsPipe *pipe, const qpNodePath &render) {
PT(GraphicsWindow) main_win;
@ -145,122 +93,6 @@ throw_new_frame() {
}
// Create a scene graph, associated with the indicated window, that
// can contain 2-d geometry and will be rendered on top of the
// existing 3-d window. Returns the top node of the scene graph.
NodePath
setup_panda_2d(GraphicsWindow *win, const string &graph_name) {
PT(Node) render2d_top;
render2d_top = new NamedNode(graph_name + "_top");
Node *render2d = new NamedNode(graph_name);
RenderRelation *render2d_arc = new RenderRelation(render2d_top, render2d);
// Set up some overrides to turn off certain properties which we
// probably won't need for 2-d objects.
// It's particularly important to turn off the depth test, since
// we'll be keeping the same depth buffer already filled by the
// previously-drawn 3-d scene--we don't want to pay for a clear
// operation, but we also don't want to collide with that depth
// buffer.
render2d_arc->set_transition(new DepthTestTransition(DepthTestProperty::M_none), 1);
render2d_arc->set_transition(new DepthWriteTransition(DepthWriteTransition::off()), 1);
render2d_arc->set_transition(new MaterialTransition(MaterialTransition::off()), 1);
render2d_arc->set_transition(new CullFaceTransition(CullFaceProperty::M_cull_none), 1);
// Create a 2-d camera.
Camera *cam2d = new Camera("cam2d");
new RenderRelation(render2d, cam2d);
PT(Lens) lens = new OrthographicLens;
lens->set_film_size(2.0);
lens->set_near_far(-1000.0f, 1000.0f);
cam2d->set_lens(lens);
add_render_layer(win, render2d_top, cam2d);
NodePath render2d_np = NodePath();
render2d_np.extend_by(render2d_arc);
return render2d_np;
}
// Create an auxiliary scene graph starting at the indicated node,
// layered on top of the previously-created layers.
void
add_render_layer(GraphicsWindow *win, Node *render_top, Camera *camera) {
GraphicsChannel *chan = win->get_channel(0);
nassertv(chan != (GraphicsChannel *)NULL);
GraphicsLayer *layer = chan->make_layer();
nassertv(layer != (GraphicsLayer *)NULL);
DisplayRegion *dr = layer->make_display_region();
nassertv(dr != (DisplayRegion *)NULL);
camera->set_scene(render_top);
dr->set_camera(camera);
}
bool
toggle_wireframe(NodeRelation *render_arc) {
static bool wireframe_mode = false;
wireframe_mode = !wireframe_mode;
if (!wireframe_mode) {
// Set the normal, filled mode on the render arc.
RenderModeTransition *rma = new RenderModeTransition(RenderModeProperty::M_filled);
CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_clockwise);
render_arc->set_transition(rma);
render_arc->set_transition(cfa);
} else {
// Set the initial state up for wireframe mode.
RenderModeTransition *rma = new RenderModeTransition(RenderModeProperty::M_wireframe);
CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_none);
render_arc->set_transition(rma);
render_arc->set_transition(cfa);
}
return wireframe_mode;
}
bool
toggle_backface(NodeRelation *render_arc) {
static bool backface_mode = false;
// Toggle the state variable
backface_mode = !backface_mode;
if (backface_mode) {
// Turn backface culling off
CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_none);
render_arc->set_transition(cfa);
} else {
// Turn backface culling on
CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_clockwise);
render_arc->set_transition(cfa);
}
return backface_mode;
}
bool
toggle_texture(NodeRelation *render_arc) {
static bool textures_enabled = true;
textures_enabled = !textures_enabled;
if (textures_enabled) {
// Remove the override from the initial state.
render_arc->clear_transition(TextureTransition::get_class_type());
} else {
// Set an override on the initial state to disable texturing.
TextureTransition *ta = new TextureTransition;
ta->set_priority(100);
render_arc->set_transition(ta);
}
return textures_enabled;
}
void
take_snapshot(GraphicsWindow *win, const string &name) {
GraphicsStateGuardian* gsg = win->get_gsg();

View File

@ -19,18 +19,17 @@
#ifndef SHOWBASE_H
#define SHOWBASE_H
#include <directbase.h>
#include "directbase.h"
#include <eventHandler.h>
#include <graphicsPipe.h>
#include <graphicsWindow.h>
#include <animControl.h>
#include <nodeRelation.h>
#include <pointerTo.h>
#include <nodePath.h>
#include <dconfig.h>
#include <dSearchPath.h>
#include <chancfg.h>
#include "eventHandler.h"
#include "graphicsPipe.h"
#include "graphicsWindow.h"
#include "animControl.h"
#include "pointerTo.h"
#include "dconfig.h"
#include "dSearchPath.h"
#include "qpnodePath.h"
#include "chancfg.h"
ConfigureDecl(config_showbase, EXPCL_DIRECT, EXPTP_DIRECT);
typedef Config::Config<ConfigureGetConfig_config_showbase> ConfigShowbase;
@ -43,30 +42,21 @@ BEGIN_PUBLISH
EXPCL_DIRECT DSearchPath &get_particle_path();
EXPCL_DIRECT PT(GraphicsPipe) make_graphics_pipe();
EXPCL_DIRECT ChanConfig
make_graphics_window(GraphicsPipe *pipe,
NodeRelation *render_arc);
EXPCL_DIRECT qpChanConfig
qpmake_graphics_window(GraphicsPipe *pipe, const qpNodePath &render);
EXPCL_DIRECT void throw_new_frame();
EXPCL_DIRECT NodePath setup_panda_2d(GraphicsWindow *win, const string &name);
EXPCL_DIRECT void add_render_layer(GraphicsWindow *win, Node *render_top,
Camera *camera);
EXPCL_DIRECT bool toggle_wireframe(NodeRelation *render_arc);
EXPCL_DIRECT bool toggle_texture(NodeRelation *render_arc);
EXPCL_DIRECT bool toggle_backface(NodeRelation *render_arc);
EXPCL_DIRECT void take_snapshot(GraphicsWindow *win, const string &name);
EXPCL_DIRECT ConfigShowbase &get_config_showbase();
// klunky interface since we cant pass array from python->C++
EXPCL_DIRECT void add_fullscreen_testsize(unsigned int xsize,unsigned int ysize);
EXPCL_DIRECT void runtest_fullscreen_sizes(GraphicsWindow *win);
EXPCL_DIRECT bool query_fullscreen_testresult(unsigned int xsize,unsigned int ysize);
EXPCL_DIRECT void take_snapshot(GraphicsWindow *win, const string &name);
EXPCL_DIRECT ConfigShowbase &get_config_showbase();
END_PUBLISH
#endif

View File

@ -5,25 +5,24 @@
#include "panda.h"
#include <config_device.h>
#include <config_display.h>
#include <config_graph.h>
#include <config_pnmimagetypes.h>
#include "config_device.h"
#include "config_display.h"
#include "config_pnmimagetypes.h"
#include "config_pgraph.h"
#ifdef DO_PSTATS
#include <config_pstats.h>
#include "config_pstats.h"
#endif
#include <config_sgraph.h>
#ifdef LINK_IN_GL
#include <config_glgsg.h>
#include "config_glgsg.h"
#ifdef HAVE_WGL
#include <config_wgldisplay.h>
#include "config_wgldisplay.h"
#endif
#endif
#ifdef LINK_IN_PHYSICS
#include <config_physics.h>
#include <config_particlesystem.h>
#include "config_physics.h"
#include "config_particlesystem.h"
#endif
////////////////////////////////////////////////////////////////////
@ -38,12 +37,11 @@ void
init_libpanda() {
init_libdevice();
init_libdisplay();
init_libgraph();
init_libpgraph();
init_libpnmimagetypes();
#ifdef DO_PSTATS
init_libpstatclient();
#endif
init_libsgraph();
#ifdef LINK_IN_GL
init_libglgsg();

View File

@ -5,9 +5,9 @@
#include "pandaegg.h"
#include <config_egg.h>
#include <config_builder.h>
#include <config_egg2sg.h>
#include "config_egg.h"
#include "config_builder.h"
#include "config_egg2pg.h"
////////////////////////////////////////////////////////////////////
// Function: init_libpandaegg
@ -21,5 +21,5 @@ void
init_libpandaegg() {
init_libegg();
init_libbuilder();
init_libegg2sg();
init_libegg2pg();
}

View File

@ -4,7 +4,7 @@
#begin lib_target
#define TARGET builder
#define LOCAL_LIBS \
linmath gobj sgraph sgattrib graph putil gsgbase mathutil pnmimage \
pgraph linmath gobj putil gsgbase mathutil pnmimage \
pandabase
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx

View File

@ -19,14 +19,11 @@
#include "builderFuncs.h"
#include "builderMisc.h"
#include "notify.h"
#include "namedNode.h"
#include "geomNode.h"
#include "pmap.h"
#include "builder.h"
#include "renderRelation.h"
#include "pandaNode.h"
#include "qpgeomNode.h"
#include "dcast.h"
////////////////////////////////////////////////////////////////////
// Function: Builder::Constructor
@ -69,31 +66,6 @@ Builder::
// with the same Node pointer have different names, then they should
// be given two different GeomNodes.
class NodeMap : public Namable {
public:
NodeMap(NamedNode *node, const BuilderBucket *bucket)
: _node(node), _bucket(bucket) { }
bool operator < (const NodeMap &other) const {
if (_node != other._node) {
return _node < other._node;
}
if (_bucket->get_name() != other._bucket->get_name()) {
return _bucket->get_name() < other._bucket->get_name();
}
return (_bucket->_trans.compare_to(other._bucket->_trans) < 0);
}
NamedNode *_node;
// Although a bucket pointer is stored here in the NodeMap class,
// you should not use it except to extract the name and/or the
// _trans member. Remember, this bucket pointer stands for any of
// possibly several bucket pointers, all different, except that they
// share the same name and _trans.
const BuilderBucket *_bucket;
};
class qpNodeMap : public Namable {
public:
qpNodeMap(PandaNode *node, const BuilderBucket *bucket)
@ -107,7 +79,6 @@ public:
return _bucket->get_name() < other._bucket->get_name();
}
return 0;
// return (_bucket->_state < other._bucket->_state);
}
PandaNode *_node;
@ -122,127 +93,6 @@ public:
////////////////////////////////////////////////////////////////////
// Function: Builder::build
// Access: Public
// Description: Creates Geoms for all the primitives added to all
// buckets, and adds them where appropriate to place
// them in the scene graph under their respective
// parents, and/or returns a single GeomNode that
// contains all geometry whose bucket did not reference
// a particular scene graph node to parent them to.
//
// If a bucket's _node pointer was a GeomNode, the
// geometry will be added directly to that node. If the
// _node pointer was any other kind of node, a GeomNode
// will be created and parented to that node, and its
// name will be the name of the bucket. In this case,
// the name of the bucket can also be used to different
// nodes: if two buckets reference the same node, but
// have different names, then two different GeomNodes
// are created, one with each name.
////////////////////////////////////////////////////////////////////
GeomNode *Builder::
build(const string &default_name) {
typedef pmap<NodeMap, GeomNode *, less<NodeMap> > GeomNodeMap;
GeomNodeMap geom_nodes;
// First, build all the Geoms and create GeomNodes for them. Each
// unique Node gets its own GeomNode. If the Node is itself a
// GeomNode, that GeomNode is used directly.
Buckets::iterator i;
for (i = _buckets.begin();
i != _buckets.end();
++i) {
BuilderBucket *bucket = (*i).get_bucket();
NamedNode *node = bucket->_node;
// const string &name = bucket->get_name();
GeomNode *geom_node = NULL;
if (node!=NULL && node->is_of_type(GeomNode::get_class_type())) {
// The node is a GeomNode. In this case, we simply use that
// node. We can't separate them out by name in this case; we'll
// just assign to it the first nonempty name we encounter.
geom_node = (GeomNode *)node;
// Since the caller already created this GeomNode and passed it
// in, we'll leave it up to the caller to name the node and set
// up the state transitions leading into it.
} else {
// The node is not a GeomNode, so look it up in the map.
GeomNodeMap::iterator f = geom_nodes.find(NodeMap(node, bucket));
if (f != geom_nodes.end()) {
geom_node = (*f).second;
} else {
// No such node/name combination. Create a new one.
geom_node = bucket->make_geom_node();
if (geom_node != NULL) {
geom_nodes[NodeMap(node, bucket)] = geom_node;
}
}
}
if (geom_node != NULL) {
(*i).build(geom_node);
}
}
// Now go through and parent the geom_nodes under their respective
// group nodes. Save out the geom_node associated with a NULL Node;
// this one is returned from this function.
GeomNode *base_geom_node = NULL;
GeomNodeMap::iterator gi;
for (gi = geom_nodes.begin();
gi != geom_nodes.end();
++gi) {
const NodeMap &nm = (*gi).first;
GeomNode *geom_node = (*gi).second;
NamedNode *node = nm._node;
const string &name = nm._bucket->get_name();
const NodeTransitions &trans = nm._bucket->_trans;
// Assign the name to the geom, if it doesn't have one already.
if (!geom_node->has_name()) {
if (!name.empty()) {
geom_node->set_name(name);
} else if (!default_name.empty()) {
geom_node->set_name(default_name);
}
}
// Only reparent the geom_node if it has no parent already.
int num_parents =
geom_node->get_num_parents(RenderRelation::get_class_type());
if (num_parents == 0) {
if (geom_node->get_num_geoms() == 0) {
// If there was nothing added, never mind.
delete geom_node;
} else if (node==NULL) {
nassertr(base_geom_node == NULL, NULL);
base_geom_node = geom_node;
} else {
RenderRelation *arc = new RenderRelation(node, geom_node);
// Now, this is our only opportunity to apply the scene-graph
// state specified in the bucket to the node: we have created
// our own geom_node for these buckets, and we have parented
// it to the scene graph.
arc->copy_transitions_from(trans);
}
}
}
return base_geom_node;
}
////////////////////////////////////////////////////////////////////
// Function: Builder::build
// Access: Public

View File

@ -175,7 +175,6 @@
#include "pset.h"
class GeomNode;
class qpGeomNode;
@ -196,7 +195,6 @@ public:
INLINE bool add_prim_nonindexed(const BuilderBucket &bucket,
const BuilderPrimI &prim);
GeomNode *build(const string &default_name = "");
qpGeomNode *qpbuild(const string &default_name = "");
protected:

View File

@ -21,8 +21,6 @@
#include "builderBucket.h"
#include "builderFuncs.h"
#include "builderMisc.h"
#include "namedNode.h"
#include "geomNode.h"
#include "qpgeomNode.h"
@ -36,7 +34,6 @@ BuilderBucket *BuilderBucket::_default_bucket = NULL;
////////////////////////////////////////////////////////////////////
BuilderBucket::
BuilderBucket() {
_node = NULL;
_qpnode = NULL;
(*this) = (*get_default_bucket());
}
@ -49,7 +46,6 @@ BuilderBucket() {
////////////////////////////////////////////////////////////////////
BuilderBucket::
BuilderBucket(const BuilderBucket &copy) {
_node = NULL;
_qpnode = NULL;
(*this) = copy;
}
@ -71,12 +67,10 @@ operator = (const BuilderBucket &copy) {
set_texcoords(copy._texcoords);
set_colors(copy._colors);
_node = copy._node;
_qpnode = copy._qpnode;
_drawBin = copy._drawBin;
_drawOrder = copy._drawOrder;
_trans = copy._trans;
_state = copy._state;
return *this;
@ -108,20 +102,6 @@ make_copy() const {
}
////////////////////////////////////////////////////////////////////
// Function: BuilderBucket::make_geom_node
// Access: Public, Virtual
// Description: Called by the builder when it is time to create a new
// GeomNode. This function should allocate and return a
// new GeomNode suitable for adding geometry to. You
// may redefine it to return a subclass of GeomNode, or
// to do some initialization to the node.
////////////////////////////////////////////////////////////////////
GeomNode *BuilderBucket::
make_geom_node() {
return new GeomNode;
}
////////////////////////////////////////////////////////////////////
// Function: BuilderBucket::qpmake_geom_node
// Access: Public, Virtual
@ -183,9 +163,6 @@ operator < (const BuilderBucket &other) const {
return get_name() < other.get_name();
}
if (_node != other._node) {
return _node < other._node;
}
if (_qpnode != other._qpnode) {
return _qpnode < other._qpnode;
}
@ -204,10 +181,6 @@ operator < (const BuilderBucket &other) const {
if (_drawOrder != other._drawOrder)
return _drawOrder < other._drawOrder;
int compare = _trans.compare_to(other._trans);
if (compare != 0) {
return (compare < 0);
}
if (_state != other._state) {
return _state < other._state;
}
@ -224,9 +197,6 @@ void BuilderBucket::
output(ostream &out) const {
out << "Bucket \"" << get_name() << "\"";
if (_node != (NamedNode *)NULL) {
out << " attached to " << *_node << "\n";
}
if (_qpnode != (PandaNode *)NULL) {
out << " attached to " << *_qpnode << "\n";
}
@ -275,7 +245,6 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
BuilderBucket::
BuilderBucket(int) {
_node = NULL;
_qpnode = NULL;
_drawBin = -1;

View File

@ -26,7 +26,6 @@
#include "namable.h"
#include "pointerToArray.h"
#include "luse.h"
#include "nodeTransitions.h"
#include "pta_Vertexf.h"
#include "pta_Normalf.h"
#include "pta_Colorf.h"
@ -35,10 +34,7 @@
#include "stdlib.h"
class NamedNode;
class Geom;
class GeomNode;
class PandaNode;
class qpGeomNode;
@ -68,7 +64,6 @@ public:
virtual ~BuilderBucket();
virtual BuilderBucket *make_copy() const;
virtual GeomNode *make_geom_node();
virtual qpGeomNode *qpmake_geom_node();
virtual Geom *done_geom(Geom *geom);
void add_attrib(const RenderAttrib *attrib);
@ -91,13 +86,11 @@ public:
virtual void output(ostream &out) const;
NamedNode *_node;
PandaNode *_qpnode;
short _drawBin;
unsigned int _drawOrder;
NodeTransitions _trans;
CPT(RenderState) _state;
protected:

View File

@ -19,7 +19,6 @@
#include "builderFuncs.h"
#include "builderBucketNode.h"
#include "geomNode.h"
#include "qpgeomNode.h"
////////////////////////////////////////////////////////////////////
@ -50,56 +49,6 @@ add_prim(const BuilderPrimI &prim) {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: BuilderBucketNode::build
// Access: Public
// Description: Builds all the geometry assigned to this particular
// bucket, and assigns it to the indicated GeomNode.
// Returns the number of Geoms created.
////////////////////////////////////////////////////////////////////
int BuilderBucketNode::
build(GeomNode *geom_node) const {
int count = 0;
{
// First, the nonindexed.
Prims::const_iterator pi, last_pi;
last_pi = _prims.begin();
for (pi = _prims.begin();
pi != _prims.end();
++pi) {
if ((*last_pi) < (*pi)) {
count += mesh_and_build(last_pi, pi, *_bucket, geom_node,
(BuilderPrim *)0);
last_pi = pi;
}
}
count += mesh_and_build(last_pi, pi, *_bucket, geom_node,
(BuilderPrim *)0);
}
{
// Then, the indexed.
IPrims::const_iterator pi, last_pi;
last_pi = _iprims.begin();
for (pi = _iprims.begin();
pi != _iprims.end();
++pi) {
if ((*last_pi) < (*pi)) {
count += mesh_and_build(last_pi, pi, *_bucket, geom_node,
(BuilderPrimI *)0);
last_pi = pi;
}
}
count += mesh_and_build(last_pi, pi, *_bucket, geom_node,
(BuilderPrimI *)0);
}
return count;
}
////////////////////////////////////////////////////////////////////
// Function: BuilderBucketNode::build

View File

@ -57,7 +57,6 @@ public:
INLINE bool operator == (const BuilderBucketNode &other) const;
INLINE bool operator != (const BuilderBucketNode &other) const;
int build(GeomNode *geom_node) const;
int build(qpGeomNode *geom_node) const;
protected:

View File

@ -484,10 +484,10 @@ expand(const PrimType &prim, BuilderBucket &bucket, OutputIterator result) {
// creates corresponding geometry for them in the
// indicated GeomNode.
////////////////////////////////////////////////////////////////////
template<class InputIterator, class PrimType, class GeomNode>
template<class InputIterator, class PrimType>
static int
build_geoms(InputIterator first, InputIterator last,
BuilderBucket &bucket, GeomNode *geom_node,
BuilderBucket &bucket, qpGeomNode *geom_node,
PrimType *) {
if (first==last) {
return 0;
@ -794,10 +794,10 @@ public:
// to infer the PrimType (BuilderPrim or BuilderPrimI)
// from the iterator's value type, and template on that.
////////////////////////////////////////////////////////////////////
template<class InputIterator, class PrimType, class GeomNode>
template<class InputIterator, class PrimType>
static int
__mesh_and_build(InputIterator first, InputIterator last,
BuilderBucket &bucket, GeomNode *geom_node,
BuilderBucket &bucket, qpGeomNode *geom_node,
PrimType *) {
if (first==last) {
return 0;
@ -877,10 +877,10 @@ __mesh_and_build(InputIterator first, InputIterator last,
// runs them through the mesher if specified by the
// bucket, and builds them into the indicated GeomNode.
////////////////////////////////////////////////////////////////////
template<class InputIterator, class value_type, class GeomNode>
template<class InputIterator, class value_type>
int
mesh_and_build(InputIterator first, InputIterator last,
BuilderBucket &bucket, GeomNode *geom_node,
BuilderBucket &bucket, qpGeomNode *geom_node,
value_type *value_type_ptr) {
return __mesh_and_build(first, last, bucket, geom_node, value_type_ptr);
}

View File

@ -18,13 +18,11 @@
#ifndef BUILDERFUNCS_H
#define BUILDERFUNCS_H
#include <pandabase.h>
#include "pandabase.h"
#include "pvector.h"
#include <string>
class BuilderBucket;
class qpGeomNode;
////////////////////////////////////////////////////////////////////
@ -56,10 +54,10 @@ expand(const PrimType &prim, BuilderBucket &bucket,
// runs them through the mesher if specified by the
// bucket, and builds them into the indicated GeomNode.
////////////////////////////////////////////////////////////////////
template<class InputIterator, class GeomNode>
template<class InputIterator>
int
mesh_and_build(InputIterator first, InputIterator last,
BuilderBucket &bucket, GeomNode *geom_node);
BuilderBucket &bucket, qpGeomNode *geom_node);

View File

@ -18,7 +18,6 @@
#include "builderFuncs.h"
#include "builderNormalVisualizer.h"
#include "geomNode.h"
#include "qpgeomNode.h"
#ifdef SUPPORT_SHOW_NORMALS
@ -57,12 +56,6 @@ add_prim(const BuilderPrimI &prim) {
add_prim(prim_ni);
}
void BuilderNormalVisualizer::
show_normals(GeomNode *node) {
// Ok, now we've got a bunch of normals saved up; create some geometry.
mesh_and_build(_lines.begin(), _lines.end(), _bucket, node, (BuilderPrim *)0);
}
void BuilderNormalVisualizer::
show_normals(qpGeomNode *node) {
// Ok, now we've got a bunch of normals saved up; create some geometry.

View File

@ -47,7 +47,6 @@ public:
void add_prim(const BuilderPrim &prim);
void add_prim(const BuilderPrimI &prim);
void show_normals(GeomNode *node);
void show_normals(qpGeomNode *node);
private:

View File

@ -4,12 +4,12 @@
#begin lib_target
#define TARGET chan
#define LOCAL_LIBS \
putil linmath mathutil event graph sgattrib
pgraph putil linmath mathutil event
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \
animBundle.I animBundle.h animBundleNode.I animBundleNode.h \
animBundle.I animBundle.h \
qpanimBundleNode.I qpanimBundleNode.h \
animChannel.I animChannel.h animChannelBase.I \
animChannelBase.h animChannelMatrixXfmTable.I \
@ -20,25 +20,24 @@
config_chan.h movingPartBase.I movingPartBase.h \
movingPartMatrix.I movingPartMatrix.h movingPartScalar.I \
movingPartScalar.h partBundle.I partBundle.N partBundle.h \
partBundleNode.I partBundleNode.h \
qppartBundleNode.I qppartBundleNode.h \
partGroup.I partGroup.h \
vector_PartGroupStar.h
#define INCLUDED_SOURCES \
animBundle.cxx animBundleNode.cxx \
animBundle.cxx \
qpanimBundleNode.cxx \
animChannel.cxx \
animChannelBase.cxx animChannelMatrixXfmTable.cxx \
animChannelScalarTable.cxx animControl.cxx \
animControlCollection.cxx animGroup.cxx auto_bind.cxx \
config_chan.cxx movingPartBase.cxx movingPartMatrix.cxx \
movingPartScalar.cxx partBundle.cxx partBundleNode.cxx \
movingPartScalar.cxx partBundle.cxx \
qppartBundleNode.cxx \
partGroup.cxx vector_PartGroupStar.cxx
#define INSTALL_HEADERS \
animBundle.I animBundle.h animBundleNode.I animBundleNode.h \
animBundle.I animBundle.h \
qpanimBundleNode.I qpanimBundleNode.h \
animChannel.I animChannel.h animChannelBase.I animChannelBase.h \
animChannelFixed.I animChannelFixed.h animChannelMatrixXfmTable.I \
@ -49,7 +48,6 @@
movingPart.I movingPart.h movingPartBase.I \
movingPartBase.h movingPartMatrix.I movingPartMatrix.h \
movingPartScalar.I movingPartScalar.h partBundle.I partBundle.h \
partBundleNode.I partBundleNode.h \
qppartBundleNode.I qppartBundleNode.h \
partGroup.I partGroup.h \
vector_PartGroupStar.h

View File

@ -1,73 +0,0 @@
// Filename: animBundleNode.I
// Created by: drose (22Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE AnimBundleNode::
AnimBundleNode(AnimBundle *bundle) :
NamedNode(bundle->get_name()),
_bundle(bundle)
{
}
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::Constructor
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
INLINE AnimBundleNode::
AnimBundleNode(void)
{
}
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE AnimBundleNode::
AnimBundleNode(const AnimBundleNode &copy) :
NamedNode(copy),
_bundle(copy._bundle)
{
}
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void AnimBundleNode::
operator = (const AnimBundleNode &copy) {
NamedNode::operator = (copy);
_bundle = copy._bundle;
}
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::get_bundle
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE AnimBundle *AnimBundleNode::
get_bundle() const {
return _bundle;
}

View File

@ -1,114 +0,0 @@
// Filename: animBundleNode.cxx
// Created by: drose (22Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "animBundleNode.h"
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
TypeHandle AnimBundleNode::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::make_copy
// Access: Public, Virtual
// Description: Returns a newly-allocated Node that is a shallow copy
// of this one. It will be a different Node pointer,
// but its internal data may or may not be shared with
// that of the original Node.
////////////////////////////////////////////////////////////////////
Node *AnimBundleNode::
make_copy() const {
return new AnimBundleNode(*this);
}
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::write_datagram
// Access: Public
// Description: Function to write the important information in
// the particular object to a Datagram
////////////////////////////////////////////////////////////////////
void AnimBundleNode::
write_datagram(BamWriter *manager, Datagram &me)
{
NamedNode::write_datagram(manager, me);
manager->write_pointer(me, _bundle);
}
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::fillin
// Access: Protected
// Description: Function that reads out of the datagram (or asks
// manager to read) all of the data that is needed to
// re-create this object and stores it in the appropiate
// place
////////////////////////////////////////////////////////////////////
void AnimBundleNode::
fillin(DatagramIterator& scan, BamReader* manager)
{
NamedNode::fillin(scan, manager);
manager->read_pointer(scan);
}
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::complete_pointers
// Access: Public
// Description: Takes in a vector of pointes to TypedWritable
// objects that correspond to all the requests for
// pointers that this object made to BamReader.
////////////////////////////////////////////////////////////////////
int AnimBundleNode::
complete_pointers(TypedWritable **p_list, BamReader* manager)
{
int start = NamedNode::complete_pointers(p_list, manager);
_bundle = DCAST(AnimBundle, p_list[start]);
return start+1;
}
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::make_AnimBundleNode
// Access: Protected
// Description: Factory method to generate a AnimBundleNode object
////////////////////////////////////////////////////////////////////
TypedWritable* AnimBundleNode::
make_AnimBundleNode(const FactoryParams &params)
{
AnimBundleNode *me = new AnimBundleNode;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}
////////////////////////////////////////////////////////////////////
// Function: AnimBundleNode::register_with_factory
// Access: Public, Static
// Description: Factory method to generate a AnimBundleNode object
////////////////////////////////////////////////////////////////////
void AnimBundleNode::
register_with_read_factory(void)
{
BamReader::get_factory()->register_factory(get_class_type(), make_AnimBundleNode);
}

View File

@ -1,81 +0,0 @@
// Filename: animBundleNode.h
// Created by: drose (22Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef ANIMBUNDLENODE_H
#define ANIMBUNDLENODE_H
#include <pandabase.h>
#include "animBundle.h"
#include <namedNode.h>
////////////////////////////////////////////////////////////////////
// Class : AnimBundleNode
// Description : This is a node that contains a pointer to an
// AnimBundle. Its primary raison d'être is to allow
// the AnimBundles to be stored in the scene graph, so
// they may conveniently be loaded as egg files, for
// instance.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA AnimBundleNode : public NamedNode {
PUBLISHED:
INLINE AnimBundleNode(AnimBundle *bundle);
INLINE AnimBundleNode(const AnimBundleNode &copy);
INLINE void operator = (const AnimBundleNode &copy);
virtual Node *make_copy() const;
INLINE AnimBundle *get_bundle() const;
private:
PT(AnimBundle) _bundle;
public:
static void register_with_read_factory(void);
virtual void write_datagram(BamWriter* manager, Datagram &me);
virtual int complete_pointers(TypedWritable **p_list,
BamReader *manager);
static TypedWritable *make_AnimBundleNode(const FactoryParams &params);
protected:
INLINE AnimBundleNode(void);
void fillin(DatagramIterator& scan, BamReader* manager);
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
NamedNode::init_type();
register_type(_type_handle, "AnimBundleNode",
NamedNode::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "animBundleNode.I"
#endif

View File

@ -19,11 +19,11 @@
#ifndef ANIMCHANNEL_H
#define ANIMCHANNEL_H
#include <pandabase.h>
#include "pandabase.h"
#include "animChannelBase.h"
#include <lmatrix.h>
#include "lmatrix.h"
////////////////////////////////////////////////////////////////////
// Class : AnimChannel

View File

@ -23,154 +23,6 @@
#include "config_chan.h"
#include "string_utils.h"
#include "animBundleNode.h"
#include "partBundleNode.h"
#include "renderRelation.h"
#include "traverserVisitor.h"
#include "dftraverser.h"
#include "nullLevelState.h"
#include "nullTransitionWrapper.h"
typedef pset<AnimBundleNode *> AnimNodes;
typedef pmap<string, AnimNodes> Anims;
typedef pset<PartBundleNode *> PartNodes;
typedef pmap<string, PartNodes> Parts;
////////////////////////////////////////////////////////////////////
// Class : CollectNodes
// Description : This is a traverser visitor that locates bundle nodes
// and adds them to their respective maps.
////////////////////////////////////////////////////////////////////
class CollectNodes :
public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
public:
bool reached_node(Node *node, const NullTransitionWrapper &,
NullLevelState &) {
if (node->is_of_type(AnimBundleNode::get_class_type())) {
AnimBundleNode *bn = DCAST(AnimBundleNode, node);
_anims[bn->get_bundle()->get_name()].insert(bn);
} else if (node->is_of_type(PartBundleNode::get_class_type())) {
PartBundleNode *bn = DCAST(PartBundleNode, node);
_parts[bn->get_bundle()->get_name()].insert(bn);
}
return true;
}
Anims _anims;
Parts _parts;
};
////////////////////////////////////////////////////////////////////
// Function: bind_anims
// Description: A support function for auto_bind(), below. Given a
// set of AnimBundles and a set of PartBundles that all
// share the same name, perform whatever bindings make
// sense.
////////////////////////////////////////////////////////////////////
static void
bind_anims(const PartNodes &parts, const AnimNodes &anims,
AnimControlCollection &controls,
int hierarchy_match_flags) {
PartNodes::const_iterator pni;
for (pni = parts.begin(); pni != parts.end(); ++pni) {
PartBundle *part = (*pni)->get_bundle();
AnimNodes::const_iterator ani;
for (ani = anims.begin(); ani != anims.end(); ++ani) {
AnimBundle *anim = (*ani)->get_bundle();
if (chan_cat.is_info()) {
chan_cat.info()
<< "Attempting to bind " << *part << " to " << *anim << "\n";
}
PT(AnimControl) control =
part->bind_anim(anim, hierarchy_match_flags);
string name = anim->get_name();
if (control != (AnimControl *)NULL) {
if (controls.find_anim(name) != (AnimControl *)NULL) {
// That name's already used; synthesize another one.
int index = 0;
string new_name;
do {
index++;
new_name = name + '.' + format_string(index);
} while (controls.find_anim(new_name) != (AnimControl *)NULL);
name = new_name;
}
controls.store_anim(control, name);
}
if (chan_cat.is_info()) {
if (control == NULL) {
chan_cat.info()
<< "Bind failed.\n";
} else {
chan_cat.info()
<< "Bind succeeded, index "
<< control->get_channel_index() << "; accessible as "
<< name << "\n";
}
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: auto_bind
// Description: Walks the scene graph or subgraph beginning at the
// indicated node, and attempts to bind any AnimBundles
// found to their matching PartBundles, when possible.
//
// The list of all resulting AnimControls created is
// filled into controls.
////////////////////////////////////////////////////////////////////
void
auto_bind(Node *root_node, AnimControlCollection &controls,
int hierarchy_match_flags) {
// First, locate all the bundles in the subgraph.
CollectNodes cn;
df_traverse(root_node, cn, NullTransitionWrapper(), NullLevelState(),
RenderRelation::get_class_type());
// Now, match up the bundles by name.
Anims::const_iterator ai = cn._anims.begin();
Parts::const_iterator pi = cn._parts.begin();
while (ai != cn._anims.end() && pi != cn._parts.end()) {
if ((*ai).first < (*pi).first) {
// Here's an anim with no matching parts.
++ai;
} else if ((*pi).first < (*ai).first) {
// And here's a part with no matching anims.
++pi;
} else {
// But here we have (at least one) match!
bind_anims((*pi).second, (*ai).second, controls,
hierarchy_match_flags);
++pi;
// We don't increment the anim counter yet. That way, the same
// anim may bind to multiple parts, if they all share the same
// name.
}
}
}
typedef pset<qpAnimBundleNode *> qpAnimNodes;
typedef pmap<string, qpAnimNodes> qpAnims;

View File

@ -24,7 +24,6 @@
#include "animControl.h"
#include "animControlCollection.h"
class Node;
class PandaNode;
BEGIN_PUBLISH
@ -37,10 +36,6 @@ BEGIN_PUBLISH
// The list of all resulting AnimControls created is
// filled into controls.
////////////////////////////////////////////////////////////////////
EXPCL_PANDA void
auto_bind(Node *root_node, AnimControlCollection &controls,
int hierarchy_match_flags = 0);
EXPCL_PANDA void
auto_bind(PandaNode *root_node, AnimControlCollection &controls,
int hierarchy_match_flags = 0);

View File

@ -5,7 +5,6 @@
#include "movingPartMatrix.cxx"
#include "movingPartScalar.cxx"
#include "partBundle.cxx"
#include "partBundleNode.cxx"
#include "qppartBundleNode.cxx"
#include "partGroup.cxx"
#include "vector_PartGroupStar.cxx"

View File

@ -1,6 +1,5 @@
#include "animBundle.cxx"
#include "animBundleNode.cxx"
#include "qpanimBundleNode.cxx"
#include "animChannel.cxx"
#include "animChannelBase.cxx"

View File

@ -19,7 +19,6 @@
#include "config_chan.h"
#include "animBundle.h"
#include "animBundleNode.h"
#include "qpanimBundleNode.h"
#include "animChannelBase.h"
#include "animChannelMatrixXfmTable.h"
@ -30,7 +29,6 @@
#include "movingPartMatrix.h"
#include "movingPartScalar.h"
#include "partBundle.h"
#include "partBundleNode.h"
#include "qppartBundleNode.h"
#include "partGroup.h"
@ -80,7 +78,6 @@ bool read_compressed_channels = config_chan.GetBool("read-compressed-channels",
ConfigureFn(config_chan) {
AnimBundle::init_type();
AnimBundleNode::init_type();
qpAnimBundleNode::init_type();
AnimChannelBase::init_type();
AnimChannelMatrixXfmTable::init_type();
@ -91,7 +88,6 @@ ConfigureFn(config_chan) {
MovingPartMatrix::init_type();
MovingPartScalar::init_type();
PartBundle::init_type();
PartBundleNode::init_type();
qpPartBundleNode::init_type();
PartGroup::init_type();
@ -110,7 +106,6 @@ ConfigureFn(config_chan) {
AnimGroup::register_with_read_factory();
AnimBundle::register_with_read_factory();
AnimBundleNode::register_with_read_factory();
qpAnimBundleNode::register_with_read_factory();
AnimChannelMatrixXfmTable::register_with_read_factory();
AnimChannelScalarTable::register_with_read_factory();

View File

@ -1,70 +0,0 @@
// Filename: partBundleNode.I
// Created by: drose (23Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: PartBundleNode::Constructor
// Access: Public
// Description: The PartBundle and its node should be constructed
// together. Generally, the derived classes of
// PartBundleNode will automatically create a PartBundle
// of the appropriate type, and pass it up to this
// constructor.
////////////////////////////////////////////////////////////////////
INLINE PartBundleNode::
PartBundleNode(const string &name, PartBundle *bundle) :
NamedNode(name),
_bundle(bundle)
{
_bundle->_node = this;
}
////////////////////////////////////////////////////////////////////
// Function: PartBundleNode::Default Constructor
// Access: Protected
// Description: For internal use only.
////////////////////////////////////////////////////////////////////
INLINE PartBundleNode::
PartBundleNode(void)
{
}
////////////////////////////////////////////////////////////////////
// Function: PartBundleNode::Copy Constructor
// Access: Protected
// Description: Use make_copy() or copy_subgraph() to copy one of
// these. Copying a PartBundleNode will always force a
// deep copy of the PartGroup hierarchy.
////////////////////////////////////////////////////////////////////
INLINE PartBundleNode::
PartBundleNode(const PartBundleNode &copy) :
NamedNode(copy),
_bundle(DCAST(PartBundle, copy._bundle->copy_subgraph()))
{
_bundle->_node = this;
}
////////////////////////////////////////////////////////////////////
// Function: PartBundleNode::get_bundle
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PartBundle *PartBundleNode::
get_bundle() const {
return _bundle;
}

View File

@ -1,88 +0,0 @@
// Filename: partBundleNode.cxx
// Created by: drose (23Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "partBundleNode.h"
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
TypeHandle PartBundleNode::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: PartBundleNode::safe_to_flatten
// Access: Public, Virtual
// Description: Returns true if it is generally safe to flatten out
// this particular kind of Node by duplicating
// instances, false otherwise (for instance, a Camera
// cannot be safely flattened, because the Camera
// pointer itself is meaningful).
////////////////////////////////////////////////////////////////////
bool PartBundleNode::
safe_to_flatten() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PartBundleNode::write_datagram
// Access: Public
// Description: Function to write the important information in
// the particular object to a Datagram
////////////////////////////////////////////////////////////////////
void PartBundleNode::
write_datagram(BamWriter *manager, Datagram &me)
{
NamedNode::write_datagram(manager, me);
manager->write_pointer(me, _bundle);
}
////////////////////////////////////////////////////////////////////
// Function: PartBundleNode::fillin
// Access: Protected
// Description: Function that reads out of the datagram (or asks
// manager to read) all of the data that is needed to
// re-create this object and stores it in the appropiate
// place
////////////////////////////////////////////////////////////////////
void PartBundleNode::
fillin(DatagramIterator& scan, BamReader* manager)
{
NamedNode::fillin(scan, manager);
manager->read_pointer(scan);
}
////////////////////////////////////////////////////////////////////
// Function: PartBundleNode::complete_pointers
// Access: Public
// Description: Takes in a vector of pointes to TypedWritable
// objects that correspond to all the requests for
// pointers that this object made to BamReader.
////////////////////////////////////////////////////////////////////
int PartBundleNode::
complete_pointers(TypedWritable **p_list, BamReader* manager)
{
int start = NamedNode::complete_pointers(p_list, manager);
_bundle = DCAST(PartBundle, p_list[start]);
//Let PartBundleNode tell the PartBundle about itselt
_bundle->_node = this;
return start+1;
}

View File

@ -1,80 +0,0 @@
// Filename: partBundleNode.h
// Created by: drose (23Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef PARTBUNDLENODE_H
#define PARTBUNDLENODE_H
#include <pandabase.h>
#include "partBundle.h"
#include <namedNode.h>
////////////////////////////////////////////////////////////////////
// Class : PartBundleNode
// Description : This is a node that contains a pointer to an
// PartBundle. Like AnimBundleNode, it exists solely to
// make it easy to store PartBundles in the scene graph.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA PartBundleNode : public NamedNode {
public:
INLINE PartBundleNode(const string &name, PartBundle *bundle);
protected:
INLINE PartBundleNode();
INLINE PartBundleNode(const PartBundleNode &copy);
public:
virtual bool safe_to_flatten() const;
PUBLISHED:
INLINE PartBundle *get_bundle() const;
private:
PT(PartBundle) _bundle;
public:
virtual void write_datagram(BamWriter* manager, Datagram &me);
virtual int complete_pointers(TypedWritable **p_list,
BamReader *manager);
protected:
void fillin(DatagramIterator& scan, BamReader* manager);
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
NamedNode::init_type();
register_type(_type_handle, "PartBundleNode",
NamedNode::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "partBundleNode.I"
#endif

View File

@ -4,7 +4,7 @@
#begin lib_target
#define TARGET chancfg
#define LOCAL_LIBS \
putil display sgattrib linmath graph sgraph gobj display gsgbase \
putil display linmath gobj display gsgbase \
mathutil
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx

View File

@ -16,26 +16,6 @@
//
////////////////////////////////////////////////////////////////////
INLINE PT_NamedNode ChanConfig::get_group_node(const int node_index) const {
return _group_node[node_index];
}
INLINE int ChanConfig::get_group_membership(const int dr_index) const {
return _group_membership[dr_index];
}
INLINE int ChanConfig::get_num_groups(void) const {
return _group_node.size();
}
INLINE int ChanConfig::get_num_drs(void) const {
return _display_region.size();
}
INLINE PT(DisplayRegion) ChanConfig::get_dr(const int dr_index) const {
return _display_region[dr_index];
}
INLINE PT(GraphicsWindow) ChanConfig::get_win(void) const {
return _graphics_window;
}
INLINE PandaNode *qpChanConfig::get_group_node(const int node_index) const {
return _group_node[node_index];
}

View File

@ -21,17 +21,14 @@
#include "displayRegion.h"
#include "graphicsChannel.h"
#include "hardwareChannel.h"
#include "camera.h"
#include "qpcamera.h"
#include "frustum.h"
#include "perspectiveLens.h"
#include "renderRelation.h"
#include "transformTransition.h"
#include "dSearchPath.h"
#include "dconfig.h"
#include "filename.h"
#include "pt_NamedNode.h"
#include "transformState.h"
#include "dcast.h"
#include <algorithm>
@ -209,283 +206,6 @@ SetupFOV ChanResolveFOV(SetupFOV& fov, float sizeX, float sizeY) {
return ret;
}
void ChanConfig::chan_eval(GraphicsWindow* win, WindowItem& W, LayoutItem& L,
SVec& S,
ChanViewport& V, int hw_offset, int xsize, int ysize,
Node *render, bool want_cameras) {
int i = min(L.GetNumRegions(), int(S.size()));
int j;
SVec::iterator k;
std::vector<PT_NamedNode>camera(W.getNumCameraGroups());
//first camera is special cased to name "camera" for older code
camera[0] = new NamedNode("camera");
for(int icam=1;icam<W.getNumCameraGroups();icam++) {
char dummy[10];//if more than 10^11 groups, you've got bigger problems
sprintf(dummy,"%d",icam);
std::string nodeName = "camera";
nodeName.append(dummy);
camera[icam] = new NamedNode(nodeName.c_str());
}
for (j=0, k=S.begin(); j<i; ++j, ++k) {
ChanViewport v(ChanScaleViewport(V, L[j]));
PT(GraphicsChannel) chan;
if ((*k).getHWChan() && W.getHWChans()) {
if ((*k).getChan() == -1) {
chan = win->get_channel(hw_offset);
} else
chan = win->get_channel((*k).getChan());
// HW channels always start with the full area of the channel
v = ChanViewport(0.0f, 1.0f, 0.0f, 1.0f);
} else {
chan = win->get_channel(0);
}
ChanViewport v2(ChanScaleViewport(v, (*k).getViewport()));
PT(GraphicsLayer) layer = chan->make_layer();
PT(DisplayRegion) dr =
layer->make_display_region(v2.left(), v2.right(),
v2.bottom(), v2.top());
if (want_cameras && camera[0] != (Node *)NULL) {
// now make a camera for it
PT(Camera) cam = new Camera;
dr->set_camera(cam);
_display_region.push_back(dr);
SetupFOV fov = (*k).getFOV();
// The distinction between ConsoleSize and DisplaySize
// is to handle display regions with orientations that
// are rotated 90 degrees left or right. For example,
// the model shop cave (LAIR) uses projectors on their
// sides, so that what's horizontal on the console is
// vertical in the cave (Display).
float xConsoleSize = xsize*(v2.right()-v2.left());
float yConsoleSize = ysize*(v2.top()-v2.bottom());
float xDisplaySize, yDisplaySize;
if ( (*k).getOrientation() == SetupItem::Left ||
(*k).getOrientation() == SetupItem::Right ) {
xDisplaySize = yConsoleSize;
yDisplaySize = xConsoleSize;
} else {
xDisplaySize = xConsoleSize;
yDisplaySize = yConsoleSize;
}
fov = ChanResolveFOV(fov, xDisplaySize, yDisplaySize);
if (chancfg_cat->is_debug()) {
chancfg_cat->debug() << "ChanEval:: FOVhoriz = " << fov.getHoriz()
<< " FOVvert = " << fov.getVert() << endl;
chancfg_cat->debug() << "ChanEval:: xsize = " << xsize
<< " ysize = " << ysize << endl;
}
// take care of the orientation
PT(TransformTransition) orient;
float hFov, vFov;
switch ((*k).getOrientation()) {
case SetupItem::Up:
hFov = fov.getHoriz(); vFov = fov.getVert();
break;
case SetupItem::Down:
hFov = fov.getHoriz(); vFov = fov.getVert();
orient = new TransformTransition(
LMatrix4f::rotate_mat_normaxis(180.0f, LVector3f::forward()));
break;
case SetupItem::Left:
// vertical and horizontal FOV are being switched
hFov = fov.getVert(); vFov = fov.getHoriz();
orient = new TransformTransition(
LMatrix4f::rotate_mat_normaxis(90.0f, LVector3f::forward()));
break;
case SetupItem::Right:
// vertical and horizontal FOV are being switched
hFov = fov.getVert(); vFov = fov.getHoriz();
orient = new TransformTransition(
LMatrix4f::rotate_mat_normaxis(-90.0f, LVector3f::forward()));
break;
}
PT(Lens) lens = new PerspectiveLens;
lens->set_fov(hFov, vFov);
lens->set_near_far(1.0f, 10000.0f);
cam->set_lens(lens);
// hfov and vfov for camera are switched from what was specified
// if the orientation is sideways.
if (chancfg_cat->is_debug())
chancfg_cat->debug() << "ChanEval:: camera hfov = "
<< lens->get_hfov() << " vfov = "
<< lens->get_vfov() << endl;
cam->set_scene(render);
RenderRelation *tocam = new RenderRelation(camera[W.getCameraGroup(j)], cam);
if (orient != (TransformTransition *)NULL) {
tocam->set_transition(orient);
}
}
}
_group_node = camera;
return;
}
ChanConfig::ChanConfig(GraphicsPipe* pipe, std::string cfg, Node *render,
ChanCfgOverrides& overrides) {
ReadChanConfigData();
// check to make sure we know everything we need to
if (!ConfigDefined(cfg)) {
chancfg_cat.error()
<< "no window configuration called '" << cfg << "'" << endl;
_graphics_window = (GraphicsWindow*)0;
return;
}
WindowItem W = (*WindowDB)[cfg];
std::string l = W.getLayout();
if (!LayoutDefined(l)) {
chancfg_cat.error()
<< "No layout called '" << l << "'" << endl;
_graphics_window = (GraphicsWindow*)0;
return;
}
LayoutItem L = (*LayoutDB)[l];
SetupSyms s = W.getSetups();
if (!ChanCheckSetups(s)) {
chancfg_cat.error() << "Setup failure" << endl;
_graphics_window = (GraphicsWindow*)0;
return;
}
SVec S;
S.reserve(s.size());
for (SetupSyms::iterator i=s.begin(); i!=s.end(); ++i)
S.push_back((*SetupDB)[(*i)]);
// get the window data
int sizeX = chanconfig.GetInt("win-width", -1);
int sizeY = chanconfig.GetInt("win-height", -1);
if (overrides.defined(ChanCfgOverrides::SizeX))
sizeX = overrides.getInt(ChanCfgOverrides::SizeX);
if (overrides.defined(ChanCfgOverrides::SizeY))
sizeY = overrides.getInt(ChanCfgOverrides::SizeY);
if (sizeX < 0) {
if (sizeY < 0) {
if(chancfg_cat.is_debug())
chancfg_cat.debug() << "Using default chan-window size\n";
// take the default size
sizeX = W.getSizeX();
sizeY = W.getSizeY();
} else {
// vertical size is defined, compute horizontal keeping the aspect from
// the default
sizeX = (W.getSizeX() * sizeY) / W.getSizeY();
}
} else if (sizeY < 0) {
// horizontal size is defined, compute vertical keeping the aspect from the
// default
sizeY = (W.getSizeY() * sizeX) / W.getSizeX();
}
int origX = chanconfig.GetInt("win-origin-x");
int origY = chanconfig.GetInt("win-origin-y");
origX = overrides.defined(ChanCfgOverrides::OrigX) ?
overrides.getInt(ChanCfgOverrides::OrigX) : origX;
origY = overrides.defined(ChanCfgOverrides::OrigY) ?
overrides.getInt(ChanCfgOverrides::OrigY) : origY;
bool border = !chanconfig.GetBool("no-border", !W.getBorder());
bool fullscreen = chanconfig.GetBool("fullscreen", false);
bool use_cursor = chanconfig.GetBool("cursor-visible", W.getCursor());
int want_depth_bits = chanconfig.GetInt("want-depth-bits", 1);
int want_color_bits = chanconfig.GetInt("want-color-bits", 1);
// visual? nope, that's handled with the mode.
uint mask = 0x0; // ?! this really should come from the win config
mask = overrides.defined(ChanCfgOverrides::Mask) ?
overrides.getUInt(ChanCfgOverrides::Mask) : mask;
std::string title = cfg;
title = overrides.defined(ChanCfgOverrides::Title) ?
overrides.getString(ChanCfgOverrides::Title) : title;
GraphicsWindow::Properties props;
props._xorg = origX;
props._yorg = origY;
props._xsize = sizeX;
props._ysize = sizeY;
props._title = title;
props._mask = mask;
props._border = border;
props._fullscreen = fullscreen;
props._want_depth_bits = want_depth_bits;
props._want_color_bits = want_color_bits;
props._bCursorIsVisible = use_cursor;
// stereo prep?
// DVR prep?
bool want_cameras = overrides.defined(ChanCfgOverrides::Cameras) ?
overrides.getBool(ChanCfgOverrides::Cameras) : true;
// open that sucker
PT(GraphicsWindow) win = pipe->make_window(props);
if(win == (GraphicsWindow *)NULL) {
chancfg_cat.error() << "Could not create window" << endl;
_graphics_window = (GraphicsWindow *)NULL;
return;
}
// make channels and display regions
ChanViewport V(0.0f, 1.0f, 0.0f, 1.0f);
chan_eval(win, W, L, S, V, W.getChanOffset()+1, sizeX, sizeY,
render, want_cameras);
for(size_t dr_index=0; dr_index<_display_region.size(); dr_index++)
_group_membership.push_back(W.getCameraGroup(dr_index));
// sanity check
if (config_sanity_check) {
nout << "ChanConfig Sanity check:" << endl
<< "window - " << (void*)win << endl
<< " width = " << win->get_width() << " height = " << win->get_height() << endl
<< " xorig = " << win->get_xorg() << " yorig = " << win->get_yorg()<< endl;
int max_channel_index = win->get_max_channel_index();
for (int c = 0; c < max_channel_index; c++) {
if (win->is_channel_defined(c)) {
GraphicsChannel *chan = win->get_channel(c);
nout << " Chan - " << (void*)chan << endl
<< " window = " << (void*)(chan->get_window()) << endl
<< " active = " << chan->is_active() << endl;
int num_layers = chan->get_num_layers();
for (int l = 0; l < num_layers; l++) {
GraphicsLayer *layer = chan->get_layer(l);
nout << " Layer - " << (void*)layer << endl
<< " channel = " << (void*)(layer->get_channel()) << endl
<< " active = " << layer->is_active() << endl;
int num_drs = layer->get_num_drs();
for (int d = 0; d < num_drs; d++) {
DisplayRegion *dr = layer->get_dr(d);
nout << " DR - " << (void*)dr << endl
<< " layer = " << (void*)(dr->get_layer()) << endl;
float ll, rr, bb, tt;
dr->get_dimensions(ll, rr, bb, tt);
nout << " (" << ll << " " << rr << " " << bb << " " << tt << ")" << endl
<< " camera = " << (void*)(dr->get_camera()) << endl;
Camera* cmm = dr->get_camera();
if (cmm != (Camera*)0L) {
nout << " active = " << cmm->is_active() << endl;
int num_cam_drs = cmm->get_num_drs();
for (int cd = 0; cd < num_cam_drs; cd++)
nout << " dr = " << (void*)cmm->get_dr(cd) << endl;
}
nout << " active = " << dr->is_active() << endl;
}
}
}
}
}
_graphics_window = win;
return;
}
void qpChanConfig::chan_eval(GraphicsWindow* win, WindowItem& W, LayoutItem& L,
SVec& S,
ChanViewport& V, int hw_offset, int xsize, int ysize,
@ -745,13 +465,14 @@ qpChanConfig::qpChanConfig(GraphicsPipe* pipe, std::string cfg, const qpNodePath
float ll, rr, bb, tt;
dr->get_dimensions(ll, rr, bb, tt);
nout << " (" << ll << " " << rr << " " << bb << " " << tt << ")" << endl
<< " camera = " << (void*)(dr->get_camera()) << endl;
Camera* cmm = dr->get_camera();
if (cmm != (Camera*)0L) {
nout << " active = " << cmm->is_active() << endl;
int num_cam_drs = cmm->get_num_drs();
<< " camera = " << dr->get_qpcamera() << endl;
qpNodePath cmm = dr->get_qpcamera();
if (!cmm.is_empty()) {
qpCamera *cmm_node = DCAST(qpCamera, cmm.node());
nout << " active = " << cmm_node->is_active() << endl;
int num_cam_drs = cmm_node->get_num_display_regions();
for (int cd = 0; cd < num_cam_drs; cd++)
nout << " dr = " << (void*)cmm->get_dr(cd) << endl;
nout << " dr = " << (void*)cmm_node->get_display_region(cd) << endl;
}
nout << " active = " << dr->is_active() << endl;
}

View File

@ -28,14 +28,11 @@
#include "graphicsPipe.h"
#include "graphicsWindow.h"
#include "pt_NamedNode.h"
#include "pandaNode.h"
#include "qpnodePath.h"
#include "pmap.h"
class Node;
class EXPCL_PANDA ChanCfgOverrides {
public:
enum Field { OrigX, OrigY, SizeX, SizeY, Title, Mask, Cameras };
@ -105,28 +102,6 @@ public:
extern ChanCfgOverrides ChanOverrideNone;
typedef pvector<SetupItem> SVec;
class NamedNode;
class EXPCL_PANDA ChanConfig
{
private:
std::vector<PT_NamedNode> _group_node;
std::vector< PT(DisplayRegion) > _display_region;
std::vector<int> _group_membership;
PT(GraphicsWindow) _graphics_window;
void chan_eval(GraphicsWindow* win, WindowItem& W, LayoutItem& L,
SVec& S, ChanViewport& V, int hw_offset,
int xsize, int ysize, Node *render, bool want_cameras);
PUBLISHED:
ChanConfig(GraphicsPipe*, std::string, Node *render,
ChanCfgOverrides& = ChanOverrideNone);
INLINE PT_NamedNode get_group_node(const int node_index) const;
INLINE int get_group_membership(const int dr_index) const;
INLINE int get_num_groups(void) const;
INLINE int get_num_drs(void) const;
INLINE PT(DisplayRegion) get_dr(const int dr_index) const;
INLINE PT(GraphicsWindow) get_win(void) const;
};
class EXPCL_PANDA qpChanConfig
{

View File

@ -4,13 +4,12 @@
#begin lib_target
#define TARGET char
#define LOCAL_LIBS \
chan graph sgraph linmath putil event sgattrib mathutil gsgbase \
chan linmath putil event mathutil gsgbase \
pstatclient
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \
character.I character.h \
qpcharacter.I qpcharacter.h \
characterJoint.h characterJointBundle.I \
characterJointBundle.h characterSlider.h computedVertices.I \
@ -18,7 +17,6 @@
computedVerticesMorph.h config_char.h dynamicVertices.h
#define INCLUDED_SOURCES \
character.cxx \
qpcharacter.cxx \
characterJoint.cxx characterJointBundle.cxx \
characterSlider.cxx computedVertices.cxx \
@ -26,7 +24,6 @@
dynamicVertices.cxx
#define INSTALL_HEADERS \
character.I character.h \
qpcharacter.I qpcharacter.h \
characterJoint.h characterJointBundle.I \
characterJointBundle.h characterSlider.h computedVertices.I \

View File

@ -1,6 +1,5 @@
#include "config_char.cxx"
#include "character.cxx"
#include "qpcharacter.cxx"
#include "characterJoint.cxx"
#include "characterJointBundle.cxx"

View File

@ -1,87 +0,0 @@
// Filename: character.I
// Created by: drose (23Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "characterJointBundle.h"
////////////////////////////////////////////////////////////////////
// Function: Character::get_bundle
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CharacterJointBundle *Character::
get_bundle() const {
return DCAST(CharacterJointBundle, PartBundleNode::get_bundle());
}
////////////////////////////////////////////////////////////////////
// Function: Character::get_computed_vertices
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE ComputedVertices *Character::
get_computed_vertices() const {
return _computed_vertices;
}
////////////////////////////////////////////////////////////////////
// Function: Character::get_num_parts
// Access: Public
// Description: Returns the total number of moving parts (e.g. joints
// and sliders) associated with the character.
////////////////////////////////////////////////////////////////////
INLINE int Character::
get_num_parts() const {
return _parts.size();
}
////////////////////////////////////////////////////////////////////
// Function: Character::get_part
// Access: Public
// Description: Returns the nth moving part associated with the
// character.
////////////////////////////////////////////////////////////////////
INLINE PartGroup *Character::
get_part(int n) const {
nassertr(n >= 0 && n < (int)_parts.size(), NULL);
return _parts[n];
}
////////////////////////////////////////////////////////////////////
// Function: Character::write_parts
// Access: Public
// Description: Writes a list of the character's joints and sliders,
// in their hierchical structure, to the indicated
// output stream.
////////////////////////////////////////////////////////////////////
INLINE void Character::
write_parts(ostream &out) const {
get_bundle()->write(out, 0);
}
////////////////////////////////////////////////////////////////////
// Function: Character::write_part_values
// Access: Public
// Description: Writes a list of the character's joints and sliders,
// along with each current position, in their hierchical
// structure, to the indicated output stream.
////////////////////////////////////////////////////////////////////
INLINE void Character::
write_part_values(ostream &out) const {
get_bundle()->write_with_value(out, 0);
}

View File

@ -1,504 +0,0 @@
// Filename: character.cxx
// Created by: drose (23Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "character.h"
#include "characterJoint.h"
#include "computedVertices.h"
#include "config_char.h"
#include "geomNode.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "pStatTimer.h"
#include "geomNode.h"
#include "animControl.h"
#include "clockObject.h"
#include "pStatTimer.h"
TypeHandle Character::_type_handle;
#ifndef CPPPARSER
PStatCollector Character::_anim_pcollector("App:Animation");
#endif
////////////////////////////////////////////////////////////////////
// Function: Character::Copy Constructor
// Access: Protected
// Description: Use make_copy() or copy_subgraph() to copy a character.
////////////////////////////////////////////////////////////////////
Character::
Character(const Character &copy) :
PartBundleNode(copy.get_name(), new CharacterJointBundle(copy.get_bundle()->get_name())),
_cv(DynamicVertices::deep_copy(copy._cv)),
_computed_vertices(copy._computed_vertices),
_parts(copy._parts),
_char_pcollector(copy._char_pcollector)
{
// Now make a copy of the joint/slider hierarchy. We could just use
// the PartBundleNode's copy constructor, but if we do it ourselves
// we can simultaneously update our _parts list.
copy_joints(get_bundle(), copy.get_bundle());
}
////////////////////////////////////////////////////////////////////
// Function: Character::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
Character::
Character(const string &name) :
PartBundleNode(name, new CharacterJointBundle(name)),
_char_pcollector(_anim_pcollector, name)
{
}
////////////////////////////////////////////////////////////////////
// Function: Character::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
Character::
~Character() {
}
////////////////////////////////////////////////////////////////////
// Function: Character::make_copy
// Access: Public, Virtual
// Description: The Character make_copy() function will make a new
// copy of the character, with all of its joints copied,
// and with a new set of dynamic vertex arrays all ready
// to go, but it will not copy any of the original
// Character's geometry, so the new Character won't look
// like much. Use copy_subgraph() to make a full copy
// of the Character.
////////////////////////////////////////////////////////////////////
Node *Character::
make_copy() const {
return new Character(*this);
}
////////////////////////////////////////////////////////////////////
// Function: Character::safe_to_transform
// Access: Public, Virtual
// Description: Returns true if it is generally safe to transform
// this particular kind of Node by calling the xform()
// method, false otherwise. For instance, it's usually
// a bad idea to attempt to xform a Character.
////////////////////////////////////////////////////////////////////
bool Character::
safe_to_transform() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: Character::app_traverse
// Access: Public, Virtual
// Description: This is called by the App traversal by virtue of the
// character node's being present in the scene graph.
////////////////////////////////////////////////////////////////////
void Character::
app_traverse(const ArcChain &) {
double now = ClockObject::get_global_clock()->get_frame_time();
get_bundle()->advance_time(now);
if (char_cat.is_debug()) {
char_cat.debug() << "Animating " << *this << " at time " << now << "\n";
}
update();
}
////////////////////////////////////////////////////////////////////
// Function: Character::update
// Access: Public
// Description: Recalculates the character's joints and vertices for
// the current frame. Normally this is performed
// automatically during the render and need not be
// called explicitly.
////////////////////////////////////////////////////////////////////
void Character::
update() {
// Statistics
PStatTimer timer(_char_pcollector);
// First, update all the joints and sliders.
bool any_changed = get_bundle()->update();
// Now update the vertices, if we need to. This is likely to be a
// slow operation.
if (any_changed || even_animation) {
if (_computed_vertices != (ComputedVertices *)NULL) {
_computed_vertices->update(this);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: Character::copy_joints
// Access: Private
// Description: Recursively walks the joint/slider hierarchy and
// creates a new copy of the hierarchy.
////////////////////////////////////////////////////////////////////
void Character::
copy_joints(PartGroup *copy, PartGroup *orig) {
if (copy->get_type() != orig->get_type()) {
char_cat.warning()
<< "Don't know how to copy " << orig->get_type() << "\n";
}
PartGroup::Children::const_iterator ci;
for (ci = orig->_children.begin(); ci != orig->_children.end(); ++ci) {
PartGroup *orig_child = (*ci);
PartGroup *copy_child = orig_child->make_copy();
copy->_children.push_back(copy_child);
copy_joints(copy_child, orig_child);
}
Parts::iterator pi = find(_parts.begin(), _parts.end(), orig);
if (pi != _parts.end()) {
(*pi) = copy;
}
}
////////////////////////////////////////////////////////////////////
// Function: Character::r_copy_subgraph
// Access: Private, Virtual
// Description: This is a virtual function inherited from Node. It's
// called when a copy_subgraph() operation reaches the
// Character node. In the case of a Character, it's
// overridden to do the all right things to copy the
// dynamic geometry to the new Character.
//
// Note that it includes the parameter inst_map, which
// is a map type, and is not (and cannot be) exported
// from PANDA.DLL. Thus, any derivative of Node that is
// not also a member of PANDA.DLL *cannot* access this
// map.
////////////////////////////////////////////////////////////////////
Node *Character::
r_copy_subgraph(TypeHandle graph_type, Node::InstanceMap &) const {
Node *copy = make_copy();
nassertr(copy != (Node *)NULL, NULL);
if (copy->get_type() != get_type()) {
graph_cat.warning()
<< "Don't know how to copy nodes of type " << get_type() << "\n";
}
// We assume there will be no instancing going on below the
// Character node. If there is, too bad; it will get flattened out.
// Now we preempt the node's r_copy_subgraph() operation with our
// own function that keeps track of the old vs. new arcs and also
// updates any Geoms we find with our new dynamic vertices.
Character *char_copy;
DCAST_INTO_R(char_copy, copy, NULL);
ArcMap arc_map;
char_copy->r_copy_char(char_copy, this, graph_type, this, arc_map);
char_copy->copy_arc_pointers(this, arc_map);
return copy;
}
////////////////////////////////////////////////////////////////////
// Function: Character::r_copy_char
// Access: Private
// Description: Recursively walks the scene graph hierarchy below the
// Character node, duplicating it while noting the
// orig:copy arc mappings, and also updates any
// GeomNodes found.
////////////////////////////////////////////////////////////////////
void Character::
r_copy_char(Node *dest, const Node *source, TypeHandle graph_type,
const Character *from, Character::ArcMap &arc_map) {
if (source->is_of_type(GeomNode::get_class_type())) {
const GeomNode *source_gnode;
GeomNode *dest_gnode;
DCAST_INTO_V(source_gnode, source);
DCAST_INTO_V(dest_gnode, dest);
dest_gnode->clear();
int num_geoms = source_gnode->get_num_geoms();
for (int i = 0; i < num_geoms; i++) {
dDrawable *d = source_gnode->get_geom(i);
if (d->is_of_type(Geom::get_class_type())) {
dest_gnode->add_geom(copy_geom(DCAST(Geom, d), from));
} else {
dest_gnode->add_geom(d);
}
}
}
int num_children = source->get_num_children(graph_type);
for (int i = 0; i < num_children; i++) {
NodeRelation *source_arc = source->get_child(graph_type, i);
const Node *source_child = source_arc->get_child();
nassertv(source_child != (Node *)NULL);
Node *dest_child;
if (source_child->is_of_type(Character::get_class_type())) {
// We make a special case for nodes of type Character. If we
// encounter one of these, we have a character under a
// character, and the nested character's copy should be called
// instead of ours.
dest_child = source_child->copy_subgraph(graph_type);
} else {
// Otherwise, we assume that make_copy() will make a suitable
// copy of the node. This does limit the sorts of things we can
// have parented to a Character and expect copy_subgraph() to
// work correctly. Too bad.
dest_child = source_child->make_copy();
r_copy_char(dest_child, source_child, graph_type, from, arc_map);
}
NodeRelation *dest_arc =
NodeRelation::create_typed_arc(graph_type, dest, dest_child);
nassertv(dest_arc != (NodeRelation *)NULL);
nassertv(dest_arc->is_exact_type(graph_type));
dest_arc->copy_transitions_from(source_arc);
arc_map[source_arc] = dest_arc;
}
}
////////////////////////////////////////////////////////////////////
// Function: Character::copy_geom
// Access: Private
// Description: Makes a new copy of the Geom with the dynamic vertex
// arrays replaced to reference this character instead
// of the other one. If no arrays have changed, simply
// returns the same Geom.
////////////////////////////////////////////////////////////////////
PT(Geom) Character::
copy_geom(Geom *source, const Character *from) {
GeomBindType bind;
PTA_ushort index;
PTA_Vertexf coords;
PTA_Normalf norms;
PTA_Colorf colors;
PTA_TexCoordf texcoords;
PT(Geom) dest = source;
source->get_coords(coords, index);
if ((coords != (void *)NULL) && (coords == (from->_cv._coords))) {
if (dest == source) {
dest = source->make_copy();
}
dest->set_coords(_cv._coords, index);
}
source->get_normals(norms, bind, index);
if (bind != G_OFF && norms == from->_cv._norms) {
if (dest == source) {
dest = source->make_copy();
}
dest->set_normals(_cv._norms, bind, index);
}
source->get_colors(colors, bind, index);
if (bind != G_OFF && colors == from->_cv._colors) {
if (dest == source) {
dest = source->make_copy();
}
dest->set_colors(_cv._colors, bind, index);
}
source->get_texcoords(texcoords, bind, index);
if (bind != G_OFF && texcoords == from->_cv._texcoords) {
if (dest == source) {
dest = source->make_copy();
}
dest->set_texcoords(_cv._texcoords, bind, index);
}
return dest;
}
////////////////////////////////////////////////////////////////////
// Function: Character::copy_arc_pointers
// Access: Public
// Description: Creates _net_transform_arcs and _local_transform_arcs
// as appropriate in each of the character's joints, as
// copied from the other character.
////////////////////////////////////////////////////////////////////
void Character::
copy_arc_pointers(const Character *from, const Character::ArcMap &arc_map) {
nassertv(_parts.size() == from->_parts.size());
for (int i = 0; i < (int)_parts.size(); i++) {
if (_parts[i]->is_of_type(CharacterJoint::get_class_type())) {
nassertv(_parts[i] != from->_parts[i]);
CharacterJoint *source_joint;
CharacterJoint *dest_joint;
DCAST_INTO_V(source_joint, from->_parts[i]);
DCAST_INTO_V(dest_joint, _parts[i]);
CharacterJoint::ArcList::const_iterator ai;
for (ai = source_joint->_net_transform_arcs.begin();
ai != source_joint->_net_transform_arcs.end();
++ai) {
NodeRelation *source_arc = (*ai);
ArcMap::const_iterator mi;
mi = arc_map.find(source_arc);
if (mi != arc_map.end()) {
NodeRelation *dest_arc = (*mi).second;
// Here's an internal joint that the source Character was
// animating directly. We'll animate our corresponding
// joint the same way.
dest_joint->add_net_transform(dest_arc);
}
}
for (ai = source_joint->_local_transform_arcs.begin();
ai != source_joint->_local_transform_arcs.end();
++ai) {
NodeRelation *source_arc = (*ai);
ArcMap::const_iterator mi;
mi = arc_map.find(source_arc);
if (mi != arc_map.end()) {
NodeRelation *dest_arc = (*mi).second;
// Here's an internal joint that the source Character was
// animating directly. We'll animate our corresponding
// joint the same way.
dest_joint->add_local_transform(dest_arc);
}
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: Character::write_datagram
// Access: Public
// Description: Function to write the important information in
// the particular object to a Datagram
////////////////////////////////////////////////////////////////////
void Character::
write_datagram(BamWriter *manager, Datagram &me)
{
PartBundleNode::write_datagram(manager, me);
_cv.write_datagram(manager, me);
manager->write_pointer(me, _computed_vertices);
me.add_uint16(_parts.size());
Parts::const_iterator pi;
for (pi = _parts.begin(); pi != _parts.end(); pi++) {
manager->write_pointer(me, (*pi));
}
}
////////////////////////////////////////////////////////////////////
// Function: Character::fillin
// Access: Protected
// Description: Function that reads out of the datagram (or asks
// manager to read) all of the data that is needed to
// re-create this object and stores it in the appropiate
// place
////////////////////////////////////////////////////////////////////
void Character::
fillin(DatagramIterator& scan, BamReader* manager)
{
PartBundleNode::fillin(scan, manager);
_cv.fillin(scan, manager);
manager->read_pointer(scan);
// Read the number of parts to expect in the _parts list, and then
// fill the array up with NULLs. We'll fill in the actual values in
// complete_pointers, later.
int num_parts = scan.get_uint16();
_parts.clear();
_parts.reserve(num_parts);
for (int i = 0; i < num_parts; i++) {
manager->read_pointer(scan);
_parts.push_back((PartGroup *)NULL);
}
#ifdef DO_PSTATS
// Reinitialize our collector with our name, now that we know it.
if (has_name()) {
_char_pcollector =
PStatCollector(_anim_pcollector, get_name());
}
#endif
}
////////////////////////////////////////////////////////////////////
// Function: Character::complete_pointers
// Access: Public
// Description: Takes in a vector of pointers to TypedWritable
// objects that correspond to all the requests for
// pointers that this object made to BamReader.
////////////////////////////////////////////////////////////////////
int Character::
complete_pointers(TypedWritable **p_list, BamReader* manager)
{
int start = PartBundleNode::complete_pointers(p_list, manager);
_computed_vertices = DCAST(ComputedVertices, p_list[start]);
start++;
int num_parts = _parts.size();
for (int i = 0; i < num_parts; i++) {
_parts[i] = DCAST(PartGroup, p_list[start + i]);
}
start += num_parts;
return start;
}
////////////////////////////////////////////////////////////////////
// Function: Character::make_Character
// Access: Protected
// Description: Factory method to generate a Character object
////////////////////////////////////////////////////////////////////
TypedWritable* Character::
make_Character(const FactoryParams &params)
{
Character *me = new Character;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}
////////////////////////////////////////////////////////////////////
// Function: Character::register_with_factory
// Access: Public, Static
// Description: Factory method to generate a Character object
////////////////////////////////////////////////////////////////////
void Character::
register_with_read_factory(void)
{
BamReader::get_factory()->register_factory(get_class_type(), make_Character);
}

View File

@ -1,136 +0,0 @@
// Filename: character.h
// Created by: drose (23Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef CHARACTER_H
#define CHARACTER_H
#include "pandabase.h"
#include "computedVertices.h"
#include "partBundleNode.h"
#include "namedNode.h"
#include "vector_PartGroupStar.h"
#include "pointerTo.h"
#include "geom.h"
#include "pStatCollector.h"
class CharacterJointBundle;
class ComputedVertices;
////////////////////////////////////////////////////////////////////
// Class : Character
// Description :
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA Character : public PartBundleNode {
protected:
Character(const Character &copy);
public:
Character(const string &name = "");
virtual ~Character();
virtual Node *make_copy() const;
virtual bool safe_to_transform() const;
PUBLISHED:
INLINE CharacterJointBundle *get_bundle() const;
INLINE ComputedVertices *get_computed_vertices() const;
INLINE int get_num_parts() const;
INLINE PartGroup *get_part(int n) const;
INLINE void write_parts(ostream &out) const;
INLINE void write_part_values(ostream &out) const;
public:
virtual void app_traverse(const ArcChain &chain);
PUBLISHED:
void update();
private:
void copy_joints(PartGroup *copy, PartGroup *orig);
typedef pmap<NodeRelation *, NodeRelation *> ArcMap;
virtual Node *r_copy_subgraph(TypeHandle graph_type,
InstanceMap &inst_map) const;
void r_copy_char(Node *dest, const Node *source, TypeHandle graph_type,
const Character *from, ArcMap &arc_map);
PT(Geom) copy_geom(Geom *source, const Character *from);
void copy_arc_pointers(const Character *from, const ArcMap &arc_map);
// These are the actual dynamic vertex pools for this character's
// ComputedVertices--the vertices that it will recompute each frame
// based on the soft-skinning and morphing requirements. Note that
// we store this concretely, instead of as a pointer, just because
// we don't really need to make it a pointer.
DynamicVertices _cv;
// And this is the object that animates them. It *is* a pointer, so
// it can be shared between multiple instances of this character.
PT(ComputedVertices) _computed_vertices;
// This vector is used by the ComputedVertices object to index back
// into our joints and sliders.
typedef vector_PartGroupStar Parts;
Parts _parts;
// Statistics
PStatCollector _char_pcollector;
static PStatCollector _anim_pcollector;
public:
static void register_with_read_factory(void);
virtual void write_datagram(BamWriter* manager, Datagram &me);
virtual int complete_pointers(TypedWritable **p_list,
BamReader *manager);
static TypedWritable *make_Character(const FactoryParams &params);
protected:
void fillin(DatagramIterator& scan, BamReader* manager);
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
PartBundleNode::init_type();
register_type(_type_handle, "Character",
PartBundleNode::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class CharacterMaker;
friend class ComputedVerticesMaker;
friend class ComputedVertices;
};
#include "character.I"
#endif

View File

@ -19,12 +19,11 @@
#include "characterJoint.h"
#include "config_char.h"
#include <compose_matrix.h>
#include <transformTransition.h>
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
#include "compose_matrix.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
TypeHandle CharacterJoint::_type_handle;
@ -48,7 +47,7 @@ CharacterJoint(const CharacterJoint &copy) :
_net_transform(copy._net_transform),
_initial_net_transform_inverse(copy._initial_net_transform_inverse)
{
// We don't copy the sets of transform arcs.
// We don't copy the sets of transform nodes.
}
////////////////////////////////////////////////////////////////////
@ -120,46 +119,6 @@ update_internals(PartGroup *parent, bool self_changed, bool parent_changed) {
}
}
if (net_changed && !_net_transform_arcs.empty()) {
PT(TransformTransition) t = new TransformTransition(_net_transform);
ArcList::iterator ai;
ai = _net_transform_arcs.begin();
while (ai != _net_transform_arcs.end()) {
NodeRelation *arc = *ai;
if (arc->is_attached()) {
arc->set_transition(t);
++ai;
} else {
// The arc is now invalid; its geometry must have been
// removed. Remove the arc from our set.
ArcList::iterator invalid = ai;
++ai;
_net_transform_arcs.erase(invalid);
}
}
}
if (self_changed && !_local_transform_arcs.empty()) {
PT(TransformTransition) t = new TransformTransition(_value);
ArcList::iterator ai;
ai = _local_transform_arcs.begin();
while (ai != _local_transform_arcs.end()) {
NodeRelation *arc = *ai;
if (arc->is_attached()) {
arc->set_transition(t);
++ai;
} else {
// The arc is now invalid; its geometry must have been
// removed. Remove the arc from our set.
ArcList::iterator invalid = ai;
++ai;
_local_transform_arcs.erase(invalid);
}
}
}
if (net_changed && !_net_transform_nodes.empty()) {
CPT(TransformState) t = TransformState::make_mat(_net_transform);
@ -187,85 +146,6 @@ update_internals(PartGroup *parent, bool self_changed, bool parent_changed) {
return self_changed || net_changed;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::add_net_transform
// Access: Public
// Description: Adds the indicated arc to the list of arcs that will
// be updated each frame with the joint's net transform
// from the root. Returns true if the arc is
// successfully added, false if it had already been
// added.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
add_net_transform(NodeRelation *arc) {
return _net_transform_arcs.insert(arc).second;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::remove_net_transform
// Access: Public
// Description: Removes the indicated arc from the list of arcs that
// will be updated each frame with the joint's net
// transform from the root. Returns true if the arc is
// successfully removed, false if it was not on the
// list.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
remove_net_transform(NodeRelation *arc) {
return (_net_transform_arcs.erase(arc) > 0);
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::has_net_transform
// Access: Public
// Description: Returns true if the arc is on the list of arcs that
// will be updated each frame with the joint's net
// transform from the root, false otherwise.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
has_net_transform(NodeRelation *arc) const {
return (_net_transform_arcs.count(arc) > 0);
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::add_local_transform
// Access: Public
// Description: Adds the indicated arc to the list of arcs that will
// be updated each frame with the joint's local
// transform from its parent. Returns true if the arc
// is successfully added, false if it had already been
// added.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
add_local_transform(NodeRelation *arc) {
return _local_transform_arcs.insert(arc).second;
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::remove_local_transform
// Access: Public
// Description: Removes the indicated arc from the list of arcs that
// will be updated each frame with the joint's local
// transform from its parent. Returns true if the arc
// is successfully removed, false if it was not on the
// list.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
remove_local_transform(NodeRelation *arc) {
return (_local_transform_arcs.erase(arc) > 0);
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::has_local_transform
// Access: Public
// Description: Returns true if the arc is on the list of arcs that
// will be updated each frame with the joint's local
// transform from its parent, false otherwise.
////////////////////////////////////////////////////////////////////
bool CharacterJoint::
has_local_transform(NodeRelation *arc) const {
return (_local_transform_arcs.count(arc) > 0);
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJoint::add_net_transform
@ -316,7 +196,6 @@ has_net_transform(PandaNode *node) const {
////////////////////////////////////////////////////////////////////
void CharacterJoint::
clear_net_transforms() {
_net_transform_arcs.clear();
_net_transform_nodes.clear();
}
@ -369,7 +248,6 @@ has_local_transform(PandaNode *node) const {
////////////////////////////////////////////////////////////////////
void CharacterJoint::
clear_local_transforms() {
_local_transform_arcs.clear();
_local_transform_nodes.clear();
}
@ -382,53 +260,13 @@ clear_local_transforms() {
void CharacterJoint::
write_datagram(BamWriter *manager, Datagram &me)
{
ArcList::iterator ai;
NodeList::iterator ni;
// First, make sure all of our arcs are still valid, before we try
// to write them out. Remove any invalid arcs.
ai = _net_transform_arcs.begin();
while (ai != _net_transform_arcs.end()) {
NodeRelation *arc = *ai;
if (arc->is_attached()) {
++ai;
} else {
// The arc is now invalid; its geometry must have been
// removed. Remove the arc from our set.
ArcList::iterator invalid = ai;
++ai;
_net_transform_arcs.erase(invalid);
}
}
ai = _local_transform_arcs.begin();
while (ai != _local_transform_arcs.end()) {
NodeRelation *arc = *ai;
if (arc->is_attached()) {
++ai;
} else {
// The arc is now invalid; its geometry must have been
// removed. Remove the arc from our set.
ArcList::iterator invalid = ai;
++ai;
_local_transform_arcs.erase(invalid);
}
}
MovingPartMatrix::write_datagram(manager, me);
me.add_uint16(_net_transform_arcs.size());
for(ai = _net_transform_arcs.begin();
ai != _net_transform_arcs.end();
ai++) {
manager->write_pointer(me, (*ai));
}
me.add_uint16(_local_transform_arcs.size());
for(ai = _local_transform_arcs.begin();
ai != _local_transform_arcs.end();
ai++) {
manager->write_pointer(me, (*ai));
}
// Legacy. We don't store the list of arcs any more. Remove this
// when we go to bam version 4.0.
me.add_uint16(0);
me.add_uint16(0);
me.add_uint16(_net_transform_nodes.size());
for(ni = _net_transform_nodes.begin();
@ -459,15 +297,12 @@ void CharacterJoint::
fillin(DatagramIterator &scan, BamReader *manager) {
int i;
MovingPartMatrix::fillin(scan, manager);
_num_net_arcs = scan.get_uint16();
for(i = 0; i < _num_net_arcs; i++) {
manager->read_pointer(scan);
}
_num_local_arcs = scan.get_uint16();
for(i = 0; i < _num_local_arcs; i++) {
manager->read_pointer(scan);
}
// Remove this when we go to bam 4.0.
int num_net_arcs = scan.get_uint16();
nassertv(num_net_arcs == 0);
int num_local_arcs = scan.get_uint16();
nassertv(num_local_arcs == 0);
if (manager->get_file_minor_ver() < 7) {
// No _node lists before version 3.7.
@ -501,14 +336,6 @@ complete_pointers(TypedWritable **p_list, BamReader* manager)
int pi = MovingPartMatrix::complete_pointers(p_list, manager);
int i;
for (i = 0; i < _num_net_arcs; i++) {
add_net_transform(DCAST(NodeRelation, p_list[pi++]));
}
for (i = 0; i < _num_local_arcs; i++) {
add_local_transform(DCAST(NodeRelation, p_list[pi++]));
}
for (i = 0; i < _num_net_nodes; i++) {
add_net_transform(DCAST(PandaNode, p_list[pi++]));
}

View File

@ -19,13 +19,10 @@
#ifndef CHARACTERJOINT_H
#define CHARACTERJOINT_H
#include <pandabase.h>
#include "pandabase.h"
#include <movingPartMatrix.h>
#include <namedNode.h>
#include <nodeRelation.h>
#include <pt_NamedNode.h>
#include <pt_NodeRelation.h>
#include "movingPartMatrix.h"
#include "pandaNode.h"
////////////////////////////////////////////////////////////////////
// Class : CharacterJoint
@ -47,14 +44,6 @@ public:
bool parent_changed);
PUBLISHED:
bool add_net_transform(NodeRelation *arc);
bool remove_net_transform(NodeRelation *arc);
bool has_net_transform(NodeRelation *arc) const;
bool add_local_transform(NodeRelation *arc);
bool remove_local_transform(NodeRelation *arc);
bool has_local_transform(NodeRelation *arc) const;
bool add_net_transform(PandaNode *node);
bool remove_net_transform(PandaNode *node);
bool has_net_transform(PandaNode *node) const;
@ -66,10 +55,6 @@ PUBLISHED:
void clear_local_transforms();
private:
typedef pset< PT_NodeRelation > ArcList;
ArcList _net_transform_arcs;
ArcList _local_transform_arcs;
typedef pset< PT(PandaNode) > NodeList;
NodeList _net_transform_nodes;
NodeList _local_transform_nodes;
@ -86,7 +71,6 @@ protected:
void fillin(DatagramIterator& scan, BamReader* manager);
private:
int _num_net_arcs, _num_local_arcs;
int _num_net_nodes, _num_local_nodes;
public:
@ -94,7 +78,6 @@ public:
// for the CharacterMaker's convenenience while creating the
// character. It does not store any meaningful value after
// creation is complete.
PT_NamedNode _geom_node;
PT(PandaNode) _qpgeom_node;
// These are filled in as the joint animates.

View File

@ -20,7 +20,7 @@
// #include reference, and please don't bother us about it. The line
// must be exactly as shown.
/* okcircular */
#include "character.h"
#include "qpcharacter.h"
////////////////////////////////////////////////////////////////////
// Function: CharacterJointBundle::Copy Constructor
@ -35,12 +35,12 @@ CharacterJointBundle(const CharacterJointBundle &copy) :
}
////////////////////////////////////////////////////////////////////
// Function: CharacterJointBundle::get_node
// Function: CharacterJointBundle::get_qpnode
// Access: Public
// Description: Returns the Character node associated with this
// PartBundle.
////////////////////////////////////////////////////////////////////
INLINE Character *CharacterJointBundle::
get_node() const {
return DCAST(Character, PartBundle::get_node());
INLINE qpCharacter *CharacterJointBundle::
get_qpnode() const {
return DCAST(qpCharacter, PartBundle::get_qpnode());
}

View File

@ -17,11 +17,10 @@
////////////////////////////////////////////////////////////////////
#include "characterJointBundle.h"
#include "character.h"
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
TypeHandle CharacterJointBundle::_type_handle;

View File

@ -19,13 +19,13 @@
#ifndef CHARACTERJOINTBUNDLE_H
#define CHARACTERJOINTBUNDLE_H
#include <pandabase.h>
#include "pandabase.h"
#include <partBundle.h>
#include <partGroup.h>
#include <animControl.h>
#include "partBundle.h"
#include "partGroup.h"
#include "animControl.h"
class Character;
class qpCharacter;
////////////////////////////////////////////////////////////////////
// Class : CharacterJointBundle
@ -40,7 +40,7 @@ public:
CharacterJointBundle(const string &name = "");
PUBLISHED:
INLINE Character *get_node() const;
INLINE qpCharacter *get_qpnode() const;
public:
virtual PartGroup *make_copy() const;

View File

@ -19,15 +19,15 @@
#include "computedVertices.h"
#include "characterJoint.h"
#include "character.h"
#include "qpcharacter.h"
#include "config_char.h"
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
#include <ioPtaDatagramLinMath.h>
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "ioPtaDatagramLinMath.h"
#include <algorithm>
TypeHandle ComputedVertices::_type_handle;
@ -54,11 +54,10 @@ VertexTransform(const VertexTransform &copy) :
// vertices in the table, according to the values of the
// relevant slider.
////////////////////////////////////////////////////////////////////
// QP
template<class ValueType, class MorphType, class Character>
template<class ValueType, class MorphType>
static void
compute_morphs(ValueType *table, const pvector<MorphType> &morph_list,
Character *character) {
qpCharacter *character) {
pvector<MorphType>::const_iterator mli;
for (mli = morph_list.begin(); mli != morph_list.end(); ++mli) {
const MorphType &morph = (*mli);
@ -129,108 +128,6 @@ read_datagram(DatagramIterator &source)
}
}
////////////////////////////////////////////////////////////////////
// Function: ComputedVertices::update
// Access: Public
// Description: Recomputes all of the _coords, _norms, etc. values
// based on the values in _orig_coords, _orig_norms,
// etc., and the current positions of all of the joints.
////////////////////////////////////////////////////////////////////
void ComputedVertices::
update(Character *character) {
nassertv(character != (Character *)NULL);
nassertv(character->_cv._coords.size() == _orig_coords.size());
nassertv(character->_cv._norms.size() == _orig_norms.size());
nassertv(character->_cv._texcoords.size() == _orig_texcoords.size());
nassertv(character->_cv._colors.size() == _orig_colors.size());
const Vertexf *orig_coords = _orig_coords;
const Normalf *orig_norms = _orig_norms;
memset(character->_cv._coords, 0, sizeof(Vertexf) * character->_cv._coords.size());
memset(character->_cv._norms, 0, sizeof(Normalf) * character->_cv._norms.size());
if (!_vertex_morphs.empty()) {
// We have some vertex morphs. Compute them first.
int table_size = sizeof(Vertexf) * _orig_coords.size();
Vertexf *morphed_coords = (Vertexf *)alloca(table_size);
memcpy(morphed_coords, _orig_coords, table_size);
compute_morphs(morphed_coords, _vertex_morphs, character);
orig_coords = morphed_coords;
}
if (!_normal_morphs.empty()) {
// We also have some normal morphs. Compute them too.
int table_size = sizeof(Normalf) * _orig_norms.size();
Normalf *morphed_norms = (Normalf *)alloca(table_size);
memcpy(morphed_norms, _orig_norms, table_size);
compute_morphs(morphed_norms, _normal_morphs, character);
orig_norms = morphed_norms;
}
if (!_texcoord_morphs.empty()) {
// We have some uv morphs. These don't particularly need to be
// done before the joints are computed, but do them now anyway.
int table_size = sizeof(TexCoordf) * _orig_texcoords.size();
// **** Is this right? Test it!
// TexCoordf *morphed_texcoords = (TexCoordf *)alloca(table_size);
memcpy(character->_cv._texcoords, _orig_texcoords, table_size);
compute_morphs(character->_cv._texcoords.p(), _texcoord_morphs, character);
}
if (!_color_morphs.empty()) {
// We have some color morphs. Do these now too.
int table_size = sizeof(Colorf) * _orig_colors.size();
// **** Is this right? Test it!
// Colorf *morphed_colors = (Colorf *)alloca(table_size);
memcpy(character->_cv._colors, _orig_colors, table_size);
compute_morphs(character->_cv._colors.p(), _color_morphs, character);
}
// Now that we've computed all the morphs, it's safe to transform
// vertices into their proper coordinate space, according to the
// current positions of all the joints.
LMatrix4f mat = LMatrix4f::ident_mat();
int last_joint_index = -1;
VertexTransforms::const_iterator vti;
for (vti = _transforms.begin(); vti != _transforms.end(); ++vti) {
const VertexTransform &vt = (*vti);
// We cache the matrix from the last joint, because we are likely
// to encounter the same joint several times in a row.
if (vt._joint_index != last_joint_index) {
last_joint_index = vt._joint_index;
// We won't encounter -1 after the first few joints.
nassertv(vt._joint_index >= 0);
CharacterJoint *joint;
DCAST_INTO_V(joint, character->get_part(vt._joint_index));
mat =
joint->_initial_net_transform_inverse *
joint->_net_transform;
}
Vertices::const_iterator vi;
for (vi = vt._vindex.begin(); vi != vt._vindex.end(); ++vi) {
int i = (*vi);
character->_cv._coords[i] += (orig_coords[i] * mat) * vt._effect;
}
for (vi = vt._nindex.begin(); vi != vt._nindex.end(); ++vi) {
int i = (*vi);
character->_cv._norms[i] += (orig_norms[i] * mat) * vt._effect;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: ComputedVertices::update
// Access: Public
@ -333,46 +230,6 @@ update(qpCharacter *character) {
}
}
////////////////////////////////////////////////////////////////////
// Function: ComputedVertices::make_orig
// Access: Public
// Description: Copies all the values loaded in the _coords, _norms,
// etc. arrays into the corresponding _orig_coords,
// etc. arrays.
////////////////////////////////////////////////////////////////////
void ComputedVertices::
make_orig(Character *character) {
nassertv(character != (Character *)NULL);
if (character->_cv._coords.empty()) {
_orig_coords.clear();
} else {
_orig_coords = PTA_Vertexf::empty_array(0);
_orig_coords.v() = character->_cv._coords.v();
}
if (character->_cv._norms.empty()) {
_orig_norms.clear();
} else {
_orig_norms = PTA_Normalf::empty_array(0);
_orig_norms.v() = character->_cv._norms.v();
}
if (character->_cv._colors.empty()) {
_orig_colors.clear();
} else {
_orig_colors = PTA_Colorf::empty_array(0);
_orig_colors.v() = character->_cv._colors.v();
}
if (character->_cv._texcoords.empty()) {
_orig_texcoords.clear();
} else {
_orig_texcoords = PTA_TexCoordf::empty_array(0);
_orig_texcoords.v() = character->_cv._texcoords.v();
}
}
////////////////////////////////////////////////////////////////////
// Function: ComputedVertices::make_orig
// Access: Public
@ -419,7 +276,7 @@ make_orig(qpCharacter *character) {
// Description:
////////////////////////////////////////////////////////////////////
void ComputedVertices::
write(ostream &out, Character *character) const {
write(ostream &out, qpCharacter *character) const {
VertexTransforms::const_iterator vti;
out << "ComputedVertices:\n";

View File

@ -27,7 +27,6 @@
#include "vector_ushort.h"
#include "typedWritableReferenceCount.h"
class Character;
class qpCharacter;
class CharacterJoint;
@ -42,12 +41,10 @@ class EXPCL_PANDA ComputedVertices : public TypedWritableReferenceCount {
public:
INLINE ComputedVertices();
void update(Character *character);
void update(qpCharacter *character);
void make_orig(Character *character);
void make_orig(qpCharacter *character);
void write(ostream &out, Character *character) const;
void write(ostream &out, qpCharacter *character) const;
private:
typedef vector_ushort Vertices;

View File

@ -18,7 +18,6 @@
#include "config_char.h"
#include "character.h"
#include "qpcharacter.h"
#include "characterJoint.h"
#include "characterJointBundle.h"
@ -67,7 +66,6 @@ init_libchar() {
}
initialized = true;
Character::init_type();
qpCharacter::init_type();
CharacterJoint::init_type();
CharacterJointBundle::init_type();
@ -83,7 +81,6 @@ init_libchar() {
//Registration of writeable object's creation
//functions with BamReader's factory
Character::register_with_read_factory();
qpCharacter::register_with_read_factory();
CharacterJoint::register_with_read_factory();
CharacterJointBundle::register_with_read_factory();

View File

@ -4,90 +4,60 @@
#begin lib_target
#define TARGET collide
#define LOCAL_LIBS \
sgmanip tform sgraphutil gobj graph putil \
tform gobj pgraph putil \
pstatclient
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \
collisionEntry.I collisionEntry.h \
qpcollisionEntry.I qpcollisionEntry.h \
collisionHandler.h \
qpcollisionHandler.h \
collisionHandlerEvent.I collisionHandlerEvent.h \
qpcollisionHandlerEvent.I qpcollisionHandlerEvent.h \
collisionHandlerFloor.I collisionHandlerFloor.h \
qpcollisionHandlerFloor.I qpcollisionHandlerFloor.h \
collisionHandlerPhysical.I collisionHandlerPhysical.h \
qpcollisionHandlerPhysical.I qpcollisionHandlerPhysical.h \
collisionHandlerPusher.I collisionHandlerPusher.h \
qpcollisionHandlerPusher.I qpcollisionHandlerPusher.h \
collisionHandlerQueue.h \
qpcollisionHandlerQueue.h \
collisionLevelState.I collisionLevelState.h \
qpcollisionLevelState.I qpcollisionLevelState.h \
collisionNode.I collisionNode.h \
qpcollisionNode.I qpcollisionNode.h \
collisionPlane.I collisionPlane.h \
collisionPolygon.I collisionPolygon.h collisionRay.I \
collisionRay.h collisionSegment.I collisionSegment.h \
collisionSolid.I collisionSolid.h collisionSphere.I \
collisionSphere.h \
collisionTraverser.I collisionTraverser.h \
qpcollisionTraverser.I qpcollisionTraverser.h \
config_collide.h
#define INCLUDED_SOURCES \
collisionEntry.cxx \
qpcollisionEntry.cxx \
collisionHandler.cxx \
qpcollisionHandler.cxx \
collisionHandlerEvent.cxx \
qpcollisionHandlerEvent.cxx \
collisionHandlerFloor.cxx \
qpcollisionHandlerFloor.cxx \
collisionHandlerPhysical.cxx \
qpcollisionHandlerPhysical.cxx \
collisionHandlerPusher.cxx \
qpcollisionHandlerPusher.cxx \
collisionHandlerQueue.cxx \
qpcollisionHandlerQueue.cxx \
collisionLevelState.cxx \
qpcollisionLevelState.cxx \
collisionNode.cxx \
qpcollisionNode.cxx \
collisionPlane.cxx \
collisionPolygon.cxx collisionRay.cxx collisionSegment.cxx \
collisionSolid.cxx collisionSphere.cxx \
collisionTraverser.cxx \
qpcollisionTraverser.cxx \
config_collide.cxx
#define INSTALL_HEADERS \
collisionEntry.I collisionEntry.h \
qpcollisionEntry.I qpcollisionEntry.h \
collisionHandler.h \
qpcollisionHandler.h \
collisionHandlerEvent.I collisionHandlerEvent.h \
qpcollisionHandlerEvent.I qpcollisionHandlerEvent.h \
collisionHandlerFloor.I collisionHandlerFloor.h \
qpcollisionHandlerFloor.I qpcollisionHandlerFloor.h \
collisionHandlerPhysical.I collisionHandlerPhysical.h \
qpcollisionHandlerPhysical.I qpcollisionHandlerPhysical.h \
collisionHandlerPusher.I collisionHandlerPusher.h \
qpcollisionHandlerPusher.I qpcollisionHandlerPusher.h \
collisionHandlerQueue.h \
qpcollisionHandlerQueue.h \
collisionLevelState.I collisionLevelState.h \
qpcollisionLevelState.I qpcollisionLevelState.h \
collisionNode.I collisionNode.h \
qpcollisionNode.I qpcollisionNode.h \
collisionPlane.I collisionPlane.h \
collisionPolygon.I collisionPolygon.h collisionRay.I collisionRay.h \
collisionSegment.I collisionSegment.h \
collisionSolid.I collisionSolid.h collisionSphere.I \
collisionSphere.h \
collisionTraverser.I collisionTraverser.h \
qpcollisionTraverser.I qpcollisionTraverser.h
#define IGATESCAN all

View File

@ -1,21 +1,12 @@
#include "config_collide.cxx"
#include "collisionEntry.cxx"
#include "qpcollisionEntry.cxx"
#include "collisionHandler.cxx"
#include "qpcollisionHandler.cxx"
#include "collisionHandlerEvent.cxx"
#include "qpcollisionHandlerEvent.cxx"
#include "collisionHandlerFloor.cxx"
#include "qpcollisionHandlerFloor.cxx"
#include "collisionHandlerPhysical.cxx"
#include "qpcollisionHandlerPhysical.cxx"
#include "collisionHandlerPusher.cxx"
#include "qpcollisionHandlerPusher.cxx"
#include "collisionHandlerQueue.cxx"
#include "qpcollisionHandlerQueue.cxx"
#include "collisionLevelState.cxx"
#include "qpcollisionLevelState.cxx"
#include "collisionNode.cxx"
#include "qpcollisionNode.cxx"

View File

@ -5,7 +5,6 @@
#include "collisionSegment.cxx"
#include "collisionSolid.cxx"
#include "collisionSphere.cxx"
#include "collisionTraverser.cxx"
#include "qpcollisionTraverser.cxx"

View File

@ -1,297 +0,0 @@
// Filename: collisionEntry.I
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CollisionEntry::
CollisionEntry() {
_flags = 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_from
// Access: Public
// Description: Returns the CollisionSolid pointer for the particular
// solid that triggered this collision.
////////////////////////////////////////////////////////////////////
INLINE const CollisionSolid *CollisionEntry::
get_from() const {
return _from;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::has_into
// Access: Public
// 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
// this returns false, the collision was detected into a
// GeomNode, and there is no CollisionSolid pointer to
// be retrieved.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionEntry::
has_into() const {
return (_into != (CollisionSolid *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_into
// Access: Public
// 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
// geometry, instead of a normal CollisionSolid
// collision; see has_into().
////////////////////////////////////////////////////////////////////
INLINE const CollisionSolid *CollisionEntry::
get_into() const {
return _into;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_from_node
// Access: Public
// 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
// add_collider().
////////////////////////////////////////////////////////////////////
INLINE CollisionNode *CollisionEntry::
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
// Description: Returns the node that contains the CollisionSolid
// that was collided into. This returns a NamedNode
// pointer instead of something more specific, because
// it might be either a CollisionNode or a GeomNode.
//
// Also see get_into_node_path().
////////////////////////////////////////////////////////////////////
INLINE NamedNode *CollisionEntry::
get_into_node() const {
return _into_node;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_into_node_path
// Access: Public
// Description: Returns the NodePath that represents the specific
// CollisionNode or GeomNode instance that was collided
// into. This is the same node returned by
// get_into_node(), represented as a NodePath; however,
// it may be more useful because the NodePath can
// resolve the particular instance of the node, if there
// is more than one.
////////////////////////////////////////////////////////////////////
INLINE const NodePath &CollisionEntry::
get_into_node_path() const {
return _into_node_path;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_into_space
// Access: Public
// 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_space() const {
return _into_space;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_wrt_space
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const LMatrix4f &CollisionEntry::
get_wrt_space() const {
return _wrt_space;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_inv_wrt_space
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const LMatrix4f &CollisionEntry::
get_inv_wrt_space() const {
return _inv_wrt_space;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::set_into_intersection_point
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionEntry::
set_into_intersection_point(const LPoint3f &point) {
_into_intersection_point = point;
_flags |= F_has_into_intersection_point;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::has_into_intersection_point
// Access: Public
// Description: Returns true if the detected collision knows its
// intersection point in the coordinate space of the
// collided-into object, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionEntry::
has_into_intersection_point() const {
return (_flags & F_has_into_intersection_point) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_into_intersection_point
// Access: Public
// 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
// false.
////////////////////////////////////////////////////////////////////
INLINE const LPoint3f &CollisionEntry::
get_into_intersection_point() const {
nassertr(has_into_intersection_point(), _into_intersection_point);
return _into_intersection_point;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::has_from_intersection_point
// Access: Public
// Description: Returns true if the detected collision knows its
// intersection point in the coordinate space of the
// colliding object, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionEntry::
has_from_intersection_point() const {
// Since we derive the from_intersection_point from the
// into_intersection_point, this is really the same question.
return has_into_intersection_point();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_from_intersection_point
// Access: Public
// 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
// false.
////////////////////////////////////////////////////////////////////
INLINE LPoint3f CollisionEntry::
get_from_intersection_point() const {
return get_into_intersection_point() * get_inv_wrt_space();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::set_into_surface_normal
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionEntry::
set_into_surface_normal(const LVector3f &normal) {
_into_surface_normal = normal;
_flags |= F_has_into_surface_normal;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::has_into_surface_normal
// Access: Public
// Description: Returns true if the detected collision knows the
// surface normal of the collided-into object at the
// point of the collision, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionEntry::
has_into_surface_normal() const {
return (_flags & F_has_into_surface_normal) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_into_surface_normal
// Access: Public
// 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
// false.
////////////////////////////////////////////////////////////////////
INLINE const LVector3f &CollisionEntry::
get_into_surface_normal() const {
nassertr(has_into_surface_normal(), _into_surface_normal);
return _into_surface_normal;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::set_into_depth
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionEntry::
set_into_depth(float depth) {
_into_depth = depth;
_flags |= F_has_into_depth;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::has_into_depth
// Access: Public
// 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
// object the colliding object has penetrated.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionEntry::
has_into_depth() const {
return (_flags & F_has_into_depth) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_into_depth
// Access: Public
// 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
// object has penetrated. It is an error to call this
// if has_into_depth() returns false.
////////////////////////////////////////////////////////////////////
INLINE float CollisionEntry::
get_into_depth() const {
nassertr(has_into_depth(), 0.0);
return _into_depth;
}

View File

@ -1,66 +0,0 @@
// Filename: collisionEntry.cxx
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionEntry.h"
TypeHandle CollisionEntry::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CollisionEntry::
CollisionEntry(const CollisionEntry &copy) :
_from(copy._from),
_into(copy._into),
_from_node(copy._from_node),
_into_node(copy._into_node),
_into_node_path(copy._into_node_path),
_from_space(copy._from_space),
_into_space(copy._into_space),
_wrt_space(copy._wrt_space),
_inv_wrt_space(copy._inv_wrt_space),
_flags(copy._flags),
_into_intersection_point(copy._into_intersection_point),
_into_surface_normal(copy._into_surface_normal),
_into_depth(copy._into_depth)
{
}
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionEntry::
operator = (const CollisionEntry &copy) {
_from = copy._from;
_into = copy._into;
_from_node = copy._from_node;
_into_node = copy._into_node;
_into_node_path = copy._into_node_path;
_from_space = copy._from_space;
_into_space = copy._into_space;
_wrt_space = copy._wrt_space;
_inv_wrt_space = copy._inv_wrt_space;
_flags = copy._flags;
_into_intersection_point = copy._into_intersection_point;
_into_surface_normal = copy._into_surface_normal;
_into_depth = copy._into_depth;
}

View File

@ -1,131 +0,0 @@
// Filename: collisionEntry.h
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONENTRY_H
#define COLLISIONENTRY_H
#include <pandabase.h>
#include "collisionSolid.h"
#include "collisionNode.h"
#include <typedReferenceCount.h>
#include <luse.h>
#include <pointerTo.h>
#include <pt_NamedNode.h>
#include <nodePath.h>
///////////////////////////////////////////////////////////////////
// Class : CollisionEntry
// Description : Defines a single collision event. One of these is
// created for each collision detected by a
// CollisionTraverser, to be dealt with by the
// CollisionHandler.
//
// A CollisionEntry provides slots for a number of data
// values (such as intersection point and normal) that
// might or might not be known for each collision. It
// is up to the handler to determine what information is
// known and to do the right thing with it.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionEntry : public TypedReferenceCount {
public:
INLINE CollisionEntry();
CollisionEntry(const CollisionEntry &copy);
void operator = (const CollisionEntry &copy);
PUBLISHED:
INLINE const CollisionSolid *get_from() const;
INLINE bool has_into() const;
INLINE const CollisionSolid *get_into() const;
INLINE CollisionNode *get_from_node() const;
INLINE NamedNode *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 void set_into_intersection_point(const LPoint3f &point);
INLINE bool has_into_intersection_point() const;
INLINE const LPoint3f &get_into_intersection_point() const;
INLINE bool has_from_intersection_point() const;
INLINE LPoint3f get_from_intersection_point() const;
INLINE void set_into_surface_normal(const LVector3f &normal);
INLINE bool has_into_surface_normal() const;
INLINE const LVector3f &get_into_surface_normal() const;
INLINE void set_into_depth(float depth);
INLINE bool has_into_depth() const;
INLINE float get_into_depth() const;
private:
CPT(CollisionSolid) _from;
CPT(CollisionSolid) _into;
PT(CollisionNode) _from_node;
PT_NamedNode _into_node;
NodePath _into_node_path;
LMatrix4f _from_space;
LMatrix4f _into_space;
LMatrix4f _wrt_space;
LMatrix4f _inv_wrt_space;
enum Flags {
F_has_into_intersection_point = 0x0001,
F_has_into_surface_normal = 0x0002,
F_has_into_depth = 0x0004,
};
int _flags;
LPoint3f _into_intersection_point;
LVector3f _into_surface_normal;
float _into_depth;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "CollisionEntry",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
friend class CollisionTraverser;
friend class qpCollisionTraverser;
};
#include "collisionEntry.I"
#endif

View File

@ -1,62 +0,0 @@
// Filename: collisionHandler.cxx
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionHandler.h"
TypeHandle CollisionHandler::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CollisionHandler::begin_group
// Access: Public, Virtual
// Description: Will be called by the CollisionTraverser before a new
// traversal is begun. It instructs the handler to
// reset itself in preparation for a number of
// CollisionEntries to be sent.
////////////////////////////////////////////////////////////////////
void CollisionHandler::
begin_group() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandler::add_entry
// Access: Public, Virtual
// Description: Called between a begin_group() .. end_group()
// sequence for each collision that is detected.
////////////////////////////////////////////////////////////////////
void CollisionHandler::
add_entry(CollisionEntry *) {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandler::end_group
// Access: Public, Virtual
// Description: Called by the CollisionTraverser at the completion of
// all collision detections for this traversal. It
// should do whatever finalization is required for the
// handler.
//
// The return value is normally true, but if this
// returns value, the CollisionTraverser will remove the
// handler from its list, allowing the CollisionHandler
// itself to determine when it is no longer needed.
////////////////////////////////////////////////////////////////////
bool CollisionHandler::
end_group() {
return true;
}

View File

@ -1,68 +0,0 @@
// Filename: collisionHandler.h
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONHANDLER_H
#define COLLISIONHANDLER_H
#include <pandabase.h>
#include <typedReferenceCount.h>
class CollisionEntry;
///////////////////////////////////////////////////////////////////
// Class : CollisionHandler
// Description : The abstract interface to a number of classes that
// decide what to do what a collision is detected. One
// of these must be assigned to the CollisionTraverser
// that is processing collisions in order to specify how
// to dispatch detected collisions.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionHandler : public TypedReferenceCount {
public:
virtual void begin_group();
virtual void add_entry(CollisionEntry *entry);
virtual bool end_group();
PUBLISHED:
static TypeHandle get_class_type() {
return _type_handle;
}
public:
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "CollisionHandler",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
friend class CollisionTraverser;
};
#endif

View File

@ -1,161 +0,0 @@
// Filename: collisionHandlerEvent.I
// Created by: drose (27Jun00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::SortEntries::operator ()
// Access: Public
// Description: Orders the CollisionEntries in the set so that there
// is one entry for each node/node intersection
// detected.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionHandlerEvent::SortEntries::
operator () (const PT(CollisionEntry) &a,
const PT(CollisionEntry) &b) const {
if (a->get_from_node() != b->get_from_node()) {
return a->get_from_node() < b->get_from_node();
}
if (a->get_into_node() != b->get_into_node()) {
return a->get_into_node() < b->get_into_node();
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::SortEntries::operator =
// Access: Public
// Description: The assignment operator does absolutely nothing,
// since this is just a function object class that
// stores no data. We define it just to quiet up g++ in
// -Wall mode.
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerEvent::SortEntries::
operator = (const CollisionHandlerEvent::SortEntries &) {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::set_in_pattern
// Access: Public
// Description: Sets the pattern string that indicates how the event
// names are generated for each collision detected.
// This is a string that may contain any of the
// following:
//
// %fn - the name of the "from" object's node
// %in - the name of the "into" object's node
// %ft - 't' if "from" is tangible, 'i' if intangible
// %it - 't' if "into" is tangible, 'i' if intangible
//
// The event name will be based on the in_pattern
// string specified here, with all occurrences of the
// above strings replaced with the corresponding values.
//
// In general, the in_pattern event is thrown on the
// first detection of a collision between two particular
// nodes. In subsequent passes, as long as a collision
// between those two nodes continues to be detected each
// frame, the again_pattern is thrown. The first frame
// in which the collision is no longer detected, the
// out_pattern event is thrown.
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerEvent::
set_in_pattern(const string &in_pattern) {
_in_pattern = in_pattern;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::get_in_pattern
// Access: Public
// Description: Returns the pattern string that indicates how the
// event names are generated for each collision
// detected. See set_in_pattern().
////////////////////////////////////////////////////////////////////
INLINE string CollisionHandlerEvent::
get_in_pattern() const {
return _in_pattern;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::set_again_pattern
// Access: Public
// Description: Sets the pattern string that indicates how the event
// names are generated when a collision between two
// particular nodes is *still* detected. This event is
// thrown each consecutive time a collision between two
// particular nodes is detected, starting with the
// second time.
//
// In general, the in_pattern event is thrown on the
// first detection of a collision between two particular
// nodes. In subsequent passes, as long as a collision
// between those two nodes continues to be detected each
// frame, the again_pattern is thrown. The first frame
// in which the collision is no longer detected, the
// out_pattern event is thrown.
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerEvent::
set_again_pattern(const string &again_pattern) {
_again_pattern = again_pattern;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::get_again_pattern
// Access: Public
// Description: Returns the pattern string that indicates how the
// event names are generated when a collision between
// two particular nodes is *still* detected. See
// set_again_pattern() and set_in_pattern().
////////////////////////////////////////////////////////////////////
INLINE string CollisionHandlerEvent::
get_again_pattern() const {
return _again_pattern;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::set_out_pattern
// Access: Public
// Description: Sets the pattern string that indicates how the event
// names are generated when a collision between two
// particular nodes is *no longer* detected.
//
// In general, the in_pattern event is thrown on the
// first detection of a collision between two particular
// nodes. In subsequent passes, as long as a collision
// between those two nodes continues to be detected each
// frame, the again_pattern is thrown. The first frame
// in which the collision is no longer detected, the
// out_pattern event is thrown.
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerEvent::
set_out_pattern(const string &out_pattern) {
_out_pattern = out_pattern;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::get_out_pattern
// Access: Public
// Description: Returns the pattern string that indicates how the
// event names are generated when a collision between
// two particular nodes is *no longer* detected. See
// set_out_pattern() and set_in_pattern().
////////////////////////////////////////////////////////////////////
INLINE string CollisionHandlerEvent::
get_out_pattern() const {
return _out_pattern;
}

View File

@ -1,213 +0,0 @@
// Filename: collisionHandlerEvent.cxx
// Created by: drose (27Jun00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionHandlerEvent.h"
#include "config_collide.h"
#include <eventParameter.h>
#include <throw_event.h>
TypeHandle CollisionHandlerEvent::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::Constructor
// Access: Public
// Description: The default CollisionHandlerEvent will throw no
// events. Its pattern strings must first be set via a
// call to set_in_pattern() and/or set_out_pattern().
////////////////////////////////////////////////////////////////////
CollisionHandlerEvent::
CollisionHandlerEvent() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::begin_group
// Access: Public, Virtual
// Description: Will be called by the CollisionTraverser before a new
// traversal is begun. It instructs the handler to
// reset itself in preparation for a number of
// CollisionEntries to be sent.
////////////////////////////////////////////////////////////////////
void CollisionHandlerEvent::
begin_group() {
if (collide_cat.is_spam()) {
collide_cat.spam()
<< "begin_group.\n";
}
_last_colliding.swap(_current_colliding);
_current_colliding.clear();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::add_entry
// Access: Public, Virtual
// Description: Called between a begin_group() .. end_group()
// sequence for each collision that is detected.
////////////////////////////////////////////////////////////////////
void CollisionHandlerEvent::
add_entry(CollisionEntry *entry) {
nassertv(entry != (CollisionEntry *)NULL);
// Record this particular entry for later. This will keep track of
// all the unique pairs of node/node intersections.
bool inserted = _current_colliding.insert(entry).second;
if (collide_cat.is_spam()) {
collide_cat.spam()
<< "Detected collision from " << (void *)entry->get_from_node()
<< " to " << (void *)entry->get_into_node()
<< ", inserted = " << inserted << "\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::end_group
// Access: Public, Virtual
// Description: Called by the CollisionTraverser at the completion of
// all collision detections for this traversal. It
// should do whatever finalization is required for the
// handler.
////////////////////////////////////////////////////////////////////
bool CollisionHandlerEvent::
end_group() {
// Now compare the list of entries we collected this frame with
// those we kept from the last time. Each new entry represents a
// new 'in' event; each missing entry represents a new 'out' event.
if (collide_cat.is_spam()) {
collide_cat.spam()
<< "end_group.\n"
<< "current_colliding has " << _current_colliding.size()
<< " entries, last_colliding has " << _last_colliding.size()
<< "\n";
}
Colliding::iterator ca, cb;
ca = _current_colliding.begin();
cb = _last_colliding.begin();
SortEntries order;
while (ca != _current_colliding.end() && cb != _last_colliding.end()) {
if (order(*ca, *cb)) {
// Here's an element in a but not in b. That's a newly entered
// intersection.
throw_event_pattern(_in_pattern, *ca);
++ca;
} else if (order(*cb, *ca)) {
// Here's an element in b but not in a. That's a newly exited
// intersection.
throw_event_pattern(_out_pattern, *cb);
++cb;
} else {
// This element is in both b and a. It hasn't changed.
throw_event_pattern(_again_pattern, *cb);
++ca;
++cb;
}
}
while (ca != _current_colliding.end()) {
// Here's an element in a but not in b. That's a newly entered
// intersection.
throw_event_pattern(_in_pattern, *ca);
++ca;
}
while (cb != _last_colliding.end()) {
// Here's an element in b but not in a. That's a newly exited
// intersection.
throw_event_pattern(_out_pattern, *cb);
++cb;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::clear
// Access: Public
// Description: Empties the list of elements that all colliders are
// known to be colliding with. No "out" events will be
// thrown; if the same collision is detected next frame,
// a new "in" event will be thrown for each collision.
//
// This can be called each frame to defeat the
// persistent "in" event mechanism, which prevents the
// same "in" event from being thrown repeatedly.
// However, also see set_again_pattern(), which can be
// used to set the event that is thrown when a collision
// is detected for two or more consecutive frames.
////////////////////////////////////////////////////////////////////
void CollisionHandlerEvent::
clear() {
_last_colliding.clear();
_current_colliding.clear();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerEvent::throw_event_pattern
// Access: Private
// Description: Throws an event matching the indicated pattern.
////////////////////////////////////////////////////////////////////
void CollisionHandlerEvent::
throw_event_pattern(const string &pattern, CollisionEntry *entry) {
if (pattern.empty()) {
return;
}
string event;
for (size_t p = 0; p < pattern.size(); ++p) {
if (pattern[p] == '%') {
string cmd = pattern.substr(p + 1, 2);
p += 2;
if (cmd == "fn") {
event += entry->get_from_node()->get_name();
} else if (cmd == "in") {
event += entry->get_into_node()->get_name();
} else if (cmd == "ft") {
event +=
(!entry->get_from()->is_tangible() ? 'i' : 't');
} else if (cmd == "it") {
event +=
(entry->has_into() && !entry->get_into()->is_tangible() ? 'i' : 't');
} else if (cmd == "ig") {
event +=
(entry->has_into() ? 'c' : 'g');
} else {
collide_cat.error()
<< "Invalid symbol in event_pattern: %" << cmd << "\n";
}
} else {
event += pattern[p];
}
}
if (!event.empty()) {
throw_event(event, EventParameter(entry));
}
}

View File

@ -1,102 +0,0 @@
// Filename: collisionHandlerEvent.h
// Created by: drose (27Jun00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONHANDLEREVENT_H
#define COLLISIONHANDLEREVENT_H
#include <pandabase.h>
#include "collisionHandler.h"
#include "collisionNode.h"
#include "collisionEntry.h"
#include <pointerTo.h>
///////////////////////////////////////////////////////////////////
// Class : CollisionHandlerEvent
// Description : A specialized kind of CollisionHandler that throws an
// event for each collision detected. The event thrown
// may be based on the name of the moving object or the
// struck object, or both. The first parameter of the
// event will be a pointer to the CollisionEntry that
// triggered it.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionHandlerEvent : public CollisionHandler {
PUBLISHED:
CollisionHandlerEvent();
public:
virtual void begin_group();
virtual void add_entry(CollisionEntry *entry);
virtual bool end_group();
PUBLISHED:
INLINE void set_in_pattern(const string &pattern);
INLINE string get_in_pattern() const;
INLINE void set_again_pattern(const string &pattern);
INLINE string get_again_pattern() const;
INLINE void set_out_pattern(const string &pattern);
INLINE string get_out_pattern() const;
void clear();
private:
void throw_event_pattern(const string &pattern, CollisionEntry *entry);
string _in_pattern;
string _again_pattern;
string _out_pattern;
int _index;
class SortEntries {
public:
INLINE bool
operator () (const PT(CollisionEntry) &a,
const PT(CollisionEntry) &b) const;
INLINE void operator = (const SortEntries &other);
};
typedef pset<PT(CollisionEntry), SortEntries> Colliding;
Colliding _current_colliding;
Colliding _last_colliding;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
CollisionHandler::init_type();
register_type(_type_handle, "CollisionHandlerEvent",
CollisionHandler::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "collisionHandlerEvent.I"
#endif

View File

@ -1,67 +0,0 @@
// Filename: collisionHandlerFloor.I
// Created by: drose (04Jul00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerFloor::set_offset
// Access: Public
// Description: Sets the linear offset to add to (or subtract from)
// the highest detected collision point to determine the
// actual height at which to set the collider.
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerFloor::
set_offset(float offset) {
_offset = offset;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerFloor::get_offset
// Access: Public
// Description: Returns the linear offset to add to (or subtract from)
// the highest detected collision point to determine the
// actual height at which to set the collider.
////////////////////////////////////////////////////////////////////
INLINE float CollisionHandlerFloor::
get_offset() const {
return _offset;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerFloor::set_max_velocity
// Access: Public
// Description: Sets the maximum speed at which the object will be
// allowed to descend towards a floor below it, in units
// per second. Set this to zero to allow it to
// instantly teleport any distance.
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerFloor::
set_max_velocity(float max_velocity) {
_max_velocity = max_velocity;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerFloor::get_max_velocity
// Access: Public
// Description: Retrieves the maximum speed at which the object will
// be allowed to descend towards a floor below it, in
// units per second. See set_max_velocity().
////////////////////////////////////////////////////////////////////
INLINE float CollisionHandlerFloor::
get_max_velocity() const {
return _max_velocity;
}

View File

@ -1,145 +0,0 @@
// Filename: collisionHandlerFloor.cxx
// Created by: drose (04Jul00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionHandlerFloor.h"
#include "config_collide.h"
#include <renderRelation.h>
#include <transformTransition.h>
#include <clockObject.h>
TypeHandle CollisionHandlerFloor::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerFloor::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CollisionHandlerFloor::
CollisionHandlerFloor() {
_offset = 0.0f;
_max_velocity = 0.0f;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerFloor::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
CollisionHandlerFloor::
~CollisionHandlerFloor() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerFloor::handle_entries
// Access: Protected, Virtual
// Description: Called by the parent class after all collisions have
// been detected, this manages the various collisions
// and moves around the nodes as necessary.
//
// The return value is normally true, but it may be
// false to indicate the CollisionTraverser should
// disable this handler from being called in the future.
////////////////////////////////////////////////////////////////////
bool CollisionHandlerFloor::
handle_entries() {
bool okflag = true;
FromEntries::const_iterator fi;
for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) {
CollisionNode *from_node = (*fi).first;
nassertr(from_node != (CollisionNode *)NULL, false);
const Entries &entries = (*fi).second;
Colliders::iterator ci;
ci = _colliders.find(from_node);
if (ci == _colliders.end()) {
// Hmm, someone added a CollisionNode to a traverser and gave
// it this CollisionHandler pointer--but they didn't tell us
// about the node.
collide_cat.error()
<< get_type() << " doesn't know about "
<< *from_node << ", disabling.\n";
okflag = false;
} else {
ColliderDef &def = (*ci).second;
if (!def.is_valid()) {
collide_cat.error()
<< "Removing invalid collider " << *from_node << " from "
<< get_type() << "\n";
_colliders.erase(ci);
} else {
// Get the maximum height for all collisions with this node.
bool got_max = false;
float max_height = 0.0f;
Entries::const_iterator ei;
for (ei = entries.begin(); ei != entries.end(); ++ei) {
CollisionEntry *entry = (*ei);
nassertr(entry != (CollisionEntry *)NULL, false);
nassertr(from_node == entry->get_from_node(), false);
if (entry->has_from_intersection_point()) {
LPoint3f point = entry->get_from_intersection_point();
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Intersection point detected at " << point << "\n";
}
float height = point[2];
if (!got_max || height > max_height) {
got_max = true;
max_height = height;
}
}
}
// Now set our height accordingly.
float adjust = max_height + _offset;
if (!IS_THRESHOLD_ZERO(adjust, 0.001)) {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Adjusting height by " << adjust << "\n";
}
if (adjust < 0.0f && _max_velocity != 0.0f) {
float max_adjust =
_max_velocity * ClockObject::get_global_clock()->get_dt();
adjust = max(adjust, -max_adjust);
}
LMatrix4f mat;
def.get_mat(mat);
mat(3, 2) += adjust;
def.set_mat(mat);
} else {
if (collide_cat.is_spam()) {
collide_cat.spam()
<< "Leaving height unchanged.\n";
}
}
}
}
}
return okflag;
}

View File

@ -1,78 +0,0 @@
// Filename: collisionHandlerFloor.h
// Created by: drose (04Jul00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONHANDLERFLOOR_H
#define COLLISIONHANDLERFLOOR_H
#include <pandabase.h>
#include "collisionHandlerPhysical.h"
#include "collisionNode.h"
///////////////////////////////////////////////////////////////////
// Class : CollisionHandlerFloor
// Description : A specialized kind of CollisionHandler that sets the
// Z height of the collider to a fixed linear offset
// from the highest detected collision point each frame.
// It's intended to implement walking around on a floor
// of varying height by casting a ray down from the
// avatar's head.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionHandlerFloor : public CollisionHandlerPhysical {
PUBLISHED:
CollisionHandlerFloor();
virtual ~CollisionHandlerFloor();
INLINE void set_offset(float offset);
INLINE float get_offset() const;
INLINE void set_max_velocity(float max_vel);
INLINE float get_max_velocity() const;
protected:
virtual bool handle_entries();
private:
float _offset;
float _max_velocity;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
CollisionHandlerPhysical::init_type();
register_type(_type_handle, "CollisionHandlerFloor",
CollisionHandlerPhysical::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "collisionHandlerFloor.I"
#endif

View File

@ -1,51 +0,0 @@
// Filename: collisionHandlerPhysical.I
// Created by: drose (03Jul00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::ColliderDef::set_drive_interface
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerPhysical::ColliderDef::
set_drive_interface(DriveInterface *drive_interface) {
_drive_interface = drive_interface;
_arc.clear();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::ColliderDef::set_arc
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerPhysical::ColliderDef::
set_arc(NodeRelation *arc) {
_arc = arc;
_drive_interface.clear();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::ColliderDef::is_valid
// Access: Public
// Description: Returns true if this ColliderDef is still valid;
// e.g. it refers to a valid arc or drive interface.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionHandlerPhysical::ColliderDef::
is_valid() const {
return (_arc != (NodeRelation *)NULL) ||
(_drive_interface != (DriveInterface *)NULL);
}

View File

@ -1,210 +0,0 @@
// Filename: collisionHandlerPhysical.cxx
// Created by: drose (03Jul00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionHandlerPhysical.h"
#include "config_collide.h"
#include <renderRelation.h>
#include <transformTransition.h>
TypeHandle CollisionHandlerPhysical::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::ColliderDef::get_mat
// Access: Public
// Description: Fills mat with the matrix representing the current
// position and orientation of this collider.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::ColliderDef::
get_mat(LMatrix4f &mat) const {
if (_arc != (NodeRelation *)NULL) {
TransformTransition *tt;
if (get_transition_into(tt, _arc)) {
mat = tt->get_matrix();
} else {
mat = LMatrix4f::ident_mat();
}
} else if (_drive_interface != (DriveInterface *)NULL) {
mat = _drive_interface->get_mat();
} else {
collide_cat.error()
<< "Invalid CollisionHandlerPhysical::ColliderDef\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::ColliderDef::set_mat
// Access: Public
// Description: Moves this collider to the position and orientation
// indicated by the given transform.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::ColliderDef::
set_mat(const LMatrix4f &mat) {
if (_arc != (NodeRelation *)NULL) {
if (!_arc->is_attached()) {
collide_cat.error()
<< "CollisionHandler is associated with an unattached arc.\n";
_arc = (NodeRelation *)NULL;
} else {
_arc->set_transition(new TransformTransition(mat));
}
} else if (_drive_interface != (DriveInterface *)NULL) {
_drive_interface->set_mat(mat);
_drive_interface->force_dgraph();
} else {
collide_cat.error()
<< "Invalid CollisionHandlerPhysical::ColliderDef\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CollisionHandlerPhysical::
CollisionHandlerPhysical() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
CollisionHandlerPhysical::
~CollisionHandlerPhysical() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::begin_group
// Access: Public, Virtual
// Description: Will be called by the CollisionTraverser before a new
// traversal is begun. It instructs the handler to
// reset itself in preparation for a number of
// CollisionEntries to be sent.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::
begin_group() {
CollisionHandlerEvent::begin_group();
_from_entries.clear();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::add_entry
// Access: Public, Virtual
// Description: Called between a begin_group() .. end_group()
// sequence for each collision that is detected.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::
add_entry(CollisionEntry *entry) {
nassertv(entry != (CollisionEntry *)NULL);
CollisionHandlerEvent::add_entry(entry);
if (entry->get_from()->is_tangible() &&
(!entry->has_into() || entry->get_into()->is_tangible())) {
_from_entries[entry->get_from_node()].push_back(entry);
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::end_group
// Access: Public, Virtual
// Description: Called by the CollisionTraverser at the completion of
// all collision detections for this traversal. It
// should do whatever finalization is required for the
// handler.
////////////////////////////////////////////////////////////////////
bool CollisionHandlerPhysical::
end_group() {
CollisionHandlerEvent::end_group();
return handle_entries();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::add_collider
// Access: Public
// Description: Adds a new collider to the list with a DriveInterface
// pointer that needs to be told about the collider's
// new position, or updates the existing collider with a
// new DriveInterface pointer.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::
add_collider(CollisionNode *node, DriveInterface *drive_interface) {
_colliders[node].set_drive_interface(drive_interface);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::add_collider
// Access: Public
// Description: Adds a new collider to the list with a NodeRelation
// pointer that will be updated with the collider's
// new position, or updates the existing collider with a
// new NodeRelation pointer.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::
add_collider(CollisionNode *node, NodeRelation *arc) {
_colliders[node].set_arc(arc);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::remove_collider
// Access: Public
// Description: Removes the collider from the list of colliders that
// this handler knows about.
////////////////////////////////////////////////////////////////////
bool CollisionHandlerPhysical::
remove_collider(CollisionNode *node) {
Colliders::iterator ci = _colliders.find(node);
if (ci == _colliders.end()) {
return false;
}
_colliders.erase(ci);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::has_collider
// Access: Public
// Description: Returns true if the handler knows about the indicated
// collider, false otherwise.
////////////////////////////////////////////////////////////////////
bool CollisionHandlerPhysical::
has_collider(CollisionNode *node) const {
Colliders::const_iterator ci = _colliders.find(node);
return (ci != _colliders.end());
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::clear_colliders
// Access: Public
// Description: Completely empties the list of colliders this handler
// knows about.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::
clear_colliders() {
_colliders.clear();
}

View File

@ -1,102 +0,0 @@
// Filename: collisionHandlerPhysical.h
// Created by: drose (03Jul00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONHANDLERPHYSICAL_H
#define COLLISIONHANDLERPHYSICAL_H
#include <pandabase.h>
#include "collisionHandlerEvent.h"
#include "collisionNode.h"
#include <driveInterface.h>
#include <pointerTo.h>
#include <pt_NodeRelation.h>
///////////////////////////////////////////////////////////////////
// Class : CollisionHandlerPhysical
// Description : The abstract base class for a number of
// CollisionHandlers that have some physical effect on
// their moving bodies: they need to update the nodes'
// positions based on the effects of the collision.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionHandlerPhysical : public CollisionHandlerEvent {
public:
CollisionHandlerPhysical();
virtual ~CollisionHandlerPhysical();
virtual void begin_group();
virtual void add_entry(CollisionEntry *entry);
virtual bool end_group();
PUBLISHED:
void add_collider(CollisionNode *node, DriveInterface *drive_interface);
void add_collider(CollisionNode *node, NodeRelation *arc);
bool remove_collider(CollisionNode *node);
bool has_collider(CollisionNode *node) const;
void clear_colliders();
protected:
virtual bool handle_entries()=0;
protected:
typedef pvector< PT(CollisionEntry) > Entries;
typedef pmap<PT(CollisionNode), Entries> FromEntries;
FromEntries _from_entries;
class ColliderDef {
public:
INLINE void set_drive_interface(DriveInterface *drive_interface);
INLINE void set_arc(NodeRelation *arc);
INLINE bool is_valid() const;
void get_mat(LMatrix4f &mat) const;
void set_mat(const LMatrix4f &mat);
PT(DriveInterface) _drive_interface;
PT_NodeRelation _arc;
};
typedef pmap<PT(CollisionNode), ColliderDef> Colliders;
Colliders _colliders;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
CollisionHandlerEvent::init_type();
register_type(_type_handle, "CollisionHandlerPhysical",
CollisionHandlerEvent::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "collisionHandlerPhysical.I"
#endif

View File

@ -1,37 +0,0 @@
// Filename: collisionHandlerPusher.I
// Created by: drose (26Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPusher::set_horizontal
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerPusher::
set_horizontal(bool flag) {
_horizontal = flag;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPusher::get_horizontal
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool CollisionHandlerPusher::
get_horizontal() const {
return _horizontal;
}

View File

@ -1,207 +0,0 @@
// Filename: collisionHandlerPusher.cxx
// Created by: drose (25Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionHandlerPusher.h"
#include "config_collide.h"
TypeHandle CollisionHandlerPusher::_type_handle;
///////////////////////////////////////////////////////////////////
// Class : ShoveData
// Description : The ShoveData class is used within
// CollisionHandlerPusher::handle_entries(), to track
// multiple shoves onto a given collider. It's not
// exported outside this file.
////////////////////////////////////////////////////////////////////
class ShoveData {
public:
LVector3f _shove;
float _length;
LVector3f _normalized_shove;
bool _valid;
};
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPusher::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CollisionHandlerPusher::
CollisionHandlerPusher() {
_horizontal = true;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPusher::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
CollisionHandlerPusher::
~CollisionHandlerPusher() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPusher::handle_entries
// Access: Protected, Virtual
// Description: Called by the parent class after all collisions have
// been detected, this manages the various collisions
// and moves around the nodes as necessary.
//
// The return value is normally true, but it may be
// false to indicate the CollisionTraverser should
// disable this handler from being called in the future.
////////////////////////////////////////////////////////////////////
bool CollisionHandlerPusher::
handle_entries() {
bool okflag = true;
FromEntries::const_iterator fi;
for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) {
CollisionNode *from_node = (*fi).first;
nassertr(from_node != (CollisionNode *)NULL, false);
const Entries &entries = (*fi).second;
Colliders::iterator ci;
ci = _colliders.find(from_node);
if (ci == _colliders.end()) {
// Hmm, someone added a CollisionNode to a traverser and gave
// it this CollisionHandler pointer--but they didn't tell us
// about the node.
collide_cat.error()
<< "CollisionHandlerPusher doesn't know about "
<< *from_node << ", disabling.\n";
okflag = false;
} else {
ColliderDef &def = (*ci).second;
if (!def.is_valid()) {
collide_cat.error()
<< "Removing invalid collider " << *from_node << " from "
<< get_type() << "\n";
_colliders.erase(ci);
} else {
// How to apply multiple shoves from different solids onto the
// same collider? One's first intuition is to vector sum all
// the shoves. However, this causes problems when two parallel
// walls shove on the collider, because we end up with a double
// shove. We hack around this by testing if two shove vectors
// share nearly the same direction, and if so, we keep only the
// longer of the two.
typedef pvector<ShoveData> Shoves;
Shoves shoves;
Entries::const_iterator ei;
for (ei = entries.begin(); ei != entries.end(); ++ei) {
CollisionEntry *entry = (*ei);
nassertr(entry != (CollisionEntry *)NULL, false);
nassertr(from_node == entry->get_from_node(), false);
if (!entry->has_into_surface_normal() ||
!entry->has_into_depth()) {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Cannot shove on " << *from_node << " for collision into "
<< *entry->get_into_node() << "; no normal/depth information.\n";
}
} else {
// Shove it just enough to clear the volume.
if (entry->get_into_depth() != 0.0f) {
ShoveData sd;
sd._shove =
entry->get_into_surface_normal() *
entry->get_into_depth();
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Shove on " << *from_node << " from "
<< *entry->get_into_node() << ": " << sd._shove << "\n";
}
sd._length = sd._shove.length();
sd._normalized_shove = sd._shove / sd._length;
sd._valid = true;
shoves.push_back(sd);
}
}
}
if (!shoves.empty()) {
// Now we combine any two shoves that shove in largely the
// same direction. Hacky.
Shoves::iterator si;
for (si = shoves.begin(); si != shoves.end(); ++si) {
ShoveData &sd = (*si);
Shoves::iterator sj;
for (sj = shoves.begin(); sj != si; ++sj) {
ShoveData &sd2 = (*sj);
if (sd2._valid) {
float d = sd._normalized_shove.dot(sd2._normalized_shove);
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Considering dot product " << d << "\n";
}
if (d > 0.9) {
// These two shoves are largely in the same direction;
// save the larger of the two.
if (sd2._length < sd._length) {
sd2._valid = false;
} else {
sd._valid = false;
}
}
}
}
}
// Now we can determine the net shove.
LVector3f net_shove(0.0f, 0.0f, 0.0f);
for (si = shoves.begin(); si != shoves.end(); ++si) {
const ShoveData &sd = (*si);
if (sd._valid) {
net_shove += sd._shove;
}
}
if (_horizontal) {
net_shove[2] = 0.0f;
}
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Net shove on " << *from_node << " is: "
<< net_shove << "\n";
}
LMatrix4f mat;
def.get_mat(mat);
def.set_mat(LMatrix4f::translate_mat(net_shove) * mat);
}
}
}
}
return okflag;
}

View File

@ -1,72 +0,0 @@
// Filename: collisionHandlerPusher.h
// Created by: drose (25Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONHANDLERPUSHER_H
#define COLLISIONHANDLERPUSHER_H
#include <pandabase.h>
#include "collisionHandlerPhysical.h"
#include "collisionNode.h"
///////////////////////////////////////////////////////////////////
// Class : CollisionHandlerPusher
// Description : A specialized kind of CollisionHandler that simply
// pushes back on things that attempt to move into solid
// walls. This is the simplest kind of "real-world"
// collisions you can have.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionHandlerPusher : public CollisionHandlerPhysical {
PUBLISHED:
CollisionHandlerPusher();
virtual ~CollisionHandlerPusher();
INLINE void set_horizontal(bool flag);
INLINE bool get_horizontal() const;
protected:
virtual bool handle_entries();
private:
bool _horizontal;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
CollisionHandlerPhysical::init_type();
register_type(_type_handle, "CollisionHandlerPusher",
CollisionHandlerPhysical::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "collisionHandlerPusher.I"
#endif

View File

@ -1,145 +0,0 @@
// Filename: collisionHandlerQueue.cxx
// Created by: drose (27Jun00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionHandlerQueue.h"
#include "config_collide.h"
TypeHandle CollisionHandlerQueue::_type_handle;
// This class is used in sort_entries(), below.
class CollisionEntrySorter {
public:
CollisionEntrySorter(CollisionEntry *entry) {
_entry = entry;
LVector3f vec =
entry->get_from_intersection_point() -
entry->get_from()->get_collision_origin();
_dist2 = vec.length_squared();
}
bool operator < (const CollisionEntrySorter &other) const {
return _dist2 < other._dist2;
}
CollisionEntry *_entry;
float _dist2;
};
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerQueue::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CollisionHandlerQueue::
CollisionHandlerQueue() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerQueue::begin_group
// Access: Public, Virtual
// Description: Will be called by the CollisionTraverser before a new
// traversal is begun. It instructs the handler to
// reset itself in preparation for a number of
// CollisionEntries to be sent.
////////////////////////////////////////////////////////////////////
void CollisionHandlerQueue::
begin_group() {
_entries.clear();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerQueue::add_entry
// Access: Public, Virtual
// Description: Called between a begin_group() .. end_group()
// sequence for each collision that is detected.
////////////////////////////////////////////////////////////////////
void CollisionHandlerQueue::
add_entry(CollisionEntry *entry) {
nassertv(entry != (CollisionEntry *)NULL);
_entries.push_back(entry);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerQueue::sort_entries
// Access: Public
// Description: Sorts all the detected collisions front-to-back by
// from_intersection_point() so that those intersection
// points closest to the collider's origin (e.g., the
// center of the CollisionSphere, or the point_a of a
// CollisionSegment) appear first.
////////////////////////////////////////////////////////////////////
void CollisionHandlerQueue::
sort_entries() {
// Build up a temporary vector of entries so we can sort the
// pointers. This uses the class defined above.
typedef pvector<CollisionEntrySorter> Sorter;
Sorter sorter;
sorter.reserve(_entries.size());
Entries::const_iterator ei;
for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
sorter.push_back(CollisionEntrySorter(*ei));
}
sort(sorter.begin(), sorter.end());
nassertv(sorter.size() == _entries.size());
// Now that they're sorted, get them back. We do this in two steps,
// building up a temporary vector first, so we don't accidentally
// delete all the entries when the pointers go away.
Entries sorted_entries;
sorted_entries.reserve(sorter.size());
Sorter::const_iterator si;
for (si = sorter.begin(); si != sorter.end(); ++si) {
sorted_entries.push_back((*si)._entry);
}
_entries.swap(sorted_entries);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerQueue::clear_entries
// Access: Public
// Description: Removes all the entries from the queue.
////////////////////////////////////////////////////////////////////
void CollisionHandlerQueue::
clear_entries() {
_entries.clear();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerQueue::get_num_entries
// Access: Public
// Description: Returns the number of CollisionEntries detected last
// pass.
////////////////////////////////////////////////////////////////////
int CollisionHandlerQueue::
get_num_entries() const {
return _entries.size();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerQueue::get_entry
// Access: Public
// Description: Returns the nth CollisionEntry detected last pass.
////////////////////////////////////////////////////////////////////
CollisionEntry *CollisionHandlerQueue::
get_entry(int n) const {
nassertr(n >= 0 && n < (int)_entries.size(), NULL);
return _entries[n];
}

View File

@ -1,76 +0,0 @@
// Filename: collisionHandlerQueue.h
// Created by: drose (27Jun00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONHANDLERQUEUE_H
#define COLLISIONHANDLERQUEUE_H
#include <pandabase.h>
#include "collisionHandler.h"
#include "collisionEntry.h"
///////////////////////////////////////////////////////////////////
// Class : CollisionHandlerQueue
// Description : A special kind of CollisionHandler that does nothing
// except remember the CollisionEntries detected the
// last pass. This set of CollisionEntries may then be
// queried by the calling function. It's primarily
// useful when a simple intersection test is being made,
// e.g. for picking from the window.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionHandlerQueue : public CollisionHandler {
PUBLISHED:
CollisionHandlerQueue();
public:
virtual void begin_group();
virtual void add_entry(CollisionEntry *entry);
PUBLISHED:
void sort_entries();
void clear_entries();
int get_num_entries() const;
CollisionEntry *get_entry(int n) const;
private:
typedef pvector< PT(CollisionEntry) > Entries;
Entries _entries;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
CollisionHandler::init_type();
register_type(_type_handle, "CollisionHandlerQueue",
CollisionHandler::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -1,244 +0,0 @@
// Filename: collisionLevelState.I
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CollisionLevelState::
CollisionLevelState(const ArcChain &arc_chain) :
_arc_chain(arc_chain)
{
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CollisionLevelState::
CollisionLevelState(const CollisionLevelState &copy) :
_arc_chain(copy._arc_chain),
_colliders(copy._colliders),
_current(copy._current),
_colliders_with_geom(copy._colliders_with_geom),
_local_bounds(copy._local_bounds)
{
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::Copy Assignment
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionLevelState::
operator = (const CollisionLevelState &copy) {
_arc_chain = copy._arc_chain;
_colliders = copy._colliders;
_current = copy._current;
_colliders_with_geom = copy._colliders_with_geom;
_local_bounds = copy._local_bounds;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::forward_arc
// Access: Public
// Description: Records that we have traversed past another arc in
// the scene graph.
////////////////////////////////////////////////////////////////////
INLINE void CollisionLevelState::
forward_arc(NodeRelation *arc) {
_arc_chain.push_back(arc);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_arc_chain
// Access: Public
// Description: Returns the chain of arcs traversed from the top of
// the scene graph.
////////////////////////////////////////////////////////////////////
INLINE const ArcChain &CollisionLevelState::
get_arc_chain() const {
return _arc_chain;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_num_colliders
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int CollisionLevelState::
get_num_colliders() const {
return _colliders.size();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::has_collider
// Access: Public
// Description: Returns true if the nth collider in the LevelState is
// still part of the level.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionLevelState::
has_collider(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), false);
return (_current & get_mask(n)) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::has_collider_with_geom
// Access: Public
// Description: Returns true if the nth collider in the LevelState is
// still part of the level, and it has the
// "collide_geom" flag set.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionLevelState::
has_collider_with_geom(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), false);
return (_current & _colliders_with_geom & get_mask(n)) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::has_any_collider
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool CollisionLevelState::
has_any_collider() const {
return _current != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::has_any_collide_geom
// Access: Public
// Description: Returns true if any Collider in the level state has
// the "collide_geom" flag set, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionLevelState::
has_any_collide_geom() const {
return (_current & _colliders_with_geom) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::reached_collision_node
// Access: Public
// Description: Called by the traverser when we reach a CollisionNode
// in the traversal. At this point, we zero out our set
// of colliders with the "collide_geom" flag set,
// because no colliders will test against geometry
// parented beneath a CollisionNode.
////////////////////////////////////////////////////////////////////
INLINE void CollisionLevelState::
reached_collision_node() {
_colliders_with_geom = 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_collider
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CollisionSolid *CollisionLevelState::
get_collider(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), NULL);
nassertr(has_collider(n), NULL);
return _colliders[n]._collider;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_node
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CollisionNode *CollisionLevelState::
get_node(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), NULL);
nassertr(has_collider(n), NULL);
return _colliders[n]._node;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_space
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const LMatrix4f &CollisionLevelState::
get_space(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), LMatrix4f::ident_mat());
nassertr(has_collider(n), LMatrix4f::ident_mat());
return _colliders[n]._space;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_inv_space
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const LMatrix4f &CollisionLevelState::
get_inv_space(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), LMatrix4f::ident_mat());
nassertr(has_collider(n), LMatrix4f::ident_mat());
return _colliders[n]._inv_space;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_local_bound
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeometricBoundingVolume *CollisionLevelState::
get_local_bound(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), NULL);
nassertr(has_collider(n), NULL);
nassertr(n >= 0 && n < (int)_local_bounds.size(), NULL);
// For whatever reason, the Intel compiler can't figure this line
// out.
//return _local_bounds[n];
// But it can figure out this equivalent line.
return *(_local_bounds + n);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::omit_collider
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionLevelState::
omit_collider(int n) {
nassertv(n >= 0 && n < (int)_colliders.size());
nassertv(has_collider(n));
_current &= ~get_mask(n);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_mask
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE CollisionLevelState::ColliderMask CollisionLevelState::
get_mask(int n) const {
return ((ColliderMask)1) << n;
}

View File

@ -1,103 +0,0 @@
// Filename: collisionLevelState.cxx
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionSolid.h"
#include "collisionNode.h"
#include "collisionLevelState.h"
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::clear
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionLevelState::
clear() {
_colliders.clear();
_local_bounds.clear();
_current = 0;
_colliders_with_geom = 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::reserve
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionLevelState::
reserve(int max_colliders) {
_colliders.reserve(max_colliders);
_local_bounds.reserve(max_colliders);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::prepare_collider
// Access: Public
// Description: Adds the indicated Collider to the set of Colliders
// in the current level state.
////////////////////////////////////////////////////////////////////
void CollisionLevelState::
prepare_collider(const ColliderDef &def) {
int index = (int)_colliders.size();
_colliders.push_back(def);
CollisionSolid *collider = def._collider;
const BoundingVolume &bv = collider->get_bound();
if (!bv.is_of_type(GeometricBoundingVolume::get_class_type())) {
_local_bounds.push_back((GeometricBoundingVolume *)NULL);
} else {
GeometricBoundingVolume *gbv;
DCAST_INTO_V(gbv, bv.make_copy());
gbv->xform(def._space);
_local_bounds.push_back(gbv);
}
_current |= get_mask(index);
if (def._node->get_collide_geom()) {
_colliders_with_geom |= get_mask(index);
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::xform
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionLevelState::
xform(const LMatrix4f &mat) {
BoundingVolumes new_bounds;
int num_colliders = get_num_colliders();
new_bounds.reserve(num_colliders);
for (int c = 0; c < num_colliders; c++) {
if (!has_collider(c) ||
get_local_bound(c) == (GeometricBoundingVolume *)NULL) {
new_bounds.push_back((GeometricBoundingVolume *)NULL);
} else {
const GeometricBoundingVolume *old_bound = get_local_bound(c);
GeometricBoundingVolume *new_bound =
DCAST(GeometricBoundingVolume, old_bound->make_copy());
new_bound->xform(mat);
new_bounds.push_back(new_bound);
}
}
_local_bounds = new_bounds;
}

View File

@ -1,98 +0,0 @@
// Filename: collisionLevelState.h
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONLEVELSTATE_H
#define COLLISIONLEVELSTATE_H
#include <pandabase.h>
#include <luse.h>
#include <pointerToArray.h>
#include <geometricBoundingVolume.h>
#include <arcChain.h>
#include "plist.h"
class CollisionSolid;
class CollisionNode;
////////////////////////////////////////////////////////////////////
// Class : CollisionLevelState
// Description : This is the state information the
// CollisionTraverser retains for each level during
// traversal.
////////////////////////////////////////////////////////////////////
class CollisionLevelState {
public:
class ColliderDef {
public:
CollisionSolid *_collider;
CollisionNode *_node;
LMatrix4f _space;
LMatrix4f _inv_space;
};
INLINE CollisionLevelState(const ArcChain &arc_chain);
INLINE CollisionLevelState(const CollisionLevelState &copy);
INLINE void operator = (const CollisionLevelState &copy);
void clear();
void reserve(int max_colliders);
void prepare_collider(const ColliderDef &def);
void xform(const LMatrix4f &mat);
INLINE void forward_arc(NodeRelation *arc);
INLINE const ArcChain &get_arc_chain() const;
INLINE int get_num_colliders() const;
INLINE bool has_collider(int n) const;
INLINE bool has_collider_with_geom(int n) const;
INLINE bool has_any_collider() const;
INLINE bool has_any_collide_geom() const;
INLINE void reached_collision_node();
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 GeometricBoundingVolume *get_local_bound(int n) const;
INLINE void omit_collider(int n);
private:
typedef int ColliderMask;
INLINE ColliderMask get_mask(int n) const;
ArcChain _arc_chain;
typedef PTA(ColliderDef) Colliders;
Colliders _colliders;
ColliderMask _current;
ColliderMask _colliders_with_geom;
typedef PTA(CPT(GeometricBoundingVolume)) BoundingVolumes;
BoundingVolumes _local_bounds;
};
#include "collisionLevelState.I"
#endif

View File

@ -1,166 +0,0 @@
// Filename: collisionNode.I
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionSolid.h"
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::set_collide_mask
// Access: Public
// Description: Simultaneously sets both the "from" and "into"
// CollideMask values to the same thing.
////////////////////////////////////////////////////////////////////
INLINE void CollisionNode::
set_collide_mask(CollideMask mask) {
_from_collide_mask = mask;
_into_collide_mask = mask;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::set_from_collide_mask
// Access: Public
// Description: Sets the "from" CollideMask. In order for a
// collision to be detected from this object into
// another object, the intersection of this object's
// "from" mask and the other object's "into" mask must
// be nonzero.
////////////////////////////////////////////////////////////////////
INLINE void CollisionNode::
set_from_collide_mask(CollideMask mask) {
_from_collide_mask = mask;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::set_into_collide_mask
// Access: Public
// Description: Sets the "into" CollideMask. In order for a
// collision to be detected from another object into
// this object, the intersection of the other object's
// "from" mask and this object's "into" mask must be
// nonzero.
////////////////////////////////////////////////////////////////////
INLINE void CollisionNode::
set_into_collide_mask(CollideMask mask) {
_into_collide_mask = mask;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::get_from_collide_mask
// Access: Public
// Description: Returns the current "from" CollideMask. In order for
// a collision to be detected from this object into
// another object, the intersection of this object's
// "from" mask and the other object's "into" mask must
// be nonzero.
////////////////////////////////////////////////////////////////////
INLINE CollideMask CollisionNode::
get_from_collide_mask() const {
return _from_collide_mask;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::get_into_collide_mask
// Access: Public
// Description: Returns the current "into" CollideMask. In order for
// a collision to be detected from another object into
// this object, the intersection of the other object's
// "from" mask and this object's "into" mask must be
// nonzero.
////////////////////////////////////////////////////////////////////
INLINE CollideMask CollisionNode::
get_into_collide_mask() const {
return _into_collide_mask;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::set_collide_geom
// Access: Public
// Description: Sets the state of the "collide geom" flag for this
// CollisionNode. Normally, this is false; when this is
// set true, the CollisionSolids in this node will test
// for collisions with actual renderable geometry, in
// addition to whatever CollisionSolids may be indicated
// by the from_collide_mask.
//
// Setting this to true causes this to test *all*
// GeomNodes for collisions. It is an all-or-none
// thing; there is no way to collide with only some
// GeomNodes, as GeomNodes have no into_collide_mask.
////////////////////////////////////////////////////////////////////
INLINE void CollisionNode::
set_collide_geom(bool flag) {
_collide_geom = flag;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::get_collide_geom
// Access: Public
// Description: Returns the current state of the collide_geom flag.
// See set_collide_geom().
////////////////////////////////////////////////////////////////////
INLINE bool CollisionNode::
get_collide_geom() const {
return _collide_geom;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::get_num_solids
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int CollisionNode::
get_num_solids() const {
return _solids.size();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::get_solid
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CollisionSolid *CollisionNode::
get_solid(int n) const {
nassertr(n >= 0 && n < get_num_solids(), NULL);
return _solids[n];
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::remove_solid
// Access: Public
// Description: Removes the solid with the indicated index. This
// will shift all subsequent indices down by one.
////////////////////////////////////////////////////////////////////
INLINE void CollisionNode::
remove_solid(int n) {
nassertv(n >= 0 && n < get_num_solids());
_solids.erase(_solids.begin() + n);
mark_bound_stale();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::add_solid
// Access: Public
// Description: Adds the indicated solid to the node. Returns the
// index of the new solid within the node's list of
// solids.
////////////////////////////////////////////////////////////////////
INLINE int CollisionNode::
add_solid(CollisionSolid *solid) {
_solids.push_back(solid);
mark_bound_stale();
return _solids.size() - 1;
}

View File

@ -1,347 +0,0 @@
// Filename: collisionNode.cxx
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionNode.h"
#include "config_collide.h"
#include <datagram.h>
#include <datagramIterator.h>
#include <bamReader.h>
#include <bamWriter.h>
TypeHandle CollisionNode::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CollisionNode::
CollisionNode(const string &name) :
NamedNode(name),
_from_collide_mask(CollideMask::all_on()),
_into_collide_mask(CollideMask::all_on()),
_collide_geom(false)
{
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CollisionNode::
CollisionNode(const CollisionNode &copy) :
NamedNode(copy),
_from_collide_mask(copy._from_collide_mask),
_into_collide_mask(copy._into_collide_mask),
_collide_geom(copy._collide_geom),
_solids(copy._solids)
{
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionNode::
operator = (const CollisionNode &copy) {
NamedNode::operator = (copy);
_from_collide_mask = copy._from_collide_mask;
_into_collide_mask = copy._into_collide_mask;
_collide_geom = copy._collide_geom;
_solids = copy._solids;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
CollisionNode::
~CollisionNode() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::make_copy
// Access: Public, Virtual
// Description: Returns a newly-allocated Node that is a shallow copy
// of this one. It will be a different Node pointer,
// but its internal data may or may not be shared with
// that of the original Node.
////////////////////////////////////////////////////////////////////
Node *CollisionNode::
make_copy() const {
return new CollisionNode(*this);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::xform
// Access: Public, Virtual
// Description: Transforms the contents of this node by the indicated
// matrix, if it means anything to do so. For most
// kinds of nodes, this does nothing.
////////////////////////////////////////////////////////////////////
void CollisionNode::
xform(const LMatrix4f &mat) {
nassertv(!mat.is_nan());
if (mat.almost_equal(LMatrix4f::ident_mat())) {
return;
}
Solids::iterator si;
for (si = _solids.begin(); si != _solids.end(); ++si) {
CollisionSolid *solid = (*si);
// We may have to copy each of our solids as we transform them if
// someone else is sharing their pointers.
if (solid->get_ref_count() > 1) {
solid = solid->make_copy();
(*si) = solid;
}
solid->xform(mat);
}
mark_bound_stale();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::combine_with
// Access: Public, Virtual
// Description: Collapses this node with the other node, if possible,
// and returns a pointer to the combined node, or NULL
// if the two nodes cannot safely be combined.
//
// The return value may be this, other, or a new node
// altogether.
//
// This function is called from GraphReducer::flatten(),
// and need not deal with children; its job is just to
// decide whether to collapse the two nodes and what the
// collapsed node should look like.
////////////////////////////////////////////////////////////////////
Node *CollisionNode::
combine_with(Node *other) {
if (is_exact_type(get_class_type()) &&
other->is_exact_type(get_class_type())) {
// Two CollisionNodes can combine, but only if they have the same
// name.
CollisionNode *cother = DCAST(CollisionNode, other);
if (get_name() == cother->get_name()) {
const PT(CollisionSolid) *solids_begin = &cother->_solids[0];
const PT(CollisionSolid) *solids_end = solids_begin + cother->_solids.size();
_solids.insert(_solids.end(), solids_begin, solids_end);
mark_bound_stale();
return this;
}
// Two CollisionNodes with different names can't combine.
return (Node *)NULL;
}
return NamedNode::combine_with(other);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::preserve_name
// Access: Public, Virtual
// Description: Returns true if the node's name has extrinsic meaning
// and must be preserved across a flatten operation,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool CollisionNode::
preserve_name() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::draw_traverse
// Access: Public, Virtual
// Description: This is called by the Draw traversal by virtue of the
// node's being present in the scene graph. Its job is
// to make sure the visualization of the collideable
// geometry is up-to-date.
////////////////////////////////////////////////////////////////////
void CollisionNode::
draw_traverse(const ArcChain &) {
Solids::iterator si;
for (si = _solids.begin(); si != _solids.end(); ++si) {
(*si)->update_viz(this);
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::output
// Access: Public, Virtual
// Description: Writes a brief description of the node to the
// indicated output stream. This is invoked by the <<
// operator. It may be overridden in derived classes to
// include some information relevant to the class.
////////////////////////////////////////////////////////////////////
void CollisionNode::
output(ostream &out) const {
NamedNode::output(out);
out << " (" << _solids.size() << " solids)";
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::recompute_bound
// Access: Protected, Virtual
// Description: Recomputes the dynamic bounding volume for this node.
////////////////////////////////////////////////////////////////////
BoundingVolume *CollisionNode::
recompute_bound() {
// First, get ourselves a fresh, empty bounding volume.
BoundingVolume *bound = BoundedObject::recompute_bound();
nassertr(bound != (BoundingVolume *)NULL, bound);
// Now actually compute the bounding volume by putting it around all
// of our solids' bounding volumes.
pvector<const BoundingVolume *> child_volumes;
Solids::const_iterator gi;
for (gi = _solids.begin(); gi != _solids.end(); ++gi) {
child_volumes.push_back(&(*gi)->get_bound());
}
const BoundingVolume **child_begin = &child_volumes[0];
const BoundingVolume **child_end = child_begin + child_volumes.size();
bool success =
bound->around(child_begin, child_end);
#ifdef NOTIFY_DEBUG
if (!success) {
collide_cat.error()
<< "Unable to generate bounding volume for " << *this << ":\n"
<< "Cannot put " << bound->get_type() << " around:\n";
for (int i = 0; i < (int)child_volumes.size(); i++) {
collide_cat.error(false)
<< " " << *child_volumes[i] << "\n";
}
}
#endif
return bound;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::write_datagram
// Access: Public
// Description: Function to write the important information in
// the particular object to a Datagram
////////////////////////////////////////////////////////////////////
void CollisionNode::
write_datagram(BamWriter *manager, Datagram &me)
{
int i;
NamedNode::write_datagram(manager, me);
me.add_uint16(_solids.size());
for(i = 0; i < (int)_solids.size(); i++)
{
manager->write_pointer(me, _solids[i]);
}
me.add_uint32(_from_collide_mask.get_word());
me.add_uint32(_into_collide_mask.get_word());
me.add_bool(_collide_geom);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::fillin
// Access: Protected
// Description: Function that reads out of the datagram (or asks
// manager to read) all of the data that is needed to
// re-create this object and stores it in the appropiate
// place
////////////////////////////////////////////////////////////////////
void CollisionNode::
fillin(DatagramIterator& scan, BamReader* manager)
{
int i;
NamedNode::fillin(scan, manager);
int num_solids = scan.get_uint16();
_solids.clear();
_solids.reserve(num_solids);
for(i = 0; i < num_solids; i++) {
manager->read_pointer(scan);
_solids.push_back((CollisionSolid *)NULL);
}
_from_collide_mask.set_word(scan.get_uint32());
_into_collide_mask.set_word(scan.get_uint32());
_collide_geom = scan.get_bool();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::complete_pointers
// Access: Public
// Description: Takes in a vector of pointes to TypedWritable
// objects that correspond to all the requests for
// pointers that this object made to BamReader.
////////////////////////////////////////////////////////////////////
int CollisionNode::
complete_pointers(TypedWritable **p_list, BamReader* manager) {
int num_solids = _solids.size();
int start = NamedNode::complete_pointers(p_list, manager);
for (int i = 0; i < num_solids; i++) {
_solids[i] = DCAST(CollisionSolid, p_list[start + i]);
}
return start + num_solids;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::make_CollisionNode
// Access: Protected
// Description: Factory method to generate a CollisionNode object
////////////////////////////////////////////////////////////////////
TypedWritable* CollisionNode::
make_CollisionNode(const FactoryParams &params)
{
CollisionNode *me = new CollisionNode;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::register_with_factory
// Access: Public, Static
// Description: Factory method to generate a CollisionNode object
////////////////////////////////////////////////////////////////////
void CollisionNode::
register_with_read_factory(void)
{
BamReader::get_factory()->register_factory(get_class_type(), make_CollisionNode);
}

View File

@ -1,111 +0,0 @@
// Filename: collisionNode.h
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONNODE_H
#define COLLISIONNODE_H
#include <pandabase.h>
#include "collisionSolid.h"
#include <collideMask.h>
#include <namedNode.h>
////////////////////////////////////////////////////////////////////
// Class : CollisionNode
// Description : A node in the scene graph that can hold any number of
// CollisionSolids. This may either represent a bit of
// static geometry in the scene that things will collide
// with, or an animated object twirling around in the
// world and running into things.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionNode : public NamedNode {
PUBLISHED:
CollisionNode(const string &name = "");
public:
CollisionNode(const CollisionNode &copy);
void operator = (const CollisionNode &copy);
virtual ~CollisionNode();
virtual Node *make_copy() const;
virtual void xform(const LMatrix4f &mat);
virtual Node *combine_with(Node *other);
virtual bool preserve_name() const;
PUBLISHED:
INLINE void set_collide_mask(CollideMask mask);
INLINE void set_from_collide_mask(CollideMask mask);
INLINE void set_into_collide_mask(CollideMask mask);
INLINE CollideMask get_from_collide_mask() const;
INLINE CollideMask get_into_collide_mask() const;
INLINE void set_collide_geom(bool flag);
INLINE bool get_collide_geom() const;
INLINE int get_num_solids() const;
INLINE CollisionSolid *get_solid(int n) const;
INLINE void remove_solid(int n);
INLINE int add_solid(CollisionSolid *solid);
public:
virtual void draw_traverse(const ArcChain &chain);
virtual void output(ostream &out) const;
protected:
virtual BoundingVolume *recompute_bound();
private:
CollideMask _from_collide_mask;
CollideMask _into_collide_mask;
bool _collide_geom;
typedef pvector< PT(CollisionSolid) > Solids;
Solids _solids;
public:
static void register_with_read_factory(void);
virtual void write_datagram(BamWriter* manager, Datagram &me);
virtual int complete_pointers(TypedWritable **plist,
BamReader *manager);
static TypedWritable *make_CollisionNode(const FactoryParams &params);
protected:
void fillin(DatagramIterator& scan, BamReader* manager);
public:
static TypeHandle get_class_type(void) {
return _type_handle;
}
static void init_type(void) {
NamedNode::init_type();
register_type(_type_handle, "CollisionNode",
NamedNode::get_class_type());
}
virtual TypeHandle get_type(void) const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "collisionNode.I"
#endif

View File

@ -18,9 +18,7 @@
#include "collisionPlane.h"
#include "collisionHandler.h"
#include "qpcollisionHandler.h"
#include "collisionEntry.h"
#include "qpcollisionEntry.h"
#include "collisionSphere.h"
#include "collisionRay.h"
@ -36,8 +34,6 @@
#include "omniBoundingVolume.h"
#include "geomQuad.h"
#include "geomNode.h"
TypeHandle CollisionPlane::_type_handle;
////////////////////////////////////////////////////////////////////
@ -50,20 +46,6 @@ make_copy() {
return new CollisionPlane(*this);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPlane::test_intersection
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionPlane::
test_intersection(CollisionHandler *, const CollisionEntry &,
const CollisionSolid *) const {
// Planes cannot currently be intersected from, only into. Do not
// add a CollisionPlane to a CollisionTraverser.
nassertr(false, 0);
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPlane::test_intersection
// Access: Public, Virtual
@ -86,7 +68,7 @@ test_intersection(qpCollisionHandler *, const qpCollisionEntry &,
void CollisionPlane::
xform(const LMatrix4f &mat) {
_plane = _plane * mat;
clear_viz_arcs();
mark_viz_stale();
mark_bound_stale();
}
@ -130,84 +112,6 @@ recompute_bound() {
return set_bound_ptr(new OmniBoundingVolume);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPlane::test_intersection_from_sphere
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionPlane::
test_intersection_from_sphere(CollisionHandler *record,
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();
LVector3f from_radius_v =
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_space();
float from_radius = length(from_radius_v);
float dist = dist_to_plane(from_center);
if (dist > from_radius) {
// No intersection.
return 0;
}
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "intersection detected from " << *entry.get_from_node() << " into "
<< entry.get_into_node_path() << "\n";
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
LVector3f into_normal = get_normal() * entry.get_inv_wrt_space();
float into_depth = from_radius - dist;
new_entry->set_into_surface_normal(into_normal);
new_entry->set_into_depth(into_depth);
record->add_entry(new_entry);
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPlane::test_intersection_from_ray
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionPlane::
test_intersection_from_ray(CollisionHandler *record,
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();
float t;
if (!_plane.intersects_line(t, from_origin, from_direction)) {
// No intersection.
return 0;
}
if (t < 0.0f) {
// The intersection point is before the start of the ray.
return 0;
}
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "intersection detected from " << *entry.get_from_node() << " into "
<< entry.get_into_node_path() << "\n";
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
LPoint3f into_intersection_point = from_origin + t * from_direction;
new_entry->set_into_intersection_point(into_intersection_point);
record->add_entry(new_entry);
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPlane::test_intersection_from_sphere
// Access: Public, Virtual
@ -286,78 +190,6 @@ test_intersection_from_ray(qpCollisionHandler *record,
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPlane::recompute_viz
// Access: Public, Virtual
// Description: Rebuilds the geometry that will be used to render a
// visible representation of the collision solid.
////////////////////////////////////////////////////////////////////
void CollisionPlane::
recompute_viz(Node *parent) {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << " on " << *parent << "\n";
}
// Since we can't represent an infinite plane, we'll have to be
// satisfied with drawing a big polygon. Choose four points on the
// plane to be the corners of the polygon.
// We must choose four points fairly reasonably spread apart on
// the plane. We'll start with a center point and one corner
// point, and then use cross products to find the remaining three
// corners of a square.
// The center point will be on the axis with the largest
// coefficent. The first corner will be diagonal in the other two
// dimensions.
LPoint3f cp;
LVector3f p1, p2, p3, p4;
LVector3f normal = get_normal();
float D = _plane._d;
if (fabs(normal[0]) > fabs(normal[1]) &&
fabs(normal[0]) > fabs(normal[2])) {
// X has the largest coefficient.
cp.set(-D / normal[0], 0.0f, 0.0f);
p1 = LPoint3f(-(normal[1] + normal[2] + D)/normal[0], 1.0f, 1.0f) - cp;
} else if (fabs(normal[1]) > fabs(normal[2])) {
// Y has the largest coefficient.
cp.set(0.0f, -D / normal[1], 0.0f);
p1 = LPoint3f(1.0f, -(normal[0] + normal[2] + D)/normal[1], 1.0f) - cp;
} else {
// Z has the largest coefficient.
cp.set(0.0f, 0.0f, -D / normal[2]);
p1 = LPoint3f(1.0f, 1.0f, -(normal[0] + normal[1] + D)/normal[2]) - cp;
}
p1.normalize();
p2 = cross(normal, p1);
p3 = cross(normal, p2);
p4 = cross(normal, p3);
static const double plane_scale = 10.0;
PTA_Vertexf verts;
verts.push_back(cp + p1 * plane_scale);
verts.push_back(cp + p2 * plane_scale);
verts.push_back(cp + p3 * plane_scale);
verts.push_back(cp + p4 * plane_scale);
GeomQuad *quad = new GeomQuad;
quad->set_coords(verts);
quad->set_num_prims(1);
GeomNode *viz = new GeomNode("viz-plane");
viz->add_geom(quad);
add_solid_viz(parent, viz);
add_wireframe_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPlane::fill_viz_geom
// Access: Protected, Virtual

View File

@ -19,12 +19,12 @@
#ifndef COLLISIONPLANE_H
#define COLLISIONPLANE_H
#include <pandabase.h>
#include "pandabase.h"
#include "collisionSolid.h"
#include <luse.h>
#include <plane.h>
#include "luse.h"
#include "plane.h"
///////////////////////////////////////////////////////////////////
// Class : CollisionPlane
@ -41,11 +41,6 @@ PUBLISHED:
public:
virtual CollisionSolid *make_copy();
virtual int
test_intersection(CollisionHandler *record,
const CollisionEntry &entry,
const CollisionSolid *into) const;
virtual int
test_intersection(qpCollisionHandler *record,
const qpCollisionEntry &entry,
@ -68,19 +63,12 @@ protected:
protected:
virtual int
test_intersection_from_sphere(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_ray(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_sphere(qpCollisionHandler *record,
const qpCollisionEntry &entry) const;
virtual int
test_intersection_from_ray(qpCollisionHandler *record,
const qpCollisionEntry &entry) const;
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
private:

View File

@ -18,9 +18,7 @@
#include "collisionPolygon.h"
#include "collisionHandler.h"
#include "qpcollisionHandler.h"
#include "collisionEntry.h"
#include "qpcollisionEntry.h"
#include "collisionSphere.h"
#include "collisionRay.h"
@ -37,8 +35,6 @@
#include "bamWriter.h"
#include "geomPolygon.h"
#include "geomNode.h"
#include <algorithm>
TypeHandle CollisionPolygon::_type_handle;
@ -124,20 +120,6 @@ verify_points(const LPoint3f *begin, const LPoint3f *end) {
return all_ok;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::test_intersection
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionPolygon::
test_intersection(CollisionHandler *, const CollisionEntry &,
const CollisionSolid *into) const {
// Polygons cannot currently be intersected from, only into. Do not
// add a CollisionPolygon to a CollisionTraverser.
nassertr(false, 0);
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::test_intersection
// Access: Public, Virtual
@ -188,7 +170,7 @@ xform(const LMatrix4f &mat) {
setup_points(verts_begin, verts_end);
}
clear_viz_arcs();
mark_viz_stale();
mark_bound_stale();
}
@ -243,212 +225,6 @@ recompute_bound() {
return bound;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::test_intersection_from_sphere
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionPolygon::
test_intersection_from_sphere(CollisionHandler *record,
const CollisionEntry &entry) const {
if (_points.size() < 3) {
return 0;
}
const CollisionSphere *sphere;
DCAST_INTO_R(sphere, entry.get_from(), 0);
LPoint3f from_center = sphere->get_center() * entry.get_wrt_space();
LVector3f from_radius_v =
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_space();
float from_radius = length(from_radius_v);
float dist = dist_to_plane(from_center);
if (dist > from_radius || dist < -from_radius) {
// No intersection.
return 0;
}
// Ok, we intersected the plane, but did we intersect the polygon?
// The nearest point within the plane to our center is the
// intersection of the line (center, center+normal) with the plane.
LPoint3f plane_point;
bool really_intersects =
get_plane().intersects_line(plane_point,
from_center, from_center + get_normal());
nassertr(really_intersects, 0);
LPoint2f p = to_2d(plane_point);
// Now we have found a point on the polygon's plane that corresponds
// to the point tangent to our collision sphere where it first
// touches the plane. We want to decide whether the sphere itself
// will intersect the polygon. We can approximate this by testing
// whether a circle of the given radius centered around this tangent
// point, in the plane of the polygon, would intersect.
// But even this approximate test is too difficult. To approximate
// the approximation, we'll test two points: (1) the center itself.
// If this is inside the polygon, then certainly the circle
// intersects the polygon, and the sphere collides. (2) a point on
// the outside of the circle, nearest to the center of the polygon.
// If _this_ point is inside the polygon, then again the circle, and
// hence the sphere, intersects. If neither point is inside the
// polygon, chances are reasonably good the sphere doesn't intersect
// the polygon after all.
if (is_inside(p)) {
// The circle's center is inside the polygon; we have a collision!
} else {
if (from_radius > 0.0f) {
// Now find the point on the rim of the circle nearest the
// polygon's center.
// First, get a vector from the center of the circle to the center
// of the polygon.
LVector2f rim = _median - p;
float rim_length = length(rim);
if (rim_length <= from_radius) {
// Here's a surprise: the center of the polygon is within the
// circle! Since the center is guaranteed to be interior to the
// polygon (the polygon is convex), it follows that the circle
// intersects the polygon.
} else {
// Now scale this vector to length radius, and get the new point.
rim = (rim * from_radius / rim_length) + p;
// Is the new point within the polygon?
if (is_inside(rim)) {
// It sure is! The circle intersects!
} else {
// No intersection.
return 0;
}
}
}
}
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "intersection detected from " << *entry.get_from_node() << " into "
<< entry.get_into_node_path() << "\n";
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
LVector3f into_normal = get_normal() * entry.get_inv_wrt_space();
float into_depth = from_radius - dist;
new_entry->set_into_surface_normal(into_normal);
new_entry->set_into_depth(into_depth);
record->add_entry(new_entry);
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::test_intersection_from_ray
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionPolygon::
test_intersection_from_ray(CollisionHandler *record,
const CollisionEntry &entry) const {
if (_points.size() < 3) {
return 0;
}
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();
float t;
if (!get_plane().intersects_line(t, from_origin, from_direction)) {
// No intersection.
return 0;
}
if (t < 0.0f) {
// The intersection point is before the start of the ray.
return 0;
}
LPoint3f plane_point = from_origin + t * from_direction;
if (!is_inside(to_2d(plane_point))) {
// Outside the polygon's perimeter.
return 0;
}
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "intersection detected from " << *entry.get_from_node() << " into "
<< entry.get_into_node_path() << "\n";
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
new_entry->set_into_intersection_point(plane_point);
record->add_entry(new_entry);
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::test_intersection_from_segment
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionPolygon::
test_intersection_from_segment(CollisionHandler *record,
const CollisionEntry &entry) const {
if (_points.size() < 3) {
return 0;
}
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_direction = from_b - from_a;
float t;
if (!get_plane().intersects_line(t, from_a, from_direction)) {
// No intersection.
return 0;
}
if (t < 0.0f || t > 1.0f) {
// The intersection point is before the start of the segment or
// after the end of the segment.
return 0;
}
LPoint3f plane_point = from_a + t * from_direction;
if (!is_inside(to_2d(plane_point))) {
// Outside the polygon's perimeter.
return 0;
}
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "intersection detected from " << *entry.get_from_node() << " into "
<< entry.get_into_node_path() << "\n";
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
new_entry->set_into_intersection_point(plane_point);
record->add_entry(new_entry);
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::test_intersection_from_sphere
// Access: Public, Virtual
@ -655,50 +431,6 @@ test_intersection_from_segment(qpCollisionHandler *record,
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::recompute_viz
// Access: Public, Virtual
// Description: Rebuilds the geometry that will be used to render a
// visible representation of the collision solid.
////////////////////////////////////////////////////////////////////
void CollisionPolygon::
recompute_viz(Node *parent) {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << " on " << *parent << "\n";
}
if (_points.size() < 3) {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "(Degenerate poly, ignoring.)\n";
}
return;
}
PTA_Vertexf verts;
Points::const_iterator pi;
for (pi = _points.begin(); pi != _points.end(); ++pi) {
verts.push_back(to_3d(*pi));
}
if (_reversed) {
reverse(verts.begin(), verts.end());
}
PTA_int lengths;
lengths.push_back(_points.size());
GeomPolygon *polygon = new GeomPolygon;
polygon->set_coords(verts);
polygon->set_num_prims(1);
polygon->set_lengths(lengths);
GeomNode *viz = new GeomNode("viz-polygon");
viz->add_geom(polygon);
add_solid_viz(parent, viz);
add_wireframe_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionPolygon::fill_viz_geom
// Access: Protected, Virtual

View File

@ -49,11 +49,6 @@ public:
static bool verify_points(const LPoint3f *begin, const LPoint3f *end);
virtual int
test_intersection(CollisionHandler *record,
const CollisionEntry &entry,
const CollisionSolid *into) const;
virtual int
test_intersection(qpCollisionHandler *record,
const qpCollisionEntry &entry,
@ -69,16 +64,6 @@ protected:
virtual BoundingVolume *recompute_bound();
protected:
virtual int
test_intersection_from_sphere(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_ray(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_segment(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_sphere(qpCollisionHandler *record,
const qpCollisionEntry &entry) const;
@ -89,7 +74,6 @@ protected:
test_intersection_from_segment(qpCollisionHandler *record,
const qpCollisionEntry &entry) const;
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
private:

View File

@ -134,20 +134,6 @@ get_direction() const {
return _direction;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::set_from_lens
// Access: Public
// Description: Accepts a LensNode and a 2-d point in the range
// [-1,1]. Sets the CollisionRay so that it begins at
// the LensNode's near plane and extends to
// infinity, making it suitable for picking objects from
// the screen given a camera and a mouse location.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionRay::
set_from_lens(LensNode *camera, float px, float py) {
return set_from_lens(camera, LPoint2f(px, py));
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::set_from_lens
// Access: Public

View File

@ -17,9 +17,7 @@
////////////////////////////////////////////////////////////////////
#include "collisionRay.h"
#include "collisionHandler.h"
#include "qpcollisionHandler.h"
#include "collisionEntry.h"
#include "qpcollisionEntry.h"
#include "config_collide.h"
#include "geom.h"
@ -33,9 +31,6 @@
#include "bamReader.h"
#include "bamWriter.h"
#include "lensNode.h"
#include "geomNode.h"
TypeHandle CollisionRay::_type_handle;
@ -49,17 +44,6 @@ make_copy() {
return new CollisionRay(*this);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::test_intersection
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionRay::
test_intersection(CollisionHandler *record, const CollisionEntry &entry,
const CollisionSolid *into) const {
return into->test_intersection_from_ray(record, entry);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::test_intersection
// Access: Public, Virtual
@ -80,7 +64,7 @@ void CollisionRay::
xform(const LMatrix4f &mat) {
_origin = _origin * mat;
_direction = _direction * mat;
clear_viz_arcs();
mark_viz_stale();
mark_bound_stale();
}
@ -107,39 +91,6 @@ output(ostream &out) const {
out << "ray, o (" << _origin << "), d (" << _direction << ")";
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::set_from_lens
// Access: Public
// Description: Accepts a LensNode and a 2-d point in the range
// [-1,1]. Sets the CollisionRay so that it begins at
// the LensNode's near plane and extends to
// infinity, making it suitable for picking objects from
// the screen given a camera and a mouse location.
//
// Returns true if the point was acceptable, false
// otherwise.
////////////////////////////////////////////////////////////////////
bool CollisionRay::
set_from_lens(LensNode *camera, const LPoint2f &point) {
Lens *lens = camera->get_lens();
bool success = true;
LPoint3f near_point, far_point;
if (!lens->extrude(point, near_point, far_point)) {
_origin = LPoint3f::origin();
_direction = LVector3f::forward();
success = false;
} else {
_origin = near_point;
_direction = far_point - near_point;
}
mark_bound_stale();
mark_viz_stale();
return success;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::set_from_lens
// Access: Public
@ -186,46 +137,6 @@ recompute_bound() {
return set_bound_ptr(new BoundingLine(_origin, _origin + _direction));
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::recompute_viz
// Access: Public, Virtual
// Description: Rebuilds the geometry that will be used to render a
// visible representation of the collision solid.
////////////////////////////////////////////////////////////////////
void CollisionRay::
recompute_viz(Node *parent) {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << " on " << *parent << "\n";
}
GeomLinestrip *ray = new GeomLinestrip;
PTA_Vertexf verts;
PTA_Colorf colors;
PTA_int lengths;
#define NUM_POINTS 100
verts.reserve(NUM_POINTS);
colors.reserve(NUM_POINTS);
for (int i = 0; i < NUM_POINTS; i++) {
verts.push_back(_origin + (double)i * _direction);
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f)+
((double)i / 100.0) * Colorf(0.0f, 0.0f, 0.0f, -1.0f));
}
ray->set_coords(verts);
ray->set_colors(colors, G_PER_VERTEX);
lengths.push_back(NUM_POINTS-1);
ray->set_lengths(lengths);
ray->set_num_prims(1);
GeomNode *viz = new GeomNode("viz-ray");
viz->add_geom(ray);
add_other_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::fill_viz_geom
// Access: Protected, Virtual

View File

@ -23,7 +23,6 @@
#include "collisionSolid.h"
class LensNode;
class qpLensNode;
///////////////////////////////////////////////////////////////////
@ -45,11 +44,6 @@ public:
INLINE CollisionRay(const CollisionRay &copy);
virtual CollisionSolid *make_copy();
virtual int
test_intersection(CollisionHandler *record,
const CollisionEntry &entry,
const CollisionSolid *into) const;
virtual int
test_intersection(qpCollisionHandler *record,
const qpCollisionEntry &entry,
@ -69,9 +63,6 @@ PUBLISHED:
INLINE void set_direction(float x, float y, float z);
INLINE const LVector3f &get_direction() const;
bool set_from_lens(LensNode *camera, const LPoint2f &point);
INLINE bool set_from_lens(LensNode *camera, float px, float py);
bool set_from_lens(qpLensNode *camera, const LPoint2f &point);
INLINE bool set_from_lens(qpLensNode *camera, float px, float py);
@ -79,7 +70,6 @@ protected:
virtual BoundingVolume *recompute_bound();
protected:
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
private:

View File

@ -137,20 +137,6 @@ get_point_b() const {
return _b;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::set_from_lens
// Access: Public
// Description: Accepts a LensNode and a 2-d point in the range
// [-1,1]. Sets the CollisionSegment so that it begins at
// the LensNode's near plane and extends to the
// far plane, making it suitable for picking objects
// from the screen given a camera and a mouse location.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionSegment::
set_from_lens(LensNode *camera, float px, float py) {
return set_from_lens(camera, LPoint2f(px, py));
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::set_from_lens
// Access: Public

View File

@ -18,9 +18,7 @@
#include "collisionSegment.h"
#include "collisionHandler.h"
#include "qpcollisionHandler.h"
#include "collisionEntry.h"
#include "qpcollisionEntry.h"
#include "config_collide.h"
@ -35,9 +33,6 @@
#include "bamReader.h"
#include "bamWriter.h"
#include "geomNode.h"
#include "lensNode.h"
TypeHandle CollisionSegment::_type_handle;
@ -51,17 +46,6 @@ make_copy() {
return new CollisionSegment(*this);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::test_intersection
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionSegment::
test_intersection(CollisionHandler *record, const CollisionEntry &entry,
const CollisionSolid *into) const {
return into->test_intersection_from_segment(record, entry);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::test_intersection
// Access: Public, Virtual
@ -82,7 +66,7 @@ void CollisionSegment::
xform(const LMatrix4f &mat) {
_a = _a * mat;
_b = _b * mat;
clear_viz_arcs();
mark_viz_stale();
mark_bound_stale();
}
@ -109,35 +93,6 @@ output(ostream &out) const {
out << "segment, a (" << _a << "), b (" << _b << ")";
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::set_from_lens
// Access: Public
// Description: Accepts a LensNode and a 2-d point in the range
// [-1,1]. Sets the CollisionSegment so that it begins at
// the LensNode's near plane and extends to the
// far plane, making it suitable for picking objects
// from the screen given a camera and a mouse location.
//
// Returns true if the point was acceptable, false
// otherwise.
////////////////////////////////////////////////////////////////////
bool CollisionSegment::
set_from_lens(LensNode *camera, const LPoint2f &point) {
Lens *proj = camera->get_lens();
bool success = true;
if (!proj->extrude(point, _a, _b)) {
_a = LPoint3f::origin();
_b = _a + LVector3f::forward();
success = false;
}
mark_bound_stale();
mark_viz_stale();
return success;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::set_from_lens
// Access: Public
@ -190,35 +145,6 @@ recompute_bound() {
return bound;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::recompute_viz
// Access: Public, Virtual
// Description: Rebuilds the geometry that will be used to render a
// visible representation of the collision solid.
////////////////////////////////////////////////////////////////////
void CollisionSegment::
recompute_viz(Node *parent) {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << " on " << *parent << "\n";
}
GeomLine *segment = new GeomLine;
PTA_Vertexf verts;
PTA_Colorf colors;
verts.push_back(_a);
verts.push_back(_b);
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
segment->set_coords(verts);
segment->set_colors(colors, G_OVERALL);
segment->set_num_prims(1);
GeomNode *viz = new GeomNode("viz-segment");
viz->add_geom(segment);
add_other_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::fill_viz_geom
// Access: Protected, Virtual

View File

@ -23,7 +23,6 @@
#include "collisionSolid.h"
class LensNode;
class qpLensNode;
///////////////////////////////////////////////////////////////////
@ -48,11 +47,6 @@ public:
INLINE CollisionSegment(const CollisionSegment &copy);
virtual CollisionSolid *make_copy();
virtual int
test_intersection(CollisionHandler *record,
const CollisionEntry &entry,
const CollisionSolid *into) const;
virtual int
test_intersection(qpCollisionHandler *record,
const qpCollisionEntry &entry,
@ -72,9 +66,6 @@ PUBLISHED:
INLINE void set_point_b(float x, float y, float z);
INLINE const LPoint3f &get_point_b() const;
bool set_from_lens(LensNode *camera, const LPoint2f &point);
INLINE bool set_from_lens(LensNode *camera, float px, float py);
bool set_from_lens(qpLensNode *camera, const LPoint2f &point);
INLINE bool set_from_lens(qpLensNode *camera, float px, float py);
@ -82,7 +73,6 @@ protected:
virtual BoundingVolume *recompute_bound();
protected:
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
private:

View File

@ -59,6 +59,5 @@ is_tangible() const {
////////////////////////////////////////////////////////////////////
INLINE void CollisionSolid::
mark_viz_stale() {
_viz_stale = true;
_viz_geom_stale = true;
}

View File

@ -19,7 +19,6 @@
#include "collisionSolid.h"
#include "config_collide.h"
#include "collisionEntry.h"
#include "collisionSphere.h"
#include "collisionRay.h"
#include "collisionSegment.h"
@ -35,14 +34,6 @@
#include "transparencyAttrib.h"
#include "qpgeomNode.h"
#include "renderRelation.h"
#include "geomNode.h"
#include "cullFaceTransition.h"
#include "colorTransition.h"
#include "renderModeTransition.h"
#include "transparencyTransition.h"
#include "textureTransition.h"
TypeHandle CollisionSolid::_type_handle;
////////////////////////////////////////////////////////////////////
@ -52,7 +43,6 @@ TypeHandle CollisionSolid::_type_handle;
////////////////////////////////////////////////////////////////////
CollisionSolid::
CollisionSolid() {
_viz_stale = true;
_viz_geom_stale = true;
_tangible = true;
}
@ -67,7 +57,6 @@ CollisionSolid(const CollisionSolid &copy) :
_tangible(copy._tangible)
{
// Actually, there's not a whole lot here we want to copy.
_viz_stale = true;
_viz_geom_stale = true;
}
@ -78,21 +67,6 @@ CollisionSolid(const CollisionSolid &copy) :
////////////////////////////////////////////////////////////////////
CollisionSolid::
~CollisionSolid() {
clear_viz_arcs();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::update_viz
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionSolid::
update_viz(Node *parent) {
if (_viz_stale) {
clear_viz_arcs();
recompute_viz(parent);
_viz_stale = false;
}
}
////////////////////////////////////////////////////////////////////
@ -137,45 +111,6 @@ write(ostream &out, int indent_level) const {
indent(out, indent_level) << (*this) << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::test_intersection_from_sphere
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionSolid::
test_intersection_from_sphere(CollisionHandler *,
const CollisionEntry &) const {
report_undefined_intersection_test(CollisionSphere::get_class_type(),
get_type());
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::test_intersection_from_ray
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionSolid::
test_intersection_from_ray(CollisionHandler *,
const CollisionEntry &) const {
report_undefined_intersection_test(CollisionRay::get_class_type(),
get_type());
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::test_intersection_from_segment
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionSolid::
test_intersection_from_segment(CollisionHandler *,
const CollisionEntry &) const {
report_undefined_intersection_test(CollisionSegment::get_class_type(),
get_type());
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::test_intersection_from_sphere
// Access: Protected, Virtual
@ -244,75 +179,6 @@ report_undefined_intersection_test(TypeHandle from_type, TypeHandle into_type) {
#endif
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::clear_viz_arcs
// Access: Protected
// Description: Removes all of the solids' visualization geometry and
// marks the viz as stale so it will be recomputed next
// time the solid is rendered.
////////////////////////////////////////////////////////////////////
void CollisionSolid::
clear_viz_arcs() {
VizArcs::iterator vi;
for (vi = _solid_viz_arcs.begin(); vi != _solid_viz_arcs.end(); ++vi) {
remove_arc(*vi);
}
for (vi = _wireframe_viz_arcs.begin(); vi != _wireframe_viz_arcs.end(); ++vi) {
remove_arc(*vi);
}
for (vi = _other_viz_arcs.begin(); vi != _other_viz_arcs.end(); ++vi) {
remove_arc(*vi);
}
_solid_viz_arcs.clear();
_wireframe_viz_arcs.clear();
_other_viz_arcs.clear();
_viz_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::add_solid_viz
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void CollisionSolid::
add_solid_viz(Node *parent, GeomNode *viz) {
RenderRelation *arc = new RenderRelation(parent, viz);
arc->set_transition(new CullFaceTransition(CullFaceProperty::M_cull_clockwise));
arc->set_transition(new RenderModeTransition(RenderModeProperty::M_filled));
arc->set_transition(new TextureTransition(TextureTransition::off()));
arc->set_transition(new TransparencyTransition(TransparencyProperty::M_alpha));
if (is_tangible()) {
arc->set_transition(new ColorTransition(1.0f, 1.0f, 1.0f, 0.5));
} else {
arc->set_transition(new ColorTransition(1.0f, 0.3, 0.5, 0.5));
}
_solid_viz_arcs.push_back(arc);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::add_wireframe_viz
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void CollisionSolid::
add_wireframe_viz(Node *parent, GeomNode *viz) {
RenderRelation *arc = new RenderRelation(parent, viz);
arc->set_transition(new CullFaceTransition(CullFaceProperty::M_cull_none));
arc->set_transition(new RenderModeTransition(RenderModeProperty::M_wireframe));
arc->set_transition(new TextureTransition(TextureTransition::off()));
arc->set_transition(new TransparencyTransition(TransparencyProperty::M_none));
float r,g,b;
if (is_tangible()) {
r=1.0f; g=1.0f; b=0.0f;
} else {
r=0.0f; g=0.0f; b=1.0f;
}
arc->set_transition(new ColorTransition(r,g,b,1.0f));
_wireframe_viz_arcs.push_back(arc);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::write_datagram
// Access: Public
@ -340,22 +206,6 @@ fillin(DatagramIterator& scan, BamReader*)
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::add_other_viz
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void CollisionSolid::
add_other_viz(Node *parent, GeomNode *viz) {
RenderRelation *arc = new RenderRelation(parent, viz);
arc->set_transition(new CullFaceTransition(CullFaceProperty::M_cull_clockwise));
arc->set_transition(new RenderModeTransition(RenderModeProperty::M_filled));
arc->set_transition(new TextureTransition(TextureTransition::off()));
arc->set_transition(new TransparencyTransition(TransparencyProperty::M_alpha));
_other_viz_arcs.push_back(arc);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::fill_viz_geom
// Access: Protected, Virtual

View File

@ -28,18 +28,10 @@
#include "renderState.h"
#include "qpgeomNode.h"
#include "nodeRelation.h"
#include "node.h"
#include "vector_PT_NodeRelation.h"
class CollisionHandler;
class qpCollisionHandler;
class CollisionEntry;
class qpCollisionEntry;
class CollisionSphere;
class Node;
class GeomNode;
class CollisionNode;
class qpGeomNode;
class qpCollisionNode;
///////////////////////////////////////////////////////////////////
@ -71,17 +63,12 @@ PUBLISHED:
public:
virtual int
test_intersection(CollisionHandler *record,
const CollisionEntry &entry,
const CollisionSolid *into) const=0;
virtual int
test_intersection(qpCollisionHandler *record,
const qpCollisionEntry &entry,
const CollisionSolid *into) const=0;
virtual void xform(const LMatrix4f &mat)=0;
void update_viz(Node *parent);
qpGeomNode *get_viz();
PUBLISHED:
@ -90,15 +77,6 @@ PUBLISHED:
protected:
virtual int
test_intersection_from_sphere(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_ray(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_segment(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_sphere(qpCollisionHandler *record,
const qpCollisionEntry &entry) const;
virtual int
@ -113,25 +91,13 @@ protected:
TypeHandle into_type);
INLINE void mark_viz_stale();
void clear_viz_arcs();
void add_solid_viz(Node *parent, GeomNode *viz);
void add_wireframe_viz(Node *parent, GeomNode *viz);
void add_other_viz(Node *parent, GeomNode *viz);
virtual void recompute_viz(Node *parent)=0;
virtual void fill_viz_geom();
CPT(RenderState) get_solid_viz_state();
CPT(RenderState) get_wireframe_viz_state();
CPT(RenderState) get_other_viz_state();
typedef vector_PT_NodeRelation VizArcs;
VizArcs _solid_viz_arcs;
VizArcs _wireframe_viz_arcs;
VizArcs _other_viz_arcs;
PT(qpGeomNode) _viz_geom;
bool _viz_stale;
bool _viz_geom_stale;
bool _tangible;

View File

@ -20,19 +20,15 @@
#include "collisionSphere.h"
#include "collisionRay.h"
#include "collisionSegment.h"
#include "collisionHandler.h"
#include "qpcollisionHandler.h"
#include "collisionEntry.h"
#include "qpcollisionEntry.h"
#include "config_collide.h"
#include "boundingSphere.h"
#include "geomNode.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "geomSphere.h"
#include "nearly_zero.h"
@ -48,17 +44,6 @@ make_copy() {
return new CollisionSphere(*this);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::test_intersection
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionSphere::
test_intersection(CollisionHandler *record, const CollisionEntry &entry,
const CollisionSolid *into) const {
return into->test_intersection_from_sphere(record, entry);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::test_intersection
// Access: Public, Virtual
@ -84,7 +69,7 @@ xform(const LMatrix4f &mat) {
LVector3f radius_v = LVector3f(_radius, 0.0f, 0.0f) * mat;
_radius = length(radius_v);
clear_viz_arcs();
mark_viz_stale();
mark_bound_stale();
}
@ -127,146 +112,6 @@ recompute_bound() {
return bound;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::test_intersection_from_sphere
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionSphere::
test_intersection_from_sphere(CollisionHandler *record,
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();
LVector3f from_radius_v =
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_space();
float from_radius = length(from_radius_v);
LPoint3f into_center = _center;
float into_radius = _radius;
LVector3f vec = from_center - into_center;
float dist2 = dot(vec, vec);
if (dist2 > (into_radius + from_radius) * (into_radius + from_radius)) {
// No intersection.
return 0;
}
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "intersection detected from " << *entry.get_from_node() << " into "
<< entry.get_into_node_path() << "\n";
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
float dist = sqrtf(dist2);
LVector3f into_normal = normalize(vec);
LPoint3f into_intersection_point = into_normal * (dist - from_radius);
float into_depth = into_radius + from_radius - dist;
new_entry->set_into_surface_normal(into_normal * entry.get_inv_wrt_space());
new_entry->set_into_intersection_point(into_intersection_point * entry.get_inv_wrt_space());
new_entry->set_into_depth(into_depth);
record->add_entry(new_entry);
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::test_intersection_from_ray
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionSphere::
test_intersection_from_ray(CollisionHandler *record,
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();
double t1, t2;
if (!intersects_line(t1, t2, from_origin, from_direction)) {
// No intersection.
return 0;
}
if (t2 < 0.0) {
// Both intersection points are before the start of the ray.
return 0;
}
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "intersection detected from " << *entry.get_from_node() << " into "
<< entry.get_into_node_path() << "\n";
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
LPoint3f into_intersection_point;
if (t1 < 0.0) {
into_intersection_point = from_origin + t2 * from_direction;
} else {
into_intersection_point = from_origin + t1 * from_direction;
}
new_entry->set_into_intersection_point(into_intersection_point);
record->add_entry(new_entry);
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::test_intersection_from_segment
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int CollisionSphere::
test_intersection_from_segment(CollisionHandler *record,
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();
LVector3f from_direction = from_b - from_a;
double t1, t2;
if (!intersects_line(t1, t2, from_a, from_direction)) {
// No intersection.
return 0;
}
if (t2 < 0.0 || t1 > 1.0) {
// Both intersection points are before the start of the segment or
// after the end of the segment.
return 0;
}
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "intersection detected from " << *entry.get_from_node() << " into "
<< entry.get_into_node_path() << "\n";
}
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
LPoint3f into_intersection_point;
if (t1 < 0.0) {
// Point a is within the sphere. The first intersection point is
// point a itself.
into_intersection_point = from_a;
} else {
// Point a is outside the sphere, and point b is either inside the
// sphere or beyond it. The first intersection point is at t1.
into_intersection_point = from_a + t1 * from_direction;
}
new_entry->set_into_intersection_point(into_intersection_point);
record->add_entry(new_entry);
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::test_intersection_from_sphere
// Access: Public, Virtual
@ -407,32 +252,6 @@ test_intersection_from_segment(qpCollisionHandler *record,
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::recompute_viz
// Access: Public, Virtual
// Description: Rebuilds the geometry that will be used to render a
// visible representation of the collision solid.
////////////////////////////////////////////////////////////////////
void CollisionSphere::
recompute_viz(Node *parent) {
if (collide_cat.is_debug()) {
collide_cat.debug()
<< "Recomputing viz for " << *this << " on " << *parent << "\n";
}
GeomSphere *sphere = new GeomSphere;
PTA_Vertexf verts;
verts.push_back(_center);
verts.push_back(_center + LVector3f(_radius, 0.0f, 0.0f));
sphere->set_coords(verts);
sphere->set_num_prims(1);
GeomNode *viz = new GeomNode("viz-sphere");
viz->add_geom(sphere);
add_solid_viz(parent, viz);
// add_wireframe_viz(parent, viz);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSphere::fill_viz_geom
// Access: Protected, Virtual

View File

@ -36,11 +36,6 @@ public:
INLINE CollisionSphere(const CollisionSphere &copy);
virtual CollisionSolid *make_copy();
virtual int
test_intersection(CollisionHandler *record,
const CollisionEntry &entry,
const CollisionSolid *into) const;
virtual int
test_intersection(qpCollisionHandler *record,
const qpCollisionEntry &entry,
@ -65,15 +60,6 @@ protected:
protected:
virtual int
test_intersection_from_sphere(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_ray(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_segment(CollisionHandler *record,
const CollisionEntry &entry) const;
virtual int
test_intersection_from_sphere(qpCollisionHandler *record,
const qpCollisionEntry &entry) const;
virtual int
@ -83,7 +69,6 @@ protected:
test_intersection_from_segment(qpCollisionHandler *record,
const qpCollisionEntry &entry) const;
virtual void recompute_viz(Node *parent);
virtual void fill_viz_geom();
bool intersects_line(double &t1, double &t2,

View File

@ -1,17 +0,0 @@
// Filename: collisionTraverser.I
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////

View File

@ -1,633 +0,0 @@
// Filename: collisionTraverser.cxx
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "collisionNode.h"
#include "collisionEntry.h"
#include "collisionPolygon.h"
#include "config_collide.h"
#include <transformTransition.h>
#include <geomNode.h>
#include <geom.h>
#include "collisionTraverser.h"
#include <nodePath.h>
#include <dftraverser.h>
#include <wrt.h>
#include <get_rel_pos.h>
#include <pStatTimer.h>
#ifndef CPPPARSER
PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions");
#endif
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CollisionTraverser::
CollisionTraverser(TypeHandle graph_type) :
_graph_type(graph_type)
{
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CollisionTraverser::
~CollisionTraverser() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::add_collider
// Access: Public
// Description: Adds a new CollisionNode, representing an object that
// will be tested for collisions into other objects,
// along with the handler that will serve each detected
// collision. Each CollisionNode may be served by only
// one handler at a time, but a given handler may serve
// many CollisionNodes.
//
// The handler that serves a particular node may be
// changed from time to time by calling add_collider()
// again on the same node.
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
add_collider(CollisionNode *node, CollisionHandler *handler) {
nassertv(_ordered_colliders.size() == _colliders.size());
nassertv(node != (CollisionNode *)NULL);
nassertv(handler != (CollisionHandler *)NULL);
Colliders::iterator ci = _colliders.find(node);
if (ci != _colliders.end()) {
// We already knew about this collider.
if ((*ci).second != handler) {
// Change the handler.
PT(CollisionHandler) old_handler = (*ci).second;
(*ci).second = handler;
// Now update our own reference counts within our handler set.
Handlers::iterator hi = _handlers.find(old_handler);
nassertv(hi != _handlers.end());
(*hi).second--;
nassertv((*hi).second >= 0);
if ((*hi).second == 0) {
_handlers.erase(hi);
}
hi = _handlers.find(handler);
if (hi == _handlers.end()) {
_handlers.insert(Handlers::value_type(handler, 1));
} else {
(*hi).second++;
}
}
} else {
// We hadn't already known about this collider.
_colliders.insert(Colliders::value_type(node, handler));
_ordered_colliders.push_back(node);
Handlers::iterator hi = _handlers.find(handler);
if (hi == _handlers.end()) {
_handlers.insert(Handlers::value_type(handler, 1));
} else {
(*hi).second++;
}
}
nassertv(_ordered_colliders.size() == _colliders.size());
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::remove_collider
// Access: Public
// Description: Removes the collider (and its associated handler)
// from the set of CollisionNodes that will be tested
// each frame for collisions into other objects.
// Returns true if the definition was found and removed,
// false if it wasn't present to begin with.
////////////////////////////////////////////////////////////////////
bool CollisionTraverser::
remove_collider(CollisionNode *node) {
nassertr(_ordered_colliders.size() == _colliders.size(), false);
Colliders::iterator ci = _colliders.find(node);
if (ci == _colliders.end()) {
// We didn't know about this node.
return false;
}
CollisionHandler *handler = (*ci).second;
// Update the set of handlers.
Handlers::iterator hi = _handlers.find(handler);
nassertr(hi != _handlers.end(), false);
(*hi).second--;
nassertr((*hi).second >= 0, false);
if ((*hi).second == 0) {
_handlers.erase(hi);
}
_colliders.erase(ci);
OrderedColliders::iterator oci =
find(_ordered_colliders.begin(), _ordered_colliders.end(), node);
nassertr(oci != _ordered_colliders.end(), false);
_ordered_colliders.erase(oci);
nassertr(_ordered_colliders.size() == _colliders.size(), false);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::has_collider
// Access: Public
// Description: Returns true if the indicated node is current in the
// set of nodes that will be tested each frame for
// collisions into other objects.
////////////////////////////////////////////////////////////////////
bool CollisionTraverser::
has_collider(CollisionNode *node) const {
Colliders::const_iterator ci = _colliders.find(node);
return (ci != _colliders.end());
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_num_colliders
// Access: Public
// Description: Returns the number of CollisionNodes that have been
// added to the traverser via add_collider().
////////////////////////////////////////////////////////////////////
int CollisionTraverser::
get_num_colliders() const {
nassertr(_ordered_colliders.size() == _colliders.size(), 0);
return _ordered_colliders.size();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_collider
// Access: Public
// Description: Returns the nth CollisionNode that has been
// added to the traverser via add_collider().
////////////////////////////////////////////////////////////////////
CollisionNode *CollisionTraverser::
get_collider(int n) const {
nassertr(_ordered_colliders.size() == _colliders.size(), NULL);
nassertr(n >= 0 && n < (int)_ordered_colliders.size(), NULL);
return _ordered_colliders[n];
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_handler
// Access: Public
// Description: Returns the handler that is currently assigned to
// serve the indicated collision node, or NULL if the
// node is not on the traverser's set of active nodes.
////////////////////////////////////////////////////////////////////
CollisionHandler *CollisionTraverser::
get_handler(CollisionNode *node) const {
Colliders::const_iterator ci = _colliders.find(node);
if (ci != _colliders.end()) {
return (*ci).second;
};
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::clear_colliders
// Access: Public
// Description: Completely empties the set of collision nodes and
// their associated handlers.
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
clear_colliders() {
_colliders.clear();
_ordered_colliders.clear();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::traverse
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
traverse(Node *root) {
traverse(NodePath(root, _graph_type));
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::traverse
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
traverse(const NodePath &root) {
nassertv(root.get_graph_type() == _graph_type);
PStatTimer timer(_collisions_pcollector);
CollisionLevelState level_state(root);
prepare_colliders(level_state);
Handlers::iterator hi;
for (hi = _handlers.begin(); hi != _handlers.end(); ++hi) {
(*hi).first->begin_group();
}
df_traverse(root.node(), *this, NullTransitionWrapper(),
level_state, _graph_type);
hi = _handlers.begin();
while (hi != _handlers.end()) {
if (!(*hi).first->end_group()) {
// This handler wants to remove itself from the traversal list.
Handlers::iterator hnext = hi;
++hnext;
_handlers.erase(hi);
hi = hnext;
} else {
++hi;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
output(ostream &out) const {
out << "CollisionTraverser, " << _colliders.size()
<< " colliders and " << _handlers.size() << " handlers.\n";
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::write
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< "CollisionTraverser, " << _colliders.size()
<< " colliders and " << _handlers.size() << " handlers:\n";
Colliders::const_iterator ci;
for (ci = _colliders.begin(); ci != _colliders.end(); ++ci) {
CollisionNode *cnode = (*ci).first;
CollisionHandler *handler = (*ci).second;
nassertv(cnode != (CollisionNode *)NULL);
nassertv(handler != (CollisionHandler *)NULL);
indent(out, indent_level + 2)
<< *cnode << " handled by " << handler->get_type() << "\n";
int num_solids = cnode->get_num_solids();
for (int i = 0; i < num_solids; i++) {
cnode->get_solid(i)->write(out, indent_level + 4);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::prepare_colliders
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
prepare_colliders(CollisionLevelState &level_state) {
level_state.clear();
level_state.reserve(_colliders.size());
int i = 0;
while (i < (int)_ordered_colliders.size()) {
CollisionNode *cnode = _ordered_colliders[i];
CollisionLevelState::ColliderDef def;
def._node = cnode;
get_rel_mat(cnode, NULL, def._space, _graph_type);
def._inv_space.invert_from(def._space);
#ifndef NDEBUG
if (def._space.is_nan()) {
collide_cat.error()
<< "Collider " << *cnode
<< " has become NaN. 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);
} else
#endif
{
int num_solids = cnode->get_num_solids();
for (int s = 0; s < num_solids; s++) {
CollisionSolid *collider = cnode->get_solid(s);
def._collider = collider;
level_state.prepare_collider(def);
}
i++;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::reached_node
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool CollisionTraverser::
reached_node(Node *node, NullTransitionWrapper &,
CollisionLevelState &level_state) {
if (node->is_of_type(CollisionNode::get_class_type())) {
level_state.reached_collision_node();
CollisionNode *cnode;
DCAST_INTO_R(cnode, node, false);
const BoundingVolume &node_bv = cnode->get_bound();
const GeometricBoundingVolume *node_gbv = NULL;
if (node_bv.is_of_type(GeometricBoundingVolume::get_class_type())) {
DCAST_INTO_R(node_gbv, &node_bv, false);
}
CollisionEntry entry;
entry._into_node = cnode;
entry._into_node_path = NodePath(level_state.get_arc_chain(), _graph_type);
entry._into_space = entry._into_node_path.get_mat(NodePath());
int num_colliders = level_state.get_num_colliders();
for (int c = 0; c < num_colliders; c++) {
if (level_state.has_collider(c)) {
entry._from_node = level_state.get_node(c);
if ((entry._from_node->get_from_collide_mask() &
cnode->get_into_collide_mask()) != 0) {
entry._from = level_state.get_collider(c);
entry._from_space = level_state.get_space(c);
NodePath root;
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);
const GeometricBoundingVolume *col_gbv =
level_state.get_local_bound(c);
compare_collider_to_node(entry, col_gbv, node_gbv);
}
}
}
} else if (node->is_of_type(GeomNode::get_class_type()) &&
level_state.has_any_collide_geom()) {
GeomNode *gnode;
DCAST_INTO_R(gnode, node, false);
const BoundingVolume &node_bv = gnode->get_bound();
const GeometricBoundingVolume *node_gbv = NULL;
if (node_bv.is_of_type(GeometricBoundingVolume::get_class_type())) {
DCAST_INTO_R(node_gbv, &node_bv, false);
}
CollisionEntry entry;
entry._into_node = gnode;
get_rel_mat(node, NULL, entry._into_space, _graph_type);
int num_colliders = level_state.get_num_colliders();
for (int c = 0; c < num_colliders; c++) {
if (level_state.has_collider_with_geom(c)) {
entry._from_node = level_state.get_node(c);
entry._from = level_state.get_collider(c);
entry._from_space = level_state.get_space(c);
LMatrix4f into_space_inv;
get_rel_mat(NULL, node, into_space_inv, _graph_type);
entry._wrt_space = entry._from_space * into_space_inv;
entry._inv_wrt_space =
entry._into_space * level_state.get_inv_space(c);
const GeometricBoundingVolume *col_gbv =
level_state.get_local_bound(c);
compare_collider_to_geom_node(entry, col_gbv, node_gbv);
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::forward_arc
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool CollisionTraverser::
forward_arc(NodeRelation *arc, NullTransitionWrapper &,
NullTransitionWrapper &, NullTransitionWrapper &,
CollisionLevelState &level_state) {
// Check the bounding volume on the arc against each of our
// colliders.
const BoundingVolume &arc_bv = arc->get_bound();
if (arc_bv.is_of_type(GeometricBoundingVolume::get_class_type())) {
const GeometricBoundingVolume *arc_gbv;
DCAST_INTO_R(arc_gbv, &arc_bv, false);
int num_colliders = level_state.get_num_colliders();
for (int c = 0; c < num_colliders; c++) {
if (level_state.has_collider(c)) {
const GeometricBoundingVolume *col_gbv =
level_state.get_local_bound(c);
if (col_gbv != (GeometricBoundingVolume *)NULL) {
if (arc_gbv->contains(col_gbv) == 0) {
// This collider certainly does not intersect with any
// geometry at this arc or below.
level_state.omit_collider(c);
}
}
}
}
}
if (!level_state.has_any_collider()) {
// No colliders intersect with the geometry at this arc or below,
// so don't bother traversing them.
return false;
}
TransformTransition *tt;
if (get_transition_into(tt, arc)) {
// There's a transform on the arc; apply it to our colliders'
// bounding volumes.
LMatrix4f inv_mat;
inv_mat.invert_from(tt->get_matrix());
level_state.xform(inv_mat);
}
level_state.forward_arc(arc);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::compare_collider_to_node
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
compare_collider_to_node(CollisionEntry &entry,
const GeometricBoundingVolume *from_node_gbv,
const GeometricBoundingVolume *into_node_gbv) {
bool within_node_bounds = true;
if (from_node_gbv != (GeometricBoundingVolume *)NULL &&
into_node_gbv != (GeometricBoundingVolume *)NULL) {
within_node_bounds = (into_node_gbv->contains(from_node_gbv) != 0);
}
if (within_node_bounds) {
CollisionNode *cnode;
DCAST_INTO_V(cnode, entry._into_node);
int num_solids = cnode->get_num_solids();
for (int s = 0; s < num_solids; s++) {
entry._into = cnode->get_solid(s);
if (entry._from != entry._into) {
const BoundingVolume &solid_bv = entry._into->get_bound();
const GeometricBoundingVolume *solid_gbv = NULL;
if (num_solids > 1 &&
solid_bv.is_of_type(GeometricBoundingVolume::get_class_type())) {
// Only bother to test against each solid's bounding
// volume if we have more than one solid in the node, as a
// slight optimization. (If the node contains just one
// solid, then the node's bounding volume, which we just
// tested, is the same as the solid's bounding volume.)
DCAST_INTO_V(solid_gbv, &solid_bv);
}
compare_collider_to_solid(entry, from_node_gbv, solid_gbv);
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::compare_collider_to_geom_node
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
compare_collider_to_geom_node(CollisionEntry &entry,
const GeometricBoundingVolume *from_node_gbv,
const GeometricBoundingVolume *into_node_gbv) {
bool within_node_bounds = true;
if (from_node_gbv != (GeometricBoundingVolume *)NULL &&
into_node_gbv != (GeometricBoundingVolume *)NULL) {
within_node_bounds = (into_node_gbv->contains(from_node_gbv) != 0);
}
if (within_node_bounds) {
GeomNode *gnode;
DCAST_INTO_V(gnode, entry._into_node);
int num_geoms = gnode->get_num_geoms();
for (int s = 0; s < num_geoms; s++) {
entry._into = (CollisionSolid *)NULL;
Geom *geom = DCAST(Geom, gnode->get_geom(s));
if (geom != (Geom *)NULL) {
const BoundingVolume &geom_bv = geom->get_bound();
const GeometricBoundingVolume *geom_gbv = NULL;
if (num_geoms > 1 &&
geom_bv.is_of_type(GeometricBoundingVolume::get_class_type())) {
// Only bother to test against each geom's bounding
// volume if we have more than one geom in the node, as a
// slight optimization. (If the node contains just one
// geom, then the node's bounding volume, which we just
// tested, is the same as the geom's bounding volume.)
DCAST_INTO_V(geom_gbv, &geom_bv);
}
compare_collider_to_geom(entry, geom, from_node_gbv, geom_gbv);
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::compare_collider_to_solid
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
compare_collider_to_solid(CollisionEntry &entry,
const GeometricBoundingVolume *from_node_gbv,
const GeometricBoundingVolume *solid_gbv) {
bool within_solid_bounds = true;
if (from_node_gbv != (GeometricBoundingVolume *)NULL &&
solid_gbv != (GeometricBoundingVolume *)NULL) {
within_solid_bounds = (solid_gbv->contains(from_node_gbv) != 0);
}
if (within_solid_bounds) {
Colliders::const_iterator ci;
ci = _colliders.find(entry.get_from_node());
nassertv(ci != _colliders.end());
entry.get_from()->test_intersection((*ci).second, entry, entry.get_into());
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::compare_collider_to_geom
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
compare_collider_to_geom(CollisionEntry &entry, Geom *geom,
const GeometricBoundingVolume *from_node_gbv,
const GeometricBoundingVolume *geom_gbv) {
bool within_geom_bounds = true;
if (from_node_gbv != (GeometricBoundingVolume *)NULL &&
geom_gbv != (GeometricBoundingVolume *)NULL) {
within_geom_bounds = (geom_gbv->contains(from_node_gbv) != 0);
}
if (within_geom_bounds) {
Colliders::const_iterator ci;
ci = _colliders.find(entry.get_from_node());
nassertv(ci != _colliders.end());
PTA_Vertexf coords;
PTA_ushort vindex;
geom->get_coords(coords, vindex);
PTA_ushort tris = geom->get_tris();
for (int i = 0; i < (int)tris.size(); i += 3) {
if (CollisionPolygon::verify_points(coords[tris[i]],
coords[tris[i + 1]],
coords[tris[i + 2]])) {
// Generate a temporary CollisionPolygon on the fly for each
// triangle in the Geom.
CollisionPolygon poly(coords[tris[i]], coords[tris[i + 1]],
coords[tris[i + 2]]);
if (entry.get_from()->test_intersection((*ci).second, entry, &poly) != 0) {
return;
}
}
}
}
}

View File

@ -1,116 +0,0 @@
// Filename: collisionTraverser.h
// Created by: drose (24Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef COLLISIONTRAVERSER_H
#define COLLISIONTRAVERSER_H
#include <pandabase.h>
#include "collisionHandler.h"
#include "collisionLevelState.h"
#include <traverserVisitor.h>
#include <nullTransitionWrapper.h>
#include <pointerTo.h>
#include <renderRelation.h>
#include <pointerTo.h>
#include <pStatCollector.h>
#include "pset.h"
class CollisionNode;
class Geom;
class NodePath;
////////////////////////////////////////////////////////////////////
// Class : CollisionTraverser
// Description :
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionTraverser :
public TraverserVisitor<NullTransitionWrapper, CollisionLevelState> {
PUBLISHED:
CollisionTraverser(TypeHandle graph_type = RenderRelation::get_class_type());
~CollisionTraverser();
void add_collider(CollisionNode *node, CollisionHandler *handler);
bool remove_collider(CollisionNode *node);
bool has_collider(CollisionNode *node) const;
int get_num_colliders() const;
CollisionNode *get_collider(int n) const;
CollisionHandler *get_handler(CollisionNode *node) const;
void clear_colliders();
void traverse(Node *root);
void traverse(const NodePath &root);
void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
private:
void prepare_colliders(CollisionLevelState &state);
public:
// These methods, from parent class TraverserVisitor, define the
// behavior of the CollisionTraverser as it traverses the graph.
// Normally you would never call these directly.
bool reached_node(Node *node, NullTransitionWrapper &render_state,
CollisionLevelState &level_state);
bool forward_arc(NodeRelation *arc, NullTransitionWrapper &trans,
NullTransitionWrapper &pre, NullTransitionWrapper &post,
CollisionLevelState &level_state);
private:
void compare_collider_to_node(CollisionEntry &entry,
const GeometricBoundingVolume *from_node_gbv,
const GeometricBoundingVolume *into_node_gbv);
void compare_collider_to_geom_node(CollisionEntry &entry,
const GeometricBoundingVolume *from_node_gbv,
const GeometricBoundingVolume *into_node_gbv);
void compare_collider_to_solid(CollisionEntry &entry,
const GeometricBoundingVolume *from_node_gbv,
const GeometricBoundingVolume *solid_gbv);
void compare_collider_to_geom(CollisionEntry &entry, Geom *geom,
const GeometricBoundingVolume *from_node_gbv,
const GeometricBoundingVolume *solid_gbv);
private:
PT(CollisionHandler) _default_handler;
TypeHandle _graph_type;
typedef pmap<PT(CollisionNode), PT(CollisionHandler) > Colliders;
Colliders _colliders;
typedef pvector<CollisionNode *> OrderedColliders;
OrderedColliders _ordered_colliders;
typedef pmap<PT(CollisionHandler), int> Handlers;
Handlers _handlers;
// Statistics
static PStatCollector _collisions_pcollector;
};
INLINE ostream &operator << (ostream &out, const CollisionTraverser &trav) {
trav.output(out);
return out;
}
#include "collisionTraverser.I"
#endif

View File

@ -17,21 +17,13 @@
////////////////////////////////////////////////////////////////////
#include "config_collide.h"
#include "collisionEntry.h"
#include "qpcollisionEntry.h"
#include "collisionHandler.h"
#include "qpcollisionHandler.h"
#include "collisionHandlerEvent.h"
#include "qpcollisionHandlerEvent.h"
#include "collisionHandlerFloor.h"
#include "qpcollisionHandlerFloor.h"
#include "collisionHandlerPhysical.h"
#include "qpcollisionHandlerPhysical.h"
#include "collisionHandlerPusher.h"
#include "qpcollisionHandlerPusher.h"
#include "collisionHandlerQueue.h"
#include "qpcollisionHandlerQueue.h"
#include "collisionNode.h"
#include "qpcollisionNode.h"
#include "collisionPlane.h"
#include "collisionPolygon.h"
@ -64,21 +56,13 @@ init_libcollide() {
}
initialized = true;
CollisionEntry::init_type();
qpCollisionEntry::init_type();
CollisionHandler::init_type();
qpCollisionHandler::init_type();
CollisionHandlerEvent::init_type();
qpCollisionHandlerEvent::init_type();
CollisionHandlerFloor::init_type();
qpCollisionHandlerFloor::init_type();
CollisionHandlerPhysical::init_type();
qpCollisionHandlerPhysical::init_type();
CollisionHandlerPusher::init_type();
qpCollisionHandlerPusher::init_type();
CollisionHandlerQueue::init_type();
qpCollisionHandlerQueue::init_type();
CollisionNode::init_type();
qpCollisionNode::init_type();
CollisionPlane::init_type();
CollisionPolygon::init_type();
@ -89,7 +73,6 @@ init_libcollide() {
//Registration of writeable object's creation
//functions with BamReader's factory
CollisionNode::register_with_read_factory();
qpCollisionNode::register_with_read_factory();
CollisionPlane::register_with_read_factory();
CollisionPolygon::register_with_read_factory();

View File

@ -18,6 +18,7 @@
#include "qpcollisionLevelState.h"
#include "collisionSolid.h"
#include "dcast.h"
////////////////////////////////////////////////////////////////////
// Function: qpCollisionLevelState::clear

View File

@ -16,7 +16,7 @@
//
////////////////////////////////////////////////////////////////////
#include "collisionNode.h"
#include "qpcollisionNode.h"
#include "config_collide.h"
#include "qpgeomNode.h"

View File

@ -24,10 +24,6 @@
#include "qpcollisionHandler.h"
#include "qpcollisionLevelState.h"
#include "traverserVisitor.h"
#include "nullTransitionWrapper.h"
#include "pointerTo.h"
#include "renderRelation.h"
#include "pointerTo.h"
#include "pStatCollector.h"

View File

@ -7,8 +7,8 @@
#begin lib_target
#define TARGET crgsg
#define LOCAL_LIBS \
pandabase cull gsgmisc gsgbase gobj sgattrib sgraphutil graph display \
putil linmath sgraph mathutil pnmimage
pandabase gsgmisc gsgbase gobj display \
putil linmath mathutil pnmimage
#define COMBINED_SOURCES $[TARGET]_composite1.cxx

File diff suppressed because it is too large Load Diff

View File

@ -29,10 +29,6 @@
#include "pixelBuffer.h"
#include "displayRegion.h"
#include "material.h"
#include "textureApplyProperty.h"
#include "depthTestProperty.h"
#include "stencilProperty.h"
#include "fog.h"
#include "depthTestAttrib.h"
#include "textureApplyAttrib.h"
#include "pointerToArray.h"
@ -87,15 +83,6 @@ public:
virtual void prepare_display_region();
virtual bool prepare_lens();
virtual void render_frame();
virtual void render_scene(Node *root, LensNode *projnode);
virtual void render_subgraph(RenderTraverser *traverser,
Node *subgraph, LensNode *projnode,
const AllTransitionsWrapper &net_trans);
virtual void render_subgraph(RenderTraverser *traverser,
Node *subgraph,
const AllTransitionsWrapper &net_trans);
virtual void draw_point(GeomPoint *geom, GeomContext *gc);
virtual void draw_line(GeomLine *geom, GeomContext *gc);
virtual void draw_linestrip(GeomLinestrip *geom, GeomContext *gc);
@ -111,16 +98,14 @@ public:
virtual void apply_texture(TextureContext *tc);
virtual void release_texture(TextureContext *tc);
virtual GeomNodeContext *prepare_geom_node(GeomNode *node);
virtual void draw_geom_node(GeomNode *node, GeomNodeContext *gnc);
virtual GeomNodeContext *prepare_geom_node(qpGeomNode *node);
virtual void draw_geom_node(qpGeomNode *node, const RenderState *state,
GeomNodeContext *gnc);
virtual void release_geom_node(GeomNodeContext *gnc);
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr);
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr,
const RenderBuffer &rb);
virtual void draw_texture(TextureContext *tc, const DisplayRegion *dr);
virtual void draw_texture(TextureContext *tc, const DisplayRegion *dr,
const RenderBuffer &rb);
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb);
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
@ -136,32 +121,8 @@ public:
const NodeTransitions& na=NodeTransitions());
virtual void apply_material(const Material *material);
virtual void apply_fog(Fog *fog);
void apply_fog(qpFog *fog);
virtual void issue_transform(const TransformTransition *attrib);
virtual void issue_color_transform(const ColorMatrixTransition *attrib);
virtual void issue_alpha_transform(const AlphaTransformTransition *attrib);
virtual void issue_tex_matrix(const TexMatrixTransition *attrib);
virtual void issue_color(const ColorTransition *attrib);
virtual void issue_texture(const TextureTransition *attrib);
virtual void issue_material(const MaterialTransition *attrib);
virtual void issue_render_mode(const RenderModeTransition *attrib);
virtual void issue_color_blend(const ColorBlendTransition *attrib);
virtual void issue_texture_apply(const TextureApplyTransition *attrib);
virtual void issue_color_mask(const ColorMaskTransition *attrib);
virtual void issue_depth_test(const DepthTestTransition *attrib);
virtual void issue_depth_write(const DepthWriteTransition *attrib);
virtual void issue_tex_gen(const TexGenTransition *attrib);
virtual void issue_cull_face(const CullFaceTransition *attrib);
virtual void issue_stencil(const StencilTransition *attrib);
virtual void issue_clip_plane(const ClipPlaneTransition *attrib);
virtual void issue_transparency(const TransparencyTransition *attrib);
virtual void issue_fog(const FogTransition *attrib);
virtual void issue_linesmooth(const LinesmoothTransition *attrib);
virtual void issue_point_shape(const PointShapeTransition *attrib);
virtual void issue_polygon_offset(const PolygonOffsetTransition *attrib);
virtual void issue_transform(const TransformState *transform);
virtual void issue_tex_matrix(const TexMatrixAttrib *attrib);
virtual void issue_texture(const TextureAttrib *attrib);
@ -185,9 +146,6 @@ public:
virtual bool wants_normals(void) const;
virtual bool wants_texcoords(void) const;
virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib);
virtual void end_decal(GeomNode *base_geom);
virtual bool depth_offset_decals();
virtual CoordinateSystem get_internal_coordinate_system() const;

View File

@ -1,53 +0,0 @@
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
dtoolutil:c dtoolbase:c dtool:m
#begin lib_target
#define TARGET cull
#define LOCAL_LIBS \
gobj sgraphutil graph putil sgraph mathutil sgattrib display \
pstatclient
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \
config_cull.h cullState.I cullState.h cullStateLookup.I \
cullStateLookup.h cullStateSubtree.I cullStateSubtree.h \
cullTraverser.I cullTraverser.h directRenderTransition.I \
directRenderTransition.h geomBin.I geomBin.h \
geomBinBackToFront.I geomBinBackToFront.h geomBinFixed.I \
geomBinFixed.h geomBinGroup.I geomBinGroup.h geomBinNormal.h \
geomBinTransition.I geomBinTransition.h geomBinUnsorted.I \
geomBinUnsorted.h
#define INCLUDED_SOURCES \
config_cull.cxx cullState.cxx cullStateLookup.cxx \
cullStateSubtree.cxx cullTraverser.cxx \
directRenderTransition.cxx geomBin.cxx \
geomBinBackToFront.cxx geomBinFixed.cxx geomBinGroup.cxx \
geomBinNormal.cxx geomBinTransition.cxx geomBinUnsorted.cxx
#define INSTALL_HEADERS \
config_cull.h cullLevelState.h cullState.I cullState.h \
cullStateLookup.I cullStateLookup.h cullStateSubtree.I \
cullStateSubtree.h cullTraverser.I cullTraverser.h \
directRenderTransition.I directRenderTransition.h geomBin.I \
geomBin.h \
geomBinBackToFront.I geomBinBackToFront.h geomBinFixed.I \
geomBinFixed.h geomBinGroup.I geomBinGroup.h geomBinNormal.h \
geomBinTransition.I geomBinTransition.h geomBinUnsorted.I \
geomBinUnsorted.h
#define IGATESCAN all
#end lib_target
#begin test_bin_target
#define TARGET test_cull
#define LOCAL_LIBS \
cull sgattrib
#define SOURCES \
test_cull.cxx
#end test_bin_target

View File

@ -1,55 +0,0 @@
// Filename: config_cull.cxx
// Created by: drose (07Apr00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "config_cull.h"
#include "cullTraverser.h"
#include "geomBin.h"
#include "geomBinUnsorted.h"
#include "geomBinBackToFront.h"
#include "geomBinGroup.h"
#include "geomBinNormal.h"
#include "geomBinTransition.h"
#include "geomBinFixed.h"
#include "directRenderTransition.h"
#include <dconfig.h>
ConfigureDef(config_cull);
NotifyCategoryDef(cull, "");
ConfigureFn(config_cull) {
CullTraverser::init_type();
GeomBin::init_type();
GeomBinUnsorted::init_type();
GeomBinBackToFront::init_type();
GeomBinGroup::init_type();
GeomBinNormal::init_type();
GeomBinTransition::init_type();
GeomBinFixed::init_type();
DirectRenderTransition::init_type();
//Registration of writeable object's creation
//functions with BamReader's factory
GeomBinTransition::register_with_read_factory();
}
// Set this true to force all of the caching to blow itself away every
// frame. Normally you would only do this during testing.
const bool cull_force_update = config_cull.GetBool("cull-force-update", false);

Some files were not shown because too many files have changed in this diff Show More