remove old scene graph code
This commit is contained in:
parent
83cfae1ab3
commit
a38e063667
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 ©) {
|
||||
_node = NULL;
|
||||
_qpnode = NULL;
|
||||
(*this) = copy;
|
||||
}
|
||||
|
|
@ -71,12 +67,10 @@ operator = (const BuilderBucket ©) {
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ©) :
|
||||
NamedNode(copy),
|
||||
_bundle(copy._bundle)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimBundleNode::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimBundleNode::
|
||||
operator = (const AnimBundleNode ©) {
|
||||
NamedNode::operator = (copy);
|
||||
_bundle = copy._bundle;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimBundleNode::get_bundle
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AnimBundle *AnimBundleNode::
|
||||
get_bundle() const {
|
||||
return _bundle;
|
||||
}
|
||||
|
|
@ -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 ¶ms)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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 ©);
|
||||
INLINE void operator = (const AnimBundleNode ©);
|
||||
|
||||
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 ¶ms);
|
||||
|
||||
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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
#include "animBundle.cxx"
|
||||
#include "animBundleNode.cxx"
|
||||
#include "qpanimBundleNode.cxx"
|
||||
#include "animChannel.cxx"
|
||||
#include "animChannelBase.cxx"
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 ©) :
|
||||
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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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 ©);
|
||||
|
||||
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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
#include "config_char.cxx"
|
||||
#include "character.cxx"
|
||||
#include "qpcharacter.cxx"
|
||||
#include "characterJoint.cxx"
|
||||
#include "characterJointBundle.cxx"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 ©) :
|
||||
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 ¶ms)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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 ©);
|
||||
|
||||
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 ¶ms);
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -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 ©) :
|
|||
_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++]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 ©) :
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ©) :
|
|||
// 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";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#include "collisionSegment.cxx"
|
||||
#include "collisionSolid.cxx"
|
||||
#include "collisionSphere.cxx"
|
||||
#include "collisionTraverser.cxx"
|
||||
#include "qpcollisionTraverser.cxx"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 ©) :
|
||||
_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 ©) {
|
||||
_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;
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
void operator = (const CollisionEntry ©);
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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];
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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 ©) :
|
||||
_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 ©) {
|
||||
_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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
INLINE void operator = (const CollisionLevelState ©);
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 ©) :
|
||||
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 ©) {
|
||||
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 ¶ms)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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 ©);
|
||||
void operator = (const CollisionNode ©);
|
||||
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 ¶ms);
|
||||
|
||||
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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include "collisionSolid.h"
|
||||
|
||||
class LensNode;
|
||||
class qpLensNode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
|
@ -45,11 +44,6 @@ public:
|
|||
INLINE CollisionRay(const CollisionRay ©);
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include "collisionSolid.h"
|
||||
|
||||
class LensNode;
|
||||
class qpLensNode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
|
@ -48,11 +47,6 @@ public:
|
|||
INLINE CollisionSegment(const CollisionSegment ©);
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -59,6 +59,5 @@ is_tangible() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionSolid::
|
||||
mark_viz_stale() {
|
||||
_viz_stale = true;
|
||||
_viz_geom_stale = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ©) :
|
|||
_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 ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -36,11 +36,6 @@ public:
|
|||
INLINE CollisionSphere(const CollisionSphere ©);
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "qpcollisionLevelState.h"
|
||||
#include "collisionSolid.h"
|
||||
#include "dcast.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCollisionLevelState::clear
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "collisionNode.h"
|
||||
#include "qpcollisionNode.h"
|
||||
#include "config_collide.h"
|
||||
|
||||
#include "qpgeomNode.h"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
Loading…
Reference in New Issue