mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
more refinements
This commit is contained in:
parent
7feba65c50
commit
1ac667d4c6
@ -8,32 +8,40 @@
|
||||
#define SOURCES \
|
||||
colorAttrib.h colorAttrib.I \
|
||||
config_pgraph.h \
|
||||
cullHandler.h \
|
||||
qpcullTraverser.h qpcullTraverser.I \
|
||||
cycleData.h cycleData.I \
|
||||
cycleDataReader.h cycleDataReader.I \
|
||||
cycleDataWriter.h cycleDataWriter.I \
|
||||
qpgeomNode.h qpgeomNode.I \
|
||||
pandaNode.h pandaNode.I \
|
||||
pipeline.h pipeline.I \
|
||||
pipelineCycler.h pipelineCycler.I \
|
||||
pipelineCyclerBase.h pipelineCyclerBase.I \
|
||||
renderAttrib.h renderAttrib.I \
|
||||
renderState.h renderState.I \
|
||||
textureAttrib.h textureAttrib.I
|
||||
textureAttrib.h textureAttrib.I \
|
||||
transformAttrib.h transformAttrib.I
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
// #define SOURCES $[SOURCES] \
|
||||
#define INCLUDED_SOURCES \
|
||||
// #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
// #define INCLUDED_SOURCES \
|
||||
#define SOURCES $[SOURCES] \
|
||||
colorAttrib.cxx \
|
||||
config_pgraph.cxx \
|
||||
cullHandler.cxx \
|
||||
qpcullTraverser.cxx \
|
||||
cycleData.cxx \
|
||||
cycleDataReader.cxx \
|
||||
cycleDataWriter.cxx \
|
||||
qpgeomNode.cxx \
|
||||
pandaNode.cxx \
|
||||
pipeline.cxx \
|
||||
pipelineCycler.cxx \
|
||||
pipelineCyclerBase.cxx \
|
||||
renderAttrib.cxx \
|
||||
renderState.cxx \
|
||||
textureAttrib.cxx
|
||||
textureAttrib.cxx \
|
||||
transformAttrib.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
pandaNode.h pandaNode.I
|
||||
|
@ -18,6 +18,10 @@
|
||||
|
||||
#include "colorAttrib.h"
|
||||
#include "dcast.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
TypeHandle ColorAttrib::_type_handle;
|
||||
|
||||
@ -30,7 +34,7 @@ TypeHandle ColorAttrib::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ColorAttrib::
|
||||
make_vertex() {
|
||||
ColorAttrib *attrib = new ColorAttrib(T_vertex, Colorf(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
ColorAttrib *attrib = new ColorAttrib(T_vertex);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
@ -55,7 +59,7 @@ make_flat(const Colorf &color) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ColorAttrib::
|
||||
make_off() {
|
||||
ColorAttrib *attrib = new ColorAttrib(T_off, Colorf(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
ColorAttrib *attrib = new ColorAttrib(T_off);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
@ -123,5 +127,59 @@ compare_to_impl(const RenderAttrib *other) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderAttrib *ColorAttrib::
|
||||
make_default_impl() const {
|
||||
return new ColorAttrib(T_vertex, Colorf(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
return new ColorAttrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColorAttrib::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// ColorAttrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ColorAttrib::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColorAttrib::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ColorAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColorAttrib::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type ColorAttrib is encountered
|
||||
// in the Bam file. It should create the ColorAttrib
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *ColorAttrib::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
ColorAttrib *attrib = new ColorAttrib;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return new_from_bam(attrib, manager);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColorAttrib::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new ColorAttrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ColorAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ PUBLISHED:
|
||||
};
|
||||
|
||||
private:
|
||||
INLINE ColorAttrib(Type type, const Colorf &color);
|
||||
INLINE ColorAttrib(Type type = T_vertex,
|
||||
const Colorf &color = Colorf(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
PUBLISHED:
|
||||
static CPT(RenderAttrib) make_vertex();
|
||||
@ -56,15 +57,23 @@ protected:
|
||||
private:
|
||||
Type _type;
|
||||
Colorf _color;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedWritableReferenceCount::init_type();
|
||||
RenderAttrib::init_type();
|
||||
register_type(_type_handle, "ColorAttrib",
|
||||
TypedWritableReferenceCount::get_class_type());
|
||||
RenderAttrib::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
@ -19,10 +19,12 @@
|
||||
#include "config_pgraph.h"
|
||||
|
||||
#include "colorAttrib.h"
|
||||
#include "qpgeomNode.h"
|
||||
#include "pandaNode.h"
|
||||
#include "renderAttrib.h"
|
||||
#include "renderState.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "transformAttrib.h"
|
||||
|
||||
#include "dconfig.h"
|
||||
|
||||
@ -51,11 +53,17 @@ init_libpgraph() {
|
||||
initialized = true;
|
||||
|
||||
ColorAttrib::init_type();
|
||||
qpGeomNode::init_type();
|
||||
PandaNode::init_type();
|
||||
RenderAttrib::init_type();
|
||||
RenderState::init_type();
|
||||
TextureAttrib::init_type();
|
||||
TransformAttrib::init_type();
|
||||
|
||||
ColorAttrib::register_with_read_factory();
|
||||
qpGeomNode::register_with_read_factory();
|
||||
PandaNode::register_with_read_factory();
|
||||
RenderState::register_with_read_factory();
|
||||
TextureAttrib::register_with_read_factory();
|
||||
TransformAttrib::register_with_read_factory();
|
||||
}
|
||||
|
36
panda/src/pgraph/cullHandler.cxx
Normal file
36
panda/src/pgraph/cullHandler.cxx
Normal file
@ -0,0 +1,36 @@
|
||||
// Filename: cullHandler.cxx
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "cullHandler.h"
|
||||
#include "geom.h"
|
||||
#include "renderState.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullHandler::found_geom
|
||||
// Access: Public, Virtual
|
||||
// Description: This callback function is intended to be overridden
|
||||
// by a derived class. This is called as each Geom is
|
||||
// discovered by the CullTraverser.
|
||||
//
|
||||
// This default method simply outputs a message to cerr;
|
||||
// it's not intended to be used except for debugging.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullHandler::
|
||||
found_geom(Geom *geom, const RenderState *state) {
|
||||
cerr << *geom << " " << *state << "\n";
|
||||
}
|
42
panda/src/pgraph/cullHandler.h
Normal file
42
panda/src/pgraph/cullHandler.h
Normal file
@ -0,0 +1,42 @@
|
||||
// Filename: cullHandler.h
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 CULLHANDLER_H
|
||||
#define CULLHANDLER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
class Geom;
|
||||
class RenderState;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CullHandler
|
||||
// Description : This defines the abstract interface for an object
|
||||
// that receives Geoms identified by the CullTraverser.
|
||||
// By itself, it's not a particularly useful class; to
|
||||
// use it, derive from it and redefine found_geom().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA CullHandler {
|
||||
public:
|
||||
virtual void found_geom(Geom *geom, const RenderState *state);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -51,9 +51,6 @@ private:
|
||||
const CycleDataType *_pointer;
|
||||
};
|
||||
|
||||
// This abbreviation macro is used for ease of typing.
|
||||
#define CDR(type) CycleDataReader< type >
|
||||
|
||||
#include "cycleDataReader.I"
|
||||
|
||||
#endif
|
||||
|
@ -52,8 +52,6 @@ private:
|
||||
CycleDataType *_pointer;
|
||||
};
|
||||
|
||||
#define CDW(type) CycleDataWriter< type >
|
||||
|
||||
#include "cycleDataWriter.I"
|
||||
|
||||
#endif
|
||||
|
@ -78,8 +78,8 @@ CData() {
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Children::
|
||||
Children(const PipelineCycler<PandaNode::CData> &cycler) :
|
||||
_cdata(cycler)
|
||||
Children(const PandaNode::CDReader &cdata) :
|
||||
_cdata(cdata)
|
||||
{
|
||||
}
|
||||
|
||||
@ -115,17 +115,6 @@ get_child(int n) const {
|
||||
return _cdata->_down[n].get_child();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::
|
||||
PandaNode(const string &name) :
|
||||
Namable(name)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_num_parents
|
||||
// Access: Published
|
||||
@ -137,7 +126,7 @@ PandaNode(const string &name) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::
|
||||
get_num_parents() const {
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_up.size();
|
||||
}
|
||||
|
||||
@ -149,7 +138,7 @@ get_num_parents() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::
|
||||
get_parent(int n) const {
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(n >= 0 && n < (int)cdata->_up.size(), NULL);
|
||||
return cdata->_up[n];
|
||||
}
|
||||
@ -162,7 +151,7 @@ get_parent(int n) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::
|
||||
find_parent(PandaNode *node) const {
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
Up::const_iterator ui = cdata->_up.find(node);
|
||||
if (ui == cdata->_up.end()) {
|
||||
return -1;
|
||||
@ -180,7 +169,7 @@ find_parent(PandaNode *node) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::
|
||||
get_num_children() const {
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_down.size();
|
||||
}
|
||||
|
||||
@ -192,7 +181,7 @@ get_num_children() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::
|
||||
get_child(int n) const {
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(n >= 0 && n < (int)cdata->_down.size(), NULL);
|
||||
return cdata->_down[n].get_child();
|
||||
}
|
||||
@ -206,7 +195,7 @@ get_child(int n) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::
|
||||
get_sort(int n) const {
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(n >= 0 && n < (int)cdata->_down.size(), -1);
|
||||
return cdata->_down[n].get_sort();
|
||||
}
|
||||
@ -222,7 +211,7 @@ get_sort(int n) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
set_attrib(const RenderAttrib *attrib, int override) {
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_state_changes = cdata->_state_changes->add(attrib, override);
|
||||
}
|
||||
|
||||
@ -237,7 +226,7 @@ set_attrib(const RenderAttrib *attrib, int override) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const RenderAttrib *PandaNode::
|
||||
get_attrib(TypeHandle type) const {
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
int index = cdata->_state_changes->find_attrib(type);
|
||||
if (index >= 0) {
|
||||
return cdata->_state_changes->get_attrib(index);
|
||||
@ -255,7 +244,7 @@ get_attrib(TypeHandle type) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
clear_attrib(TypeHandle type) {
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_state_changes = cdata->_state_changes->remove(type);
|
||||
}
|
||||
|
||||
@ -271,7 +260,7 @@ clear_attrib(TypeHandle type) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
set_state(const RenderState *state) {
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_state_changes = state;
|
||||
}
|
||||
|
||||
@ -286,7 +275,7 @@ set_state(const RenderState *state) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const RenderState *PandaNode::
|
||||
get_state() const {
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_state_changes;
|
||||
}
|
||||
|
||||
@ -300,7 +289,7 @@ get_state() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
clear_state() {
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_state_changes = RenderState::make_empty();
|
||||
}
|
||||
|
||||
@ -320,6 +309,7 @@ clear_state() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Children PandaNode::
|
||||
get_children() const {
|
||||
return Children(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
return Children(cdata);
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,17 @@ make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode::
|
||||
PandaNode(const string &name) :
|
||||
Namable(name)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Copy Constructor
|
||||
// Access: Published
|
||||
@ -64,8 +75,8 @@ PandaNode(const PandaNode ©) :
|
||||
// Copying a node does not copy its children.
|
||||
|
||||
// Copy the other node's bounding volume.
|
||||
CDR(CData) copy_cdata(copy._cycler);
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDReader copy_cdata(copy._cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_node_bounds = copy_cdata->_node_bounds;
|
||||
}
|
||||
|
||||
@ -81,8 +92,8 @@ operator = (const PandaNode ©) {
|
||||
ReferenceCount::operator = (copy);
|
||||
|
||||
// Copy the other node's bounding volume.
|
||||
CDR(CData) copy_cdata(copy._cycler);
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDReader copy_cdata(copy._cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_node_bounds = copy_cdata->_node_bounds;
|
||||
}
|
||||
|
||||
@ -95,7 +106,7 @@ PandaNode::
|
||||
~PandaNode() {
|
||||
// We shouldn't have any parents left by the time we destruct, or
|
||||
// there's a refcount fault somewhere.
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
nassertv(cdata->_up.empty());
|
||||
|
||||
remove_all_children();
|
||||
@ -109,7 +120,7 @@ PandaNode::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PandaNode::
|
||||
find_child(PandaNode *node) const {
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
// We have to search for the child by brute force, since we don't
|
||||
// know what sort index it was added as.
|
||||
@ -139,8 +150,8 @@ find_child(PandaNode *node) const {
|
||||
int PandaNode::
|
||||
add_child(PandaNode *child, int sort) {
|
||||
remove_child(child);
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDW(CData) cdata_child(child->_cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
CDWriter cdata_child(child->_cycler);
|
||||
|
||||
Down::iterator ci = cdata->_down.insert(DownConnection(child, sort));
|
||||
cdata_child->_up.insert(this);
|
||||
@ -155,11 +166,11 @@ add_child(PandaNode *child, int sort) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
remove_child(int n) {
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(n >= 0 && n < (int)cdata->_down.size());
|
||||
|
||||
PandaNode *child = cdata->_down[n].get_child();
|
||||
CDW(CData) cdata_child(child->_cycler);
|
||||
CDWriter cdata_child(child->_cycler);
|
||||
|
||||
cdata->_down.erase(cdata->_down.begin() + n);
|
||||
int num_erased = cdata_child->_up.erase(this);
|
||||
@ -175,7 +186,7 @@ remove_child(int n) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PandaNode::
|
||||
remove_child(PandaNode *child) {
|
||||
CDW(CData) cdata_child(child->_cycler);
|
||||
CDWriter cdata_child(child->_cycler);
|
||||
|
||||
// First, look for and remove this node from the child's parent
|
||||
// list.
|
||||
@ -185,7 +196,7 @@ remove_child(PandaNode *child) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
// Now, look for and remove the child node from our down list.
|
||||
Down::iterator ci;
|
||||
@ -208,11 +219,11 @@ remove_child(PandaNode *child) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
remove_all_children() {
|
||||
CDW(CData) cdata(_cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
Down::iterator ci;
|
||||
for (ci = cdata->_down.begin(); ci != cdata->_down.end(); ++ci) {
|
||||
PandaNode *child = (*ci).get_child();
|
||||
CDW(CData) child_cdata(child->_cycler);
|
||||
CDWriter child_cdata(child->_cycler);
|
||||
child_cdata->_up.erase(this);
|
||||
}
|
||||
}
|
||||
@ -235,13 +246,29 @@ output(ostream &out) const {
|
||||
void PandaNode::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level) << *this;
|
||||
CDR(CData) cdata(_cycler);
|
||||
CDReader cdata(_cycler);
|
||||
if (!cdata->_state_changes->is_empty()) {
|
||||
out << " (" << *cdata->_state_changes << ")";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::is_geom_node
|
||||
// Access: Public, Virtual
|
||||
// Description: A simple downcast check. Returns true if this kind
|
||||
// of node happens to inherit from GeomNode, false
|
||||
// otherwise.
|
||||
//
|
||||
// This is provided as a a faster alternative to calling
|
||||
// is_of_type(GeomNode::get_class_type()), since this
|
||||
// test is so important to rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PandaNode::
|
||||
is_geom_node() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
@ -41,10 +41,10 @@
|
||||
// is the base class of all specialized nodes, and also
|
||||
// serves as a generic node with no special properties.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PandaNode : public TypedWritable,
|
||||
public Namable, virtual public ReferenceCount {
|
||||
class EXPCL_PANDA PandaNode : public TypedWritable, public Namable,
|
||||
virtual public ReferenceCount {
|
||||
PUBLISHED:
|
||||
INLINE PandaNode(const string &name);
|
||||
PandaNode(const string &name);
|
||||
PandaNode(const PandaNode ©);
|
||||
void operator = (const PandaNode ©);
|
||||
virtual ~PandaNode();
|
||||
@ -75,6 +75,9 @@ PUBLISHED:
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
public:
|
||||
virtual bool is_geom_node() const;
|
||||
|
||||
private:
|
||||
class EXPCL_PANDA DownConnection {
|
||||
public:
|
||||
@ -114,6 +117,8 @@ private:
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
typedef CycleDataReader<CData> CDReader;
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
|
||||
public:
|
||||
// Use this interface when you want to walk through the list of
|
||||
@ -122,14 +127,14 @@ public:
|
||||
// However, it does not protect you from self-modifying loops.
|
||||
class EXPCL_PANDA Children {
|
||||
public:
|
||||
INLINE Children(const PipelineCycler<CData> &cycler);
|
||||
INLINE Children(const CDReader &cdata);
|
||||
INLINE Children(const Children ©);
|
||||
|
||||
INLINE int get_num_children() const;
|
||||
INLINE PandaNode *get_child(int n) const;
|
||||
|
||||
private:
|
||||
CDR(CData) _cdata;
|
||||
CDReader _cdata;
|
||||
};
|
||||
|
||||
INLINE Children get_children() const;
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "colorAttrib.cxx"
|
||||
#include "config_pgraph.cxx"
|
||||
#include "cycleData.cxx"
|
||||
#include "cycleDataReader.cxx"
|
||||
#include "cycleDataWriter.cxx"
|
||||
#include "pandaNode.cxx"
|
||||
#include "colorAttrib.cxx"
|
||||
#include "config_pgraph.cxx"
|
||||
#include "cullHandler.cxx"
|
||||
#include "qpcullTraverser.cxx"
|
||||
#include "cycleData.cxx"
|
||||
#include "cycleDataReader.cxx"
|
||||
#include "cycleDataWriter.cxx"
|
||||
#include "qpgeomNode.cxx"
|
||||
#include "pandaNode.cxx"
|
||||
|
@ -1,8 +1,9 @@
|
||||
#include "pipeline.cxx"
|
||||
#include "pipelineCycler.cxx"
|
||||
#include "pipelineCyclerBase.cxx"
|
||||
#include "renderAttrib.cxx"
|
||||
#include "renderState.cxx"
|
||||
#include "test_pgraph.cxx"
|
||||
#include "textureAttrib.cxx"
|
||||
|
||||
#include "pipeline.cxx"
|
||||
#include "pipelineCycler.cxx"
|
||||
#include "pipelineCyclerBase.cxx"
|
||||
#include "renderAttrib.cxx"
|
||||
#include "renderState.cxx"
|
||||
#include "test_pgraph.cxx"
|
||||
#include "textureAttrib.cxx"
|
||||
#include "transformAttrib.cxx"
|
||||
|
||||
|
17
panda/src/pgraph/qpcullTraverser.I
Normal file
17
panda/src/pgraph/qpcullTraverser.I
Normal file
@ -0,0 +1,17 @@
|
||||
// Filename: qpcullTraverser.I
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
117
panda/src/pgraph/qpcullTraverser.cxx
Normal file
117
panda/src/pgraph/qpcullTraverser.cxx
Normal file
@ -0,0 +1,117 @@
|
||||
// Filename: qpcullTraverser.cxx
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpcullTraverser.h"
|
||||
#include "renderState.h"
|
||||
#include "cullHandler.h"
|
||||
#include "dcast.h"
|
||||
#include "qpgeomNode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCullTraverser::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpCullTraverser::
|
||||
qpCullTraverser() {
|
||||
_initial_state = RenderState::make_empty();
|
||||
_world_transform = DCAST(TransformAttrib, TransformAttrib::make_identity());
|
||||
_cull_handler = (CullHandler *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCullTraverser::set_initial_state
|
||||
// Access: Public
|
||||
// Description: Sets the initial RenderState at the top of the scene
|
||||
// graph we are traversing. If this is not set, the
|
||||
// default is the empty state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpCullTraverser::
|
||||
set_initial_state(const RenderState *initial_state) {
|
||||
_initial_state = initial_state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCullTraverser::set_world_transform
|
||||
// Access: Public
|
||||
// Description: Specifies the net inverse transform of the camera
|
||||
// viewing the scene. Normally, this is the same as the
|
||||
// transform specified in the initial state, but it
|
||||
// might be different if we are culling a subgraph,
|
||||
// for instance.
|
||||
//
|
||||
// This is used to evaluate camera-dependent attributes
|
||||
// like billboards and LOD nodes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpCullTraverser::
|
||||
set_world_transform(const TransformAttrib *world_transform) {
|
||||
_world_transform = world_transform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCullTraverser::set_cull_handler
|
||||
// Access: Public
|
||||
// Description: Specifies the object that will receive the culled
|
||||
// Geoms. This must be called before traverse().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpCullTraverser::
|
||||
set_cull_handler(CullHandler *cull_handler) {
|
||||
_cull_handler = cull_handler;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCullTraverser::traverse
|
||||
// Access: Public
|
||||
// Description: Begins the traversal from the indicated node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpCullTraverser::
|
||||
traverse(PandaNode *root) {
|
||||
nassertv(_cull_handler != (CullHandler *)NULL);
|
||||
|
||||
r_traverse(root, _initial_state, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpCullTraverser::r_traverse
|
||||
// Access: Private
|
||||
// Description: The recursive traversal implementation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpCullTraverser::
|
||||
r_traverse(PandaNode *node, const RenderState *state, int flags) {
|
||||
CPT(RenderState) next_state = state->compose(node->get_state());
|
||||
|
||||
if (node->is_geom_node()) {
|
||||
qpGeomNode *geom_node;
|
||||
DCAST_INTO_V(geom_node, node);
|
||||
|
||||
int num_geoms = geom_node->get_num_geoms();
|
||||
for (int i = 0; i < num_geoms; i++) {
|
||||
Geom *geom = geom_node->get_geom(i);
|
||||
CPT(RenderState) geom_state =
|
||||
next_state->compose(geom_node->get_geom_state(i));
|
||||
_cull_handler->found_geom(geom, geom_state);
|
||||
}
|
||||
}
|
||||
|
||||
// Now visit all the node's children.
|
||||
PandaNode::Children cr = node->get_children();
|
||||
int num_children = cr.get_num_children();
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
r_traverse(cr.get_child(i), next_state, flags);
|
||||
}
|
||||
}
|
62
panda/src/pgraph/qpcullTraverser.h
Normal file
62
panda/src/pgraph/qpcullTraverser.h
Normal file
@ -0,0 +1,62 @@
|
||||
// Filename: qpcullTraverser.h
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpCULLTRAVERSER_H
|
||||
#define qpCULLTRAVERSER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "renderState.h"
|
||||
#include "transformAttrib.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
class PandaNode;
|
||||
class CullHandler;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CullTraverser
|
||||
// Description : This object performs a depth-first traversal of the
|
||||
// scene graph, with optional view-frustum culling,
|
||||
// collecting CullState and searching for GeomNodes.
|
||||
// Each renderable Geom encountered is passed along with
|
||||
// its associated RenderState to the CullHandler object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpCullTraverser {
|
||||
public:
|
||||
qpCullTraverser();
|
||||
|
||||
void set_initial_state(const RenderState *initial_state);
|
||||
void set_world_transform(const TransformAttrib *world_transform);
|
||||
void set_cull_handler(CullHandler *cull_handler);
|
||||
|
||||
void traverse(PandaNode *root);
|
||||
|
||||
private:
|
||||
void r_traverse(PandaNode *node, const RenderState *state, int flags);
|
||||
|
||||
CPT(RenderState) _initial_state;
|
||||
CPT(TransformAttrib) _world_transform;
|
||||
CullHandler *_cull_handler;
|
||||
};
|
||||
|
||||
#include "qpcullTraverser.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
140
panda/src/pgraph/qpgeomNode.I
Normal file
140
panda/src/pgraph/qpgeomNode.I
Normal file
@ -0,0 +1,140 @@
|
||||
// Filename: qpgeomNode.I
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: qpGeomNode::GeomEntry::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomNode::GeomEntry::
|
||||
GeomEntry(Geom *geom, const RenderState *state) :
|
||||
_geom(geom),
|
||||
_state(state)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomNode::CData::
|
||||
CData() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::get_num_geoms
|
||||
// Access: Public
|
||||
// Description: Returns the number of geoms in the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomNode::
|
||||
get_num_geoms() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_geoms.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::get_geom
|
||||
// Access: Public
|
||||
// Description: Returns the nth geom of the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom *qpGeomNode::
|
||||
get_geom(int n) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(n >= 0 && n < (int)cdata->_geoms.size(), NULL);
|
||||
return cdata->_geoms[n]._geom;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::get_geom_state
|
||||
// Access: Public
|
||||
// Description: Returns the RenderState associated with the nth geom
|
||||
// of the node. This is just the RenderState directly
|
||||
// associated with the Geom; the actual state in which
|
||||
// the Geom is rendered will also be affected by
|
||||
// RenderStates that appear on the scene graph in nodes
|
||||
// above this GeomNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const RenderState *qpGeomNode::
|
||||
get_geom_state(int n) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(n >= 0 && n < (int)cdata->_geoms.size(), NULL);
|
||||
return cdata->_geoms[n]._state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::set_state
|
||||
// Access: Public
|
||||
// Description: Changes the RenderState associated with the nth geom
|
||||
// of the node. This is just the RenderState directly
|
||||
// associated with the Geom; the actual state in which
|
||||
// the Geom is rendered will also be affected by
|
||||
// RenderStates that appear on the scene graph in nodes
|
||||
// above this GeomNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomNode::
|
||||
set_state(int n, const RenderState *state) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(n >= 0 && n < (int)cdata->_geoms.size());
|
||||
cdata->_geoms[n]._state = state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::add_geom
|
||||
// Access: Published
|
||||
// Description: Adds a new Geom to the node. The geom is given the
|
||||
// indicated state (which may be
|
||||
// RenderState::make_empty(), to completely inherit its
|
||||
// state from the scene graph).
|
||||
//
|
||||
// The return value is the index number of the new Geom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomNode::
|
||||
add_geom(Geom *geom, const RenderState *state) {
|
||||
nassertr(geom != (Geom *)NULL, -1);
|
||||
nassertr(state != (RenderState *)NULL, -1);
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
cdata->_geoms.push_back(GeomEntry(geom, state));
|
||||
return cdata->_geoms.size() - 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::remove_geom
|
||||
// Access: Published
|
||||
// Description: Removes the nth geom from the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomNode::
|
||||
remove_geom(int n) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(n >= 0 && n < (int)cdata->_geoms.size());
|
||||
|
||||
cdata->_geoms.erase(cdata->_geoms.begin() + n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::remove_all_geoms
|
||||
// Access: Published
|
||||
// Description: Removes all the geoms from the node at once.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomNode::
|
||||
remove_all_geoms() {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_geoms.clear();
|
||||
}
|
214
panda/src/pgraph/qpgeomNode.cxx
Normal file
214
panda/src/pgraph/qpgeomNode.cxx
Normal file
@ -0,0 +1,214 @@
|
||||
// Filename: qpgeomNode.cxx
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomNode.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle qpGeomNode::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::CData::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomNode::CData::
|
||||
CData(const qpGeomNode::CData ©) :
|
||||
_geoms(copy._geoms)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *qpGeomNode::CData::
|
||||
make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomNode::
|
||||
qpGeomNode(const string &name) :
|
||||
PandaNode(name)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomNode::
|
||||
qpGeomNode(const qpGeomNode ©) :
|
||||
PandaNode(copy)
|
||||
{
|
||||
// Copy the other node's _geoms.
|
||||
CDReader copy_cdata(copy._cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_geoms = copy_cdata->_geoms;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomNode::
|
||||
operator = (const qpGeomNode ©) {
|
||||
PandaNode::operator = (copy);
|
||||
|
||||
// Copy the other node's _geoms.
|
||||
CDReader copy_cdata(copy._cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_geoms = copy_cdata->_geoms;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomNode::
|
||||
~qpGeomNode() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::write_verbose
|
||||
// Access: Published
|
||||
// Description: Writes a detailed description of all the Geoms in the
|
||||
// node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomNode::
|
||||
write_verbose(ostream &out, int indent_level) const {
|
||||
CDReader cdata(_cycler);
|
||||
PandaNode::write(out, indent_level);
|
||||
Geoms::const_iterator gi;
|
||||
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||
const GeomEntry &entry = (*gi);
|
||||
indent(out, indent_level + 2)
|
||||
<< *entry._geom << " (" << *entry._state << ")\n";
|
||||
entry._geom->write_verbose(out, indent_level + 4);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::output
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomNode::
|
||||
output(ostream &out) const {
|
||||
PandaNode::output(out);
|
||||
out << " (" << get_num_geoms() << " geoms)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::write
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomNode::
|
||||
write(ostream &out, int indent_level) const {
|
||||
CDReader cdata(_cycler);
|
||||
PandaNode::write(out, indent_level);
|
||||
Geoms::const_iterator gi;
|
||||
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||
const GeomEntry &entry = (*gi);
|
||||
indent(out, indent_level + 2)
|
||||
<< *entry._geom << " (" << *entry._state << ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::is_geom_node
|
||||
// Access: Public, Virtual
|
||||
// Description: A simple downcast check. Returns true if this kind
|
||||
// of node happens to inherit from GeomNode, false
|
||||
// otherwise.
|
||||
//
|
||||
// This is provided as a a faster alternative to calling
|
||||
// is_of_type(GeomNode::get_class_type()), since this
|
||||
// test is so important to rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomNode::
|
||||
is_geom_node() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// qpGeomNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomNode::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomNode::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
PandaNode::write_datagram(manager, dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type qpGeomNode is encountered
|
||||
// in the Bam file. It should create the qpGeomNode
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomNode::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomNode *node = new qpGeomNode("");
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
node->fillin(scan, manager);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new qpGeomNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomNode::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
PandaNode::fillin(scan, manager);
|
||||
}
|
118
panda/src/pgraph/qpgeomNode.h
Normal file
118
panda/src/pgraph/qpgeomNode.h
Normal file
@ -0,0 +1,118 @@
|
||||
// Filename: qpgeomNode.h
|
||||
// Created by: drose (22Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMNODE_H
|
||||
#define qpGEOMNODE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "pandaNode.h"
|
||||
#include "pointerToArray.h"
|
||||
#include "geom.h"
|
||||
#include "pipelineCycler.h"
|
||||
#include "cycleData.h"
|
||||
#include "pvector.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomNode
|
||||
// Description : A node that holds Geom objects, renderable pieces of
|
||||
// geometry. This is the primary kind of leaf node in
|
||||
// the scene graph; almost all visible objects will be
|
||||
// contained in a GeomNode somewhere.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomNode : public PandaNode {
|
||||
PUBLISHED:
|
||||
qpGeomNode(const string &name);
|
||||
|
||||
public:
|
||||
qpGeomNode(const qpGeomNode ©);
|
||||
void operator = (const qpGeomNode ©);
|
||||
virtual ~qpGeomNode();
|
||||
|
||||
PUBLISHED:
|
||||
INLINE int get_num_geoms() const;
|
||||
INLINE Geom *get_geom(int n) const;
|
||||
INLINE const RenderState *get_geom_state(int n) const;
|
||||
INLINE void set_state(int n, const RenderState *state);
|
||||
|
||||
INLINE int add_geom(Geom *geom, const RenderState *state);
|
||||
INLINE void remove_geom(int n);
|
||||
INLINE void remove_all_geoms();
|
||||
|
||||
void write_verbose(ostream &out, int indent_level) const;
|
||||
|
||||
public:
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
virtual bool is_geom_node() const;
|
||||
|
||||
private:
|
||||
class GeomEntry {
|
||||
public:
|
||||
INLINE GeomEntry(Geom *geom, const RenderState *state);
|
||||
PT(Geom) _geom;
|
||||
CPT(RenderState) _state;
|
||||
};
|
||||
typedef pvector<GeomEntry> Geoms;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
INLINE CData();
|
||||
CData(const CData ©);
|
||||
virtual CycleData *make_copy() const;
|
||||
|
||||
Geoms _geoms;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
typedef CycleDataReader<CData> CDReader;
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
PandaNode::init_type();
|
||||
register_type(_type_handle, "qpGeomNode",
|
||||
PandaNode::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 PandaNode::Children;
|
||||
};
|
||||
|
||||
#include "qpgeomNode.I"
|
||||
|
||||
#endif
|
@ -160,7 +160,7 @@ compare_to_impl(const RenderAttrib *other) const {
|
||||
// RenderAttrib (that is, a subsequent RenderAttrib
|
||||
// completely replaces the preceding one). On the other
|
||||
// hand, some kinds of RenderAttrib (for instance,
|
||||
// TextureTransform) might combine in meaningful ways.
|
||||
// TransformAttrib) might combine in meaningful ways.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) RenderAttrib::
|
||||
compose_impl(const RenderAttrib *other) const {
|
||||
@ -238,3 +238,14 @@ new_from_bam(RenderAttrib *attrib, BamReader *manager) {
|
||||
// reader expects that.
|
||||
return (RenderAttrib *)pointer.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new RenderAttrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ public:
|
||||
|
||||
protected:
|
||||
static TypedWritable *new_from_bam(RenderAttrib *attrib, BamReader *manager);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -272,6 +272,14 @@ compose(const RenderState *other) const {
|
||||
|
||||
cerr << "composing " << *this << " with " << *other << "\n";
|
||||
|
||||
// We handle empty state (identity) as a trivial special case.
|
||||
if (is_empty()) {
|
||||
return other;
|
||||
}
|
||||
if (other->is_empty()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (other == this) {
|
||||
// compose(this) has to be handled as a special case, because the
|
||||
// caching problem is so different.
|
||||
|
@ -19,7 +19,13 @@
|
||||
#include "pandaNode.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "transformAttrib.h"
|
||||
#include "texture.h"
|
||||
#include "qpgeomNode.h"
|
||||
#include "geomTristrip.h"
|
||||
#include "geomTrifan.h"
|
||||
#include "qpcullTraverser.h"
|
||||
#include "cullHandler.h"
|
||||
|
||||
void
|
||||
list_hierarchy(PandaNode *node, int indent_level) {
|
||||
@ -51,32 +57,31 @@ main(int argc, char *argv[]) {
|
||||
PandaNode *a1 = new PandaNode("a1");
|
||||
a->add_child(a1);
|
||||
|
||||
qpGeomNode *g1 = new qpGeomNode("g1");
|
||||
a1->add_child(g1);
|
||||
|
||||
Geom *geom1 = new GeomTristrip;
|
||||
g1->add_geom(geom1, RenderState::make_empty());
|
||||
Geom *geom2 = new GeomTrifan;
|
||||
g1->add_geom(geom2, b->get_state());
|
||||
|
||||
qpGeomNode *g2 = new qpGeomNode("g2");
|
||||
b->add_child(g2);
|
||||
g2->add_geom(geom1, b->get_state());
|
||||
g2->set_attrib(TransformAttrib::make_mat(LMatrix4f::translate_mat(10, 0, 0)));
|
||||
|
||||
cerr << "\n";
|
||||
list_hierarchy(root, 0);
|
||||
|
||||
cerr << "\nroot's attribs:\n";
|
||||
root->get_state()->write(cerr, 0);
|
||||
qpCullTraverser trav;
|
||||
CullHandler cull_handler;
|
||||
trav.set_cull_handler(&cull_handler);
|
||||
cerr << "\n";
|
||||
trav.traverse(root);
|
||||
|
||||
cerr << "\na's attribs:\n";
|
||||
a->get_state()->write(cerr, 0);
|
||||
|
||||
cerr << "\nroot compose a:\n";
|
||||
CPT(RenderState) result1 = root->get_state()->compose(a->get_state());
|
||||
result1->write(cerr, 0);
|
||||
|
||||
// a->clear_state();
|
||||
|
||||
cerr << "\nroot compose root:\n";
|
||||
CPT(RenderState) result2 = root->get_state()->compose(root->get_state());
|
||||
result2->write(cerr, 0);
|
||||
|
||||
cerr << "\nroot compose a:\n";
|
||||
CPT(RenderState) result3 = root->get_state()->compose(a->get_state());
|
||||
result3->write(cerr, 0);
|
||||
|
||||
cerr << "\na compose root:\n";
|
||||
CPT(RenderState) result4 = a->get_state()->compose(root->get_state());
|
||||
result4->write(cerr, 0);
|
||||
cerr << "\n";
|
||||
trav.traverse(root);
|
||||
|
||||
cerr << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "textureAttrib.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
TypeHandle TextureAttrib::_type_handle;
|
||||
|
||||
@ -97,3 +101,57 @@ RenderAttrib *TextureAttrib::
|
||||
make_default_impl() const {
|
||||
return new TextureAttrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureAttrib::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// TextureAttrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureAttrib::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureAttrib::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureAttrib::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type TextureAttrib is encountered
|
||||
// in the Bam file. It should create the TextureAttrib
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *TextureAttrib::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
TextureAttrib *attrib = new TextureAttrib;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return new_from_bam(attrib, manager);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureAttrib::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new TextureAttrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
}
|
||||
|
@ -50,15 +50,23 @@ protected:
|
||||
|
||||
private:
|
||||
PT(Texture) _texture;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedWritableReferenceCount::init_type();
|
||||
RenderAttrib::init_type();
|
||||
register_type(_type_handle, "TextureAttrib",
|
||||
TypedWritableReferenceCount::get_class_type());
|
||||
RenderAttrib::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
172
panda/src/pgraph/transformAttrib.I
Normal file
172
panda/src/pgraph/transformAttrib.I
Normal file
@ -0,0 +1,172 @@
|
||||
// Filename: transformAttrib.I
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: TransformAttrib::Constructor
|
||||
// Access: Private
|
||||
// Description: Use TransformAttrib::make() to construct a new
|
||||
// TransformAttrib object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TransformAttrib::
|
||||
TransformAttrib() {
|
||||
_flags = F_is_identity | F_singular_known;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::is_identity
|
||||
// Access: Published
|
||||
// Description: Returns true if the transform represents the identity
|
||||
// matrix, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TransformAttrib::
|
||||
is_identity() const {
|
||||
return ((_flags & F_is_identity) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::is_singular
|
||||
// Access: Published
|
||||
// Description: Returns true if the transform represents a singular
|
||||
// transform (that is, it has a zero scale, and it
|
||||
// cannot be inverted), or false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TransformAttrib::
|
||||
is_singular() const {
|
||||
check_singular();
|
||||
return ((_flags & F_is_singular) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::has_components
|
||||
// Access: Published
|
||||
// Description: Returns true if the transform can be described by
|
||||
// separate pos, hpr, and scale components. Most
|
||||
// transforms we use in everyday life can be so
|
||||
// described, but some kinds of transforms (for
|
||||
// instance, those involving a skew) cannot.
|
||||
//
|
||||
// This is not related to whether the transform was
|
||||
// originally described componentwise. Even a transform
|
||||
// that was constructed with a 4x4 may return true here
|
||||
// if the matrix is a simple affine matrix with no skew.
|
||||
//
|
||||
// If this returns true, you may safely call get_pos(),
|
||||
// etc., to retrieve the components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TransformAttrib::
|
||||
has_components() const {
|
||||
check_components();
|
||||
return ((_flags & F_has_components) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::get_pos
|
||||
// Access: Published
|
||||
// Description: Returns the pos component of the transform. It is an
|
||||
// error to call this if has_components() returned
|
||||
// false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVecBase3f &TransformAttrib::
|
||||
get_pos() const {
|
||||
check_components();
|
||||
nassertr(has_components(), _pos);
|
||||
return _pos;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::get_hpr
|
||||
// Access: Published
|
||||
// Description: Returns the hpr component of the transform. It is an
|
||||
// error to call this if has_components() returned
|
||||
// false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVecBase3f &TransformAttrib::
|
||||
get_hpr() const {
|
||||
check_components();
|
||||
nassertr(has_components(), _hpr);
|
||||
return _hpr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::get_scale
|
||||
// Access: Published
|
||||
// Description: Returns the scale component of the transform. It is an
|
||||
// error to call this if has_components() returned
|
||||
// false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVecBase3f &TransformAttrib::
|
||||
get_scale() const {
|
||||
check_components();
|
||||
nassertr(has_components(), _scale);
|
||||
return _scale;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::get_mat
|
||||
// Access: Published
|
||||
// Description: Returns the matrix that describes the transform.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &TransformAttrib::
|
||||
get_mat() const {
|
||||
check_mat();
|
||||
return _mat;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::check_singular
|
||||
// Access: Private
|
||||
// Description: Ensures that we know whether the matrix is singular.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformAttrib::
|
||||
check_singular() const {
|
||||
// This pretends to be a const function, even though it's not,
|
||||
// because it only updates a transparent cache value.
|
||||
if ((_flags & F_singular_known) == 0) {
|
||||
((TransformAttrib *)this)->calc_singular();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::check_components
|
||||
// Access: Private
|
||||
// Description: Ensures that we know the components of the transform
|
||||
// (or that we know they cannot be derived).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformAttrib::
|
||||
check_components() const {
|
||||
// This pretends to be a const function, even though it's not,
|
||||
// because it only updates a transparent cache value.
|
||||
if ((_flags & F_components_known) == 0) {
|
||||
((TransformAttrib *)this)->calc_components();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::check_mat
|
||||
// Access: Private
|
||||
// Description: Ensures that we know the overall matrix.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TransformAttrib::
|
||||
check_mat() const {
|
||||
// This pretends to be a const function, even though it's not,
|
||||
// because it only updates a transparent cache value.
|
||||
if ((_flags & F_mat_known) == 0) {
|
||||
((TransformAttrib *)this)->calc_mat();
|
||||
}
|
||||
}
|
308
panda/src/pgraph/transformAttrib.cxx
Normal file
308
panda/src/pgraph/transformAttrib.cxx
Normal file
@ -0,0 +1,308 @@
|
||||
// Filename: transformAttrib.cxx
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "transformAttrib.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "compose_matrix.h"
|
||||
|
||||
TypeHandle TransformAttrib::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::make_identity
|
||||
// Access: Published, Static
|
||||
// Description: Constructs an identity transform.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) TransformAttrib::
|
||||
make_identity() {
|
||||
TransformAttrib *attrib = new TransformAttrib;
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::make_components
|
||||
// Access: Published, Static
|
||||
// Description: Makes a new TransformAttrib with the specified
|
||||
// components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) TransformAttrib::
|
||||
make_components(const LVecBase3f &pos, const LVecBase3f &hpr,
|
||||
const LVecBase3f &scale) {
|
||||
// Make a special-case check for the identity transform.
|
||||
if (pos == LVecBase3f(0.0f, 0.0f, 0.0f) &&
|
||||
hpr == LVecBase3f(0.0f, 0.0f, 0.0f) &&
|
||||
scale == LVecBase3f(1.0f, 1.0f, 1.0f)) {
|
||||
return make_identity();
|
||||
}
|
||||
|
||||
TransformAttrib *attrib = new TransformAttrib;
|
||||
attrib->_pos = pos;
|
||||
attrib->_hpr = hpr;
|
||||
attrib->_scale = scale;
|
||||
attrib->_flags = F_components_given | F_components_known | F_has_components;
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::make_components
|
||||
// Access: Published, Static
|
||||
// Description: Makes a new TransformAttrib with the specified
|
||||
// transformation matrix.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) TransformAttrib::
|
||||
make_mat(const LMatrix4f &mat) {
|
||||
// Make a special-case check for the identity matrix.
|
||||
if (mat == LMatrix4f::ident_mat()) {
|
||||
return make_identity();
|
||||
}
|
||||
|
||||
TransformAttrib *attrib = new TransformAttrib;
|
||||
attrib->_mat = mat;
|
||||
attrib->_flags = F_mat_known;
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::output
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformAttrib::
|
||||
output(ostream &out) const {
|
||||
out << get_type() << ":";
|
||||
if (is_identity()) {
|
||||
out << "(identity)";
|
||||
|
||||
} else if (has_components()) {
|
||||
out << "(";
|
||||
if (get_pos() != LVecBase3f(0.0f, 0.0f, 0.0f)) {
|
||||
out << "pos " << get_pos();
|
||||
}
|
||||
if (get_hpr() != LVecBase3f(0.0f, 0.0f, 0.0f)) {
|
||||
out << "hpr " << get_hpr();
|
||||
}
|
||||
if (get_scale() != LVecBase3f(1.0f, 1.0f, 1.0f)) {
|
||||
out << "scale " << get_scale();
|
||||
}
|
||||
out << ")";
|
||||
|
||||
} else {
|
||||
out << get_mat();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::compare_to_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Intended to be overridden by derived TransformAttrib
|
||||
// types to return a unique number indicating whether
|
||||
// this TransformAttrib is equivalent to the other one.
|
||||
//
|
||||
// This should return 0 if the two TransformAttrib objects
|
||||
// are equivalent, a number less than zero if this one
|
||||
// should be sorted before the other one, and a number
|
||||
// greater than zero otherwise.
|
||||
//
|
||||
// This will only be called with two TransformAttrib
|
||||
// objects whose get_type() functions return the same.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int TransformAttrib::
|
||||
compare_to_impl(const RenderAttrib *other) const {
|
||||
const TransformAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
|
||||
if (is_identity() != ta->is_identity()) {
|
||||
return is_identity() < ta->is_identity();
|
||||
}
|
||||
if (is_identity()) {
|
||||
// All identity transforms are equivalent to each other.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool components_given = (_flags & F_components_given) != 0;
|
||||
bool ta_components_given = (ta->_flags & F_components_given) != 0;
|
||||
if (components_given != ta_components_given) {
|
||||
return components_given < ta_components_given;
|
||||
}
|
||||
if (components_given) {
|
||||
// If the transform was specified componentwise, compare them
|
||||
// componentwise.
|
||||
int c = _pos.compare_to(ta->_pos);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
c = _hpr.compare_to(ta->_hpr);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
c = _scale.compare_to(ta->_hpr);
|
||||
return c;
|
||||
|
||||
}
|
||||
|
||||
// Otherwise, compare the matrices.
|
||||
return get_mat().compare_to(ta->get_mat());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::compose_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Intended to be overridden by derived RenderAttrib
|
||||
// types to specify how two consecutive RenderAttrib
|
||||
// objects of the same type interact.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) TransformAttrib::
|
||||
compose_impl(const RenderAttrib *other) const {
|
||||
const TransformAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, other);
|
||||
|
||||
// Identity times anything, duh.
|
||||
if (is_identity()) {
|
||||
return ta;
|
||||
} else if (ta->is_identity()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Perhaps we should be smarter here if both transforms are
|
||||
// componentwise, and multiply them componentwise.
|
||||
LMatrix4f new_mat = get_mat() * ta->get_mat();
|
||||
return make_mat(new_mat);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::make_default_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Intended to be overridden by derived TransformAttrib
|
||||
// types to specify what the default property for a
|
||||
// TransformAttrib of this type should be.
|
||||
//
|
||||
// This should return a newly-allocated TransformAttrib of
|
||||
// the same type that corresponds to whatever the
|
||||
// standard default for this kind of TransformAttrib is.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderAttrib *TransformAttrib::
|
||||
make_default_impl() const {
|
||||
return new TransformAttrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::calc_singular
|
||||
// Access: Private
|
||||
// Description: Determines whether the transform is singular (i.e. it
|
||||
// scales to zero, and has no inverse).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformAttrib::
|
||||
calc_singular() {
|
||||
bool singular = false;
|
||||
|
||||
if (has_components()) {
|
||||
// The matrix is singular if any component of its scale is 0.
|
||||
singular = (_scale[0] == 0.0f || _scale[1] == 0.0f || _scale[2] == 0.0f);
|
||||
} else {
|
||||
// The matrix is singular if its determinant is zero.
|
||||
const LMatrix4f &mat = get_mat();
|
||||
singular = (mat.get_upper_3().determinant() == 0.0f);
|
||||
}
|
||||
|
||||
if (singular) {
|
||||
_flags |= F_is_singular;
|
||||
}
|
||||
_flags |= F_singular_known;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::calc_components
|
||||
// Access: Private
|
||||
// Description: Derives the components from the matrix, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformAttrib::
|
||||
calc_components() {
|
||||
bool possible = decompose_matrix(get_mat(), _scale, _hpr, _pos);
|
||||
if (possible) {
|
||||
// Some matrices can't be decomposed into scale, hpr, pos.
|
||||
_flags |= F_has_components;
|
||||
}
|
||||
_flags |= F_components_known;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::calc_mat
|
||||
// Access: Private
|
||||
// Description: Computes the matrix from the components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformAttrib::
|
||||
calc_mat() {
|
||||
compose_matrix(_mat, _scale, _hpr, _pos);
|
||||
_flags |= F_mat_known;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// TransformAttrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformAttrib::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type TransformAttrib is encountered
|
||||
// in the Bam file. It should create the TransformAttrib
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *TransformAttrib::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
TransformAttrib *attrib = new TransformAttrib;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return new_from_bam(attrib, manager);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformAttrib::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new TransformAttrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
}
|
117
panda/src/pgraph/transformAttrib.h
Normal file
117
panda/src/pgraph/transformAttrib.h
Normal file
@ -0,0 +1,117 @@
|
||||
// Filename: transformAttrib.h
|
||||
// Created by: drose (23Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 TRANSFORMATTRIB_H
|
||||
#define TRANSFORMATTRIB_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "renderAttrib.h"
|
||||
#include "luse.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : TransformAttrib
|
||||
// Description : Indicates a coordinate-system transform on vertices.
|
||||
// TransformAttribs are the primary means for storing
|
||||
// transformations on the scene graph.
|
||||
//
|
||||
// Transforms may be specified in one of two ways:
|
||||
// componentwise, with a pos-hpr-scale, or with an
|
||||
// arbitrary transform matrix. If you specify a
|
||||
// transform componentwise, it will remember its
|
||||
// original components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA TransformAttrib : public RenderAttrib {
|
||||
private:
|
||||
INLINE TransformAttrib();
|
||||
|
||||
PUBLISHED:
|
||||
static CPT(RenderAttrib) make_identity();
|
||||
static CPT(RenderAttrib) make_components(const LVecBase3f &pos,
|
||||
const LVecBase3f &hpr,
|
||||
const LVecBase3f &scale);
|
||||
static CPT(RenderAttrib) make_mat(const LMatrix4f &mat);
|
||||
|
||||
INLINE bool is_identity() const;
|
||||
INLINE bool is_singular() const;
|
||||
INLINE bool has_components() const;
|
||||
INLINE const LVecBase3f &get_pos() const;
|
||||
INLINE const LVecBase3f &get_hpr() const;
|
||||
INLINE const LVecBase3f &get_scale() const;
|
||||
INLINE const LMatrix4f &get_mat() const;
|
||||
|
||||
public:
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
protected:
|
||||
virtual int compare_to_impl(const RenderAttrib *other) const;
|
||||
virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
|
||||
virtual RenderAttrib *make_default_impl() const;
|
||||
|
||||
private:
|
||||
INLINE void check_singular() const;
|
||||
INLINE void check_components() const;
|
||||
INLINE void check_mat() const;
|
||||
void calc_singular();
|
||||
void calc_components();
|
||||
void calc_mat();
|
||||
|
||||
enum Flags {
|
||||
F_is_identity = 0x0001,
|
||||
F_is_singular = 0x0002,
|
||||
F_singular_known = 0x0004,
|
||||
F_components_given = 0x0008,
|
||||
F_components_known = 0x0010,
|
||||
F_has_components = 0x0020,
|
||||
F_mat_known = 0x0040,
|
||||
};
|
||||
LVecBase3f _pos, _hpr, _scale;
|
||||
LMatrix4f _mat;
|
||||
|
||||
short _flags;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
RenderAttrib::init_type();
|
||||
register_type(_type_handle, "TransformAttrib",
|
||||
RenderAttrib::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 "transformAttrib.I"
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user