mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
pgraph billboards
This commit is contained in:
parent
e274be72af
commit
4fac7d8fbf
@ -137,8 +137,8 @@ cull_and_draw_together(GraphicsWindow *win, DisplayRegion *dr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PandaNode *scene = camera_node->get_scene();
|
NodeChain scene = camera_node->get_scene();
|
||||||
if (scene == (PandaNode *)NULL) {
|
if (scene.is_empty()) {
|
||||||
// No scene, no draw.
|
// No scene, no draw.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -161,20 +161,22 @@ cull_and_draw_together(GraphicsWindow *win, DisplayRegion *dr) {
|
|||||||
// The world transform is computed from the camera's position; we
|
// The world transform is computed from the camera's position; we
|
||||||
// then might need to adjust it into the GSG's internal coordinate
|
// then might need to adjust it into the GSG's internal coordinate
|
||||||
// system.
|
// system.
|
||||||
CPT(TransformState) world_transform = camera.get_rel_transform(NodeChain());
|
trav.set_camera_transform(scene.get_rel_transform(camera));
|
||||||
|
|
||||||
|
CPT(TransformState) render_transform = camera.get_rel_transform(scene);
|
||||||
CoordinateSystem external_cs = gsg->get_coordinate_system();
|
CoordinateSystem external_cs = gsg->get_coordinate_system();
|
||||||
CoordinateSystem internal_cs = gsg->get_internal_coordinate_system();
|
CoordinateSystem internal_cs = gsg->get_internal_coordinate_system();
|
||||||
if (internal_cs != CS_default && internal_cs != external_cs) {
|
if (internal_cs != CS_default && internal_cs != external_cs) {
|
||||||
CPT(TransformState) cs_transform =
|
CPT(TransformState) cs_transform =
|
||||||
TransformState::make_mat(LMatrix4f::convert_mat(external_cs, internal_cs));
|
TransformState::make_mat(LMatrix4f::convert_mat(external_cs, internal_cs));
|
||||||
world_transform = cs_transform->compose(world_transform);
|
render_transform = cs_transform->compose(render_transform);
|
||||||
}
|
}
|
||||||
trav.set_world_transform(world_transform);
|
trav.set_render_transform(render_transform);
|
||||||
|
|
||||||
DisplayRegionStack old_dr = gsg->push_display_region(dr);
|
DisplayRegionStack old_dr = gsg->push_display_region(dr);
|
||||||
gsg->prepare_display_region();
|
gsg->prepare_display_region();
|
||||||
|
|
||||||
trav.traverse(scene);
|
trav.traverse(scene.node());
|
||||||
|
|
||||||
gsg->pop_display_region(old_dr);
|
gsg->pop_display_region(old_dr);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "transformState.h"
|
#include "transformState.h"
|
||||||
#include "textureAttrib.h"
|
#include "textureAttrib.h"
|
||||||
#include "texturePool.h"
|
#include "texturePool.h"
|
||||||
|
#include "billboardAttrib.h"
|
||||||
#include "qpgeomNode.h"
|
#include "qpgeomNode.h"
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
#include "eggPrimitive.h"
|
#include "eggPrimitive.h"
|
||||||
@ -985,13 +986,13 @@ setup_bucket(BuilderBucket &bucket, PandaNode *parent,
|
|||||||
bin = render_mode->get_bin();
|
bin = render_mode->get_bin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bucket._state = bucket._state->add(TextureAttrib::make_off());
|
bucket._state = bucket._state->add_attrib(TextureAttrib::make_off());
|
||||||
if (egg_prim->has_texture()) {
|
if (egg_prim->has_texture()) {
|
||||||
PT(EggTexture) egg_tex = egg_prim->get_texture();
|
PT(EggTexture) egg_tex = egg_prim->get_texture();
|
||||||
|
|
||||||
const TextureDef &def = _textures[egg_tex];
|
const TextureDef &def = _textures[egg_tex];
|
||||||
if (def._texture != (const RenderAttrib *)NULL) {
|
if (def._texture != (const RenderAttrib *)NULL) {
|
||||||
bucket._state = bucket._state->add(def._texture);
|
bucket._state = bucket._state->add_attrib(def._texture);
|
||||||
// bucket._trans.set_transition(def._apply);
|
// bucket._trans.set_transition(def._apply);
|
||||||
|
|
||||||
// If neither the primitive nor the texture specified an alpha
|
// If neither the primitive nor the texture specified an alpha
|
||||||
@ -1499,25 +1500,23 @@ create_group_arc(EggGroup *egg_group, PandaNode *parent, PandaNode *node) {
|
|||||||
node->set_transform(TransformState::make_mat(matf));
|
node->set_transform(TransformState::make_mat(matf));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// If the group has a billboard flag, apply that.
|
// If the group has a billboard flag, apply that.
|
||||||
switch (egg_group->get_billboard_type()) {
|
switch (egg_group->get_billboard_type()) {
|
||||||
case EggGroup::BT_point_camera_relative:
|
case EggGroup::BT_point_camera_relative:
|
||||||
arc->set_transition(new BillboardTransition(BillboardTransition::point_eye()));
|
node->set_attrib(BillboardAttrib::make_point_eye());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EggGroup::BT_point_world_relative:
|
case EggGroup::BT_point_world_relative:
|
||||||
arc->set_transition(new BillboardTransition(BillboardTransition::point_world()));
|
node->set_attrib(BillboardAttrib::make_point_world());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EggGroup::BT_axis:
|
case EggGroup::BT_axis:
|
||||||
arc->set_transition(new BillboardTransition(BillboardTransition::axis()));
|
node->set_attrib(BillboardAttrib::make_axis());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EggGroup::BT_none:
|
case EggGroup::BT_none:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (egg_group->get_decal_flag()) {
|
if (egg_group->get_decal_flag()) {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#define TARGET pgraph
|
#define TARGET pgraph
|
||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
|
billboardAttrib.h billboardAttrib.I \
|
||||||
qpcamera.h qpcamera.I \
|
qpcamera.h qpcamera.I \
|
||||||
colorAttrib.h colorAttrib.I \
|
colorAttrib.h colorAttrib.I \
|
||||||
config_pgraph.h \
|
config_pgraph.h \
|
||||||
@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||||
#define INCLUDED_SOURCES \
|
#define INCLUDED_SOURCES \
|
||||||
|
billboardAttrib.cxx \
|
||||||
qpcamera.cxx \
|
qpcamera.cxx \
|
||||||
colorAttrib.cxx \
|
colorAttrib.cxx \
|
||||||
config_pgraph.cxx \
|
config_pgraph.cxx \
|
||||||
@ -57,6 +59,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
|
billboardAttrib.h billboardAttrib.I \
|
||||||
qpcamera.h qpcamera.I \
|
qpcamera.h qpcamera.I \
|
||||||
colorAttrib.h colorAttrib.I \
|
colorAttrib.h colorAttrib.I \
|
||||||
config_pgraph.h \
|
config_pgraph.h \
|
||||||
|
153
panda/src/pgraph/billboardAttrib.I
Normal file
153
panda/src/pgraph/billboardAttrib.I
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// Filename: billboardAttrib.I
|
||||||
|
// Created by: drose (27Feb02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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: BillboardAttrib::Constructor
|
||||||
|
// Access: Private
|
||||||
|
// Description: Use BillboardAttrib::make() to construct a new
|
||||||
|
// BillboardAttrib object.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE BillboardAttrib::
|
||||||
|
BillboardAttrib() {
|
||||||
|
_off = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::make_axis
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: A convenience function to make a typical
|
||||||
|
// axis-rotating billboard.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(RenderAttrib) BillboardAttrib::
|
||||||
|
make_axis() {
|
||||||
|
return make(LVector3f::up(), false, true,
|
||||||
|
0.0f, NodeChain(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::make_point_eye
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: A convenience function to make a typical
|
||||||
|
// eye-relative point-rotating billboard.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(RenderAttrib) BillboardAttrib::
|
||||||
|
make_point_eye() {
|
||||||
|
return make(LVector3f::up(), true, false,
|
||||||
|
0.0f, NodeChain(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::make_point_world
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: A convenience function to make a typical
|
||||||
|
// world-relative point-rotating billboard.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(RenderAttrib) BillboardAttrib::
|
||||||
|
make_point_world() {
|
||||||
|
return make(LVector3f::up(), false, false,
|
||||||
|
0.0f, NodeChain(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::is_off
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if the BillboardAttrib is an 'off'
|
||||||
|
// BillboardAttrib, indicating that it does not enable
|
||||||
|
// billboarding. This kind of BillboardAttrib isn't
|
||||||
|
// particularly useful and isn't normally created or
|
||||||
|
// stored in the graph; it might be implicitly
|
||||||
|
// discovered as the result of a
|
||||||
|
// NodeChain::get_rel_state().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool BillboardAttrib::
|
||||||
|
is_off() const {
|
||||||
|
return _off;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::get_up_vector
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the up vector in effect for this billboard.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const LVector3f &BillboardAttrib::
|
||||||
|
get_up_vector() const {
|
||||||
|
return _up_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::get_eye_relative
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if this billboard interprets the up
|
||||||
|
// vector relative to the camera, or false if it is
|
||||||
|
// relative to the world.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool BillboardAttrib::
|
||||||
|
get_eye_relative() const {
|
||||||
|
return _eye_relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::get_axial_rotate
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if this billboard rotates only around
|
||||||
|
// the axis of the up vector, or false if it rotates
|
||||||
|
// freely in three dimensions.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool BillboardAttrib::
|
||||||
|
get_axial_rotate() const {
|
||||||
|
return _axial_rotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::get_offset
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the distance toward the camera (or the
|
||||||
|
// look_at_point) the billboard is moved towards, after
|
||||||
|
// rotating. This can be used to ensure the billboard
|
||||||
|
// is not obscured by nearby geometry.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float BillboardAttrib::
|
||||||
|
get_offset() const {
|
||||||
|
return _offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::get_look_at
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the node this billboard will rotate to look
|
||||||
|
// towards. If this is empty, it means the billboard
|
||||||
|
// will rotate towards the current camera node, wherever
|
||||||
|
// that might be.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const NodeChain &BillboardAttrib::
|
||||||
|
get_look_at() const {
|
||||||
|
return _look_at;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::get_look_at_point
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the point, relative to the look_at node,
|
||||||
|
// towards which the billboard will rotate. Normally
|
||||||
|
// this is (0, 0, 0).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const LPoint3f &BillboardAttrib::
|
||||||
|
get_look_at_point() const {
|
||||||
|
return _look_at_point;
|
||||||
|
}
|
255
panda/src/pgraph/billboardAttrib.cxx
Normal file
255
panda/src/pgraph/billboardAttrib.cxx
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
// Filename: billboardAttrib.cxx
|
||||||
|
// Created by: drose (27Feb02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 "billboardAttrib.h"
|
||||||
|
#include "look_at.h"
|
||||||
|
#include "bamReader.h"
|
||||||
|
#include "bamWriter.h"
|
||||||
|
#include "datagram.h"
|
||||||
|
#include "datagramIterator.h"
|
||||||
|
|
||||||
|
TypeHandle BillboardAttrib::_type_handle;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::make
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Constructs a new BillboardAttrib object with the
|
||||||
|
// indicated properties.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CPT(RenderAttrib) BillboardAttrib::
|
||||||
|
make(const LVector3f &up_vector, bool eye_relative,
|
||||||
|
bool axial_rotate, float offset, const NodeChain &look_at,
|
||||||
|
const LPoint3f &look_at_point) {
|
||||||
|
BillboardAttrib *attrib = new BillboardAttrib;
|
||||||
|
attrib->_up_vector = up_vector;
|
||||||
|
attrib->_eye_relative = eye_relative;
|
||||||
|
attrib->_axial_rotate = axial_rotate;
|
||||||
|
attrib->_offset = offset;
|
||||||
|
attrib->_look_at = look_at;
|
||||||
|
attrib->_look_at_point = look_at_point;
|
||||||
|
attrib->_off = false;
|
||||||
|
return return_new(attrib);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::output
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void BillboardAttrib::
|
||||||
|
output(ostream &out) const {
|
||||||
|
out << get_type() << ":";
|
||||||
|
if (is_off()) {
|
||||||
|
out << "(off)";
|
||||||
|
} else {
|
||||||
|
if (_axial_rotate) {
|
||||||
|
out << "(axis";
|
||||||
|
} else {
|
||||||
|
out << "(point";
|
||||||
|
}
|
||||||
|
if (!_up_vector.almost_equal(LVector3f::up())) {
|
||||||
|
out << " up " << _up_vector;
|
||||||
|
}
|
||||||
|
if (_eye_relative) {
|
||||||
|
out << " eye";
|
||||||
|
}
|
||||||
|
if (_offset != 0.0f) {
|
||||||
|
out << " offset " << _offset;
|
||||||
|
}
|
||||||
|
if (!_look_at.is_empty()) {
|
||||||
|
out << " look at " << _look_at;
|
||||||
|
}
|
||||||
|
if (!_look_at_point.almost_equal(LPoint3f(0.0f, 0.0f, 0.0f))) {
|
||||||
|
out << " look at point " << _look_at_point;
|
||||||
|
}
|
||||||
|
out << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::do_billboard
|
||||||
|
// Access: Public
|
||||||
|
// Description: Computes the appropriate transform to apply to the
|
||||||
|
// billboarded geometry, given its current net
|
||||||
|
// transform, and the camera's inverse net transform.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CPT(TransformState) BillboardAttrib::
|
||||||
|
do_billboard(const TransformState *net_transform,
|
||||||
|
const TransformState *camera_transform) const {
|
||||||
|
// Determine the relative transform to our camera (or other look_at
|
||||||
|
// coordinate space).
|
||||||
|
CPT(TransformState) rel_transform =
|
||||||
|
net_transform->invert_compose(camera_transform);
|
||||||
|
const LMatrix4f &rel_mat = rel_transform->get_mat();
|
||||||
|
|
||||||
|
// Determine the look_at point in the camera space.
|
||||||
|
LVector3f camera_pos, up;
|
||||||
|
|
||||||
|
// If this is an eye-relative Billboard, then (a) the up vector is
|
||||||
|
// relative to the camera, not to the world, and (b) the look
|
||||||
|
// direction is towards the plane that contains the camera,
|
||||||
|
// perpendicular to the forward direction, not directly to the
|
||||||
|
// camera.
|
||||||
|
|
||||||
|
if (_eye_relative) {
|
||||||
|
up = _up_vector * rel_mat;
|
||||||
|
camera_pos = LVector3f::forward() * rel_mat;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// camera_pos= -rel_mat.get_row3(3);
|
||||||
|
|
||||||
|
camera_pos[0] = -rel_mat(3,0);
|
||||||
|
camera_pos[1] = -rel_mat(3,1);
|
||||||
|
camera_pos[2] = -rel_mat(3,2);
|
||||||
|
|
||||||
|
up = _up_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now determine the rotation matrix for the Billboard.
|
||||||
|
LMatrix4f rotate;
|
||||||
|
if (_axial_rotate) {
|
||||||
|
heads_up(rotate, camera_pos, up);
|
||||||
|
} else {
|
||||||
|
look_at(rotate, camera_pos, up);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also slide the billboard geometry towards the camera according to
|
||||||
|
// the offset factor.
|
||||||
|
if (_offset != 0.0f) {
|
||||||
|
LVector3f translate(rel_mat(3, 0), rel_mat(3, 1), rel_mat(3, 2));
|
||||||
|
translate.normalize();
|
||||||
|
translate *= _offset;
|
||||||
|
rotate.set_row(3, translate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TransformState::make_mat(rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::compare_to_impl
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Intended to be overridden by derived BillboardAttrib
|
||||||
|
// types to return a unique number indicating whether
|
||||||
|
// this BillboardAttrib is equivalent to the other one.
|
||||||
|
//
|
||||||
|
// This should return 0 if the two BillboardAttrib 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 BillboardAttrib
|
||||||
|
// objects whose get_type() functions return the same.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int BillboardAttrib::
|
||||||
|
compare_to_impl(const RenderAttrib *other) const {
|
||||||
|
const BillboardAttrib *ta;
|
||||||
|
DCAST_INTO_R(ta, other, 0);
|
||||||
|
|
||||||
|
if (_axial_rotate != ta->_axial_rotate) {
|
||||||
|
return _axial_rotate - ta->_axial_rotate;
|
||||||
|
}
|
||||||
|
if (_eye_relative != ta->_eye_relative) {
|
||||||
|
return _eye_relative - ta->_eye_relative;
|
||||||
|
}
|
||||||
|
if (_offset != ta->_offset) {
|
||||||
|
return _offset < ta->_offset ? -1 : 1;
|
||||||
|
}
|
||||||
|
int compare = _up_vector.compare_to(ta->_up_vector);
|
||||||
|
if (compare != 0) {
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
compare = _look_at.compare_to(ta->_look_at);
|
||||||
|
if (compare != 0) {
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
compare = _look_at_point.compare_to(ta->_look_at_point);
|
||||||
|
if (compare != 0) {
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::make_default_impl
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Intended to be overridden by derived BillboardAttrib
|
||||||
|
// types to specify what the default property for a
|
||||||
|
// BillboardAttrib of this type should be.
|
||||||
|
//
|
||||||
|
// This should return a newly-allocated BillboardAttrib of
|
||||||
|
// the same type that corresponds to whatever the
|
||||||
|
// standard default for this kind of BillboardAttrib is.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
RenderAttrib *BillboardAttrib::
|
||||||
|
make_default_impl() const {
|
||||||
|
return new BillboardAttrib;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::register_with_read_factory
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Tells the BamReader how to create objects of type
|
||||||
|
// BillboardAttrib.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void BillboardAttrib::
|
||||||
|
register_with_read_factory() {
|
||||||
|
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::write_datagram
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Writes the contents of this object to the datagram
|
||||||
|
// for shipping out to a Bam file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void BillboardAttrib::
|
||||||
|
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||||
|
RenderAttrib::write_datagram(manager, dg);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::make_from_bam
|
||||||
|
// Access: Protected, Static
|
||||||
|
// Description: This function is called by the BamReader's factory
|
||||||
|
// when a new object of type BillboardAttrib is encountered
|
||||||
|
// in the Bam file. It should create the BillboardAttrib
|
||||||
|
// and extract its information from the file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
TypedWritable *BillboardAttrib::
|
||||||
|
make_from_bam(const FactoryParams ¶ms) {
|
||||||
|
BillboardAttrib *attrib = new BillboardAttrib;
|
||||||
|
DatagramIterator scan;
|
||||||
|
BamReader *manager;
|
||||||
|
|
||||||
|
parse_params(params, scan, manager);
|
||||||
|
attrib->fillin(scan, manager);
|
||||||
|
|
||||||
|
return new_from_bam(attrib, manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BillboardAttrib::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 BillboardAttrib.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void BillboardAttrib::
|
||||||
|
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||||
|
RenderAttrib::fillin(scan, manager);
|
||||||
|
}
|
105
panda/src/pgraph/billboardAttrib.h
Normal file
105
panda/src/pgraph/billboardAttrib.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// Filename: billboardAttrib.h
|
||||||
|
// Created by: drose (27Feb02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 BILLBOARDATTRIB_H
|
||||||
|
#define BILLBOARDATTRIB_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "renderAttrib.h"
|
||||||
|
#include "luse.h"
|
||||||
|
#include "nodeChain.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : BillboardAttrib
|
||||||
|
// Description : Indicates that geometry at this node should
|
||||||
|
// automatically rotate to face the camera, or any other
|
||||||
|
// arbitrary node.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA BillboardAttrib : public RenderAttrib {
|
||||||
|
private:
|
||||||
|
INLINE BillboardAttrib();
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
|
static CPT(RenderAttrib) make(const LVector3f &up_vector,
|
||||||
|
bool eye_relative,
|
||||||
|
bool axial_rotate,
|
||||||
|
float offset,
|
||||||
|
const NodeChain &look_at,
|
||||||
|
const LPoint3f &look_at_point);
|
||||||
|
INLINE static CPT(RenderAttrib) make_axis();
|
||||||
|
INLINE static CPT(RenderAttrib) make_point_eye();
|
||||||
|
INLINE static CPT(RenderAttrib) make_point_world();
|
||||||
|
|
||||||
|
INLINE bool is_off() const;
|
||||||
|
INLINE const LVector3f &get_up_vector() const;
|
||||||
|
INLINE bool get_eye_relative() const;
|
||||||
|
INLINE bool get_axial_rotate() const;
|
||||||
|
INLINE float get_offset() const;
|
||||||
|
INLINE const NodeChain &get_look_at() const;
|
||||||
|
INLINE const LPoint3f &get_look_at_point() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void output(ostream &out) const;
|
||||||
|
|
||||||
|
CPT(TransformState) do_billboard(const TransformState *net_transform,
|
||||||
|
const TransformState *camera_transform) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual int compare_to_impl(const RenderAttrib *other) const;
|
||||||
|
virtual RenderAttrib *make_default_impl() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _off;
|
||||||
|
LVector3f _up_vector;
|
||||||
|
bool _eye_relative;
|
||||||
|
bool _axial_rotate;
|
||||||
|
float _offset;
|
||||||
|
NodeChain _look_at;
|
||||||
|
LPoint3f _look_at_point;
|
||||||
|
|
||||||
|
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, "BillboardAttrib",
|
||||||
|
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 "billboardAttrib.I"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "config_pgraph.h"
|
#include "config_pgraph.h"
|
||||||
|
|
||||||
|
#include "billboardAttrib.h"
|
||||||
#include "qpcamera.h"
|
#include "qpcamera.h"
|
||||||
#include "colorAttrib.h"
|
#include "colorAttrib.h"
|
||||||
#include "qpgeomNode.h"
|
#include "qpgeomNode.h"
|
||||||
@ -57,6 +58,7 @@ init_libpgraph() {
|
|||||||
}
|
}
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
|
BillboardAttrib::init_type();
|
||||||
qpCamera::init_type();
|
qpCamera::init_type();
|
||||||
ColorAttrib::init_type();
|
ColorAttrib::init_type();
|
||||||
qpGeomNode::init_type();
|
qpGeomNode::init_type();
|
||||||
@ -70,6 +72,7 @@ init_libpgraph() {
|
|||||||
ColorAttrib::init_type();
|
ColorAttrib::init_type();
|
||||||
TransformState::init_type();
|
TransformState::init_type();
|
||||||
|
|
||||||
|
BillboardAttrib::register_with_read_factory();
|
||||||
ColorAttrib::register_with_read_factory();
|
ColorAttrib::register_with_read_factory();
|
||||||
qpGeomNode::register_with_read_factory();
|
qpGeomNode::register_with_read_factory();
|
||||||
PandaNode::register_with_read_factory();
|
PandaNode::register_with_read_factory();
|
||||||
|
@ -249,7 +249,7 @@ get_child_sort(int n) const {
|
|||||||
INLINE void PandaNode::
|
INLINE void PandaNode::
|
||||||
set_attrib(const RenderAttrib *attrib, int override) {
|
set_attrib(const RenderAttrib *attrib, int override) {
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
cdata->_state = cdata->_state->add(attrib, override);
|
cdata->_state = cdata->_state->add_attrib(attrib, override);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -282,7 +282,7 @@ get_attrib(TypeHandle type) const {
|
|||||||
INLINE void PandaNode::
|
INLINE void PandaNode::
|
||||||
clear_attrib(TypeHandle type) {
|
clear_attrib(TypeHandle type) {
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
cdata->_state = cdata->_state->remove(type);
|
cdata->_state = cdata->_state->remove_attrib(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -48,7 +48,7 @@ is_active() const {
|
|||||||
// represent the root of any subgraph.
|
// represent the root of any subgraph.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void qpCamera::
|
INLINE void qpCamera::
|
||||||
set_scene(PandaNode *scene) {
|
set_scene(const NodeChain &scene) {
|
||||||
_scene = scene;
|
_scene = scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ set_scene(PandaNode *scene) {
|
|||||||
// Description: Returns the scene that will be rendered by the
|
// Description: Returns the scene that will be rendered by the
|
||||||
// camera. See set_scene().
|
// camera. See set_scene().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE PandaNode *qpCamera::
|
INLINE const NodeChain &qpCamera::
|
||||||
get_scene() const {
|
get_scene() const {
|
||||||
return _scene;
|
return _scene;
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,7 @@ TypeHandle qpCamera::_type_handle;
|
|||||||
qpCamera::
|
qpCamera::
|
||||||
qpCamera(const string &name) :
|
qpCamera(const string &name) :
|
||||||
qpLensNode(name),
|
qpLensNode(name),
|
||||||
_active(true),
|
_active(true)
|
||||||
_scene((PandaNode *)NULL)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
|
|
||||||
#include "qplensNode.h"
|
#include "qplensNode.h"
|
||||||
|
#include "nodeChain.h"
|
||||||
|
|
||||||
class DisplayRegion;
|
class DisplayRegion;
|
||||||
class PandaNode;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : qpCamera
|
// Class : qpCamera
|
||||||
@ -49,8 +49,8 @@ PUBLISHED:
|
|||||||
INLINE void set_active(bool active);
|
INLINE void set_active(bool active);
|
||||||
INLINE bool is_active() const;
|
INLINE bool is_active() const;
|
||||||
|
|
||||||
INLINE void set_scene(PandaNode *scene);
|
INLINE void set_scene(const NodeChain &scene);
|
||||||
INLINE PandaNode *get_scene() const;
|
INLINE const NodeChain &get_scene() const;
|
||||||
|
|
||||||
INLINE int get_num_display_regions() const;
|
INLINE int get_num_display_regions() const;
|
||||||
INLINE DisplayRegion *get_display_region(int n) const;
|
INLINE DisplayRegion *get_display_region(int n) const;
|
||||||
@ -60,7 +60,7 @@ private:
|
|||||||
void remove_display_region(DisplayRegion *display_region);
|
void remove_display_region(DisplayRegion *display_region);
|
||||||
|
|
||||||
bool _active;
|
bool _active;
|
||||||
PandaNode *_scene;
|
NodeChain _scene;
|
||||||
|
|
||||||
typedef pvector<DisplayRegion *> DisplayRegions;
|
typedef pvector<DisplayRegion *> DisplayRegions;
|
||||||
DisplayRegions _display_regions;
|
DisplayRegions _display_regions;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "qpcullTraverser.h"
|
#include "qpcullTraverser.h"
|
||||||
#include "transformState.h"
|
#include "transformState.h"
|
||||||
#include "renderState.h"
|
#include "renderState.h"
|
||||||
|
#include "billboardAttrib.h"
|
||||||
#include "cullHandler.h"
|
#include "cullHandler.h"
|
||||||
#include "dcast.h"
|
#include "dcast.h"
|
||||||
#include "qpgeomNode.h"
|
#include "qpgeomNode.h"
|
||||||
@ -31,7 +32,8 @@
|
|||||||
qpCullTraverser::
|
qpCullTraverser::
|
||||||
qpCullTraverser() {
|
qpCullTraverser() {
|
||||||
_initial_state = RenderState::make_empty();
|
_initial_state = RenderState::make_empty();
|
||||||
_world_transform = DCAST(TransformState, TransformState::make_identity());
|
_camera_transform = DCAST(TransformState, TransformState::make_identity());
|
||||||
|
_render_transform = DCAST(TransformState, TransformState::make_identity());
|
||||||
_cull_handler = (CullHandler *)NULL;
|
_cull_handler = (CullHandler *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,14 +50,28 @@ set_initial_state(const RenderState *initial_state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpCullTraverser::set_world_transform
|
// Function: qpCullTraverser::set_camera_transform
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Specifies the position of the world relative to the
|
// Description: Specifies the position of the camera relative to the
|
||||||
// camera.
|
// starting node, without any compensating
|
||||||
|
// coordinate-system transforms that might have been
|
||||||
|
// introduced for the purposes of rendering.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void qpCullTraverser::
|
void qpCullTraverser::
|
||||||
set_world_transform(const TransformState *world_transform) {
|
set_camera_transform(const TransformState *camera_transform) {
|
||||||
_world_transform = world_transform;
|
_camera_transform = camera_transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpCullTraverser::set_render_transform
|
||||||
|
// Access: Public
|
||||||
|
// Description: Specifies the position of the starting node relative
|
||||||
|
// to the camera, pretransformed as appropriate for
|
||||||
|
// rendering.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void qpCullTraverser::
|
||||||
|
set_render_transform(const TransformState *render_transform) {
|
||||||
|
_render_transform = render_transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -78,7 +94,8 @@ void qpCullTraverser::
|
|||||||
traverse(PandaNode *root) {
|
traverse(PandaNode *root) {
|
||||||
nassertv(_cull_handler != (CullHandler *)NULL);
|
nassertv(_cull_handler != (CullHandler *)NULL);
|
||||||
|
|
||||||
r_traverse(root, _world_transform, _initial_state, 0);
|
r_traverse(root, _render_transform, TransformState::make_identity(),
|
||||||
|
_initial_state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -87,11 +104,25 @@ traverse(PandaNode *root) {
|
|||||||
// Description: The recursive traversal implementation.
|
// Description: The recursive traversal implementation.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void qpCullTraverser::
|
void qpCullTraverser::
|
||||||
r_traverse(PandaNode *node, const TransformState *transform,
|
r_traverse(PandaNode *node,
|
||||||
|
const TransformState *render_transform,
|
||||||
|
const TransformState *net_transform,
|
||||||
const RenderState *state, int flags) {
|
const RenderState *state, int flags) {
|
||||||
CPT(TransformState) next_transform = transform->compose(node->get_transform());
|
CPT(TransformState) next_render_transform =
|
||||||
|
render_transform->compose(node->get_transform());
|
||||||
|
CPT(TransformState) next_net_transform =
|
||||||
|
net_transform->compose(node->get_transform());
|
||||||
CPT(RenderState) next_state = state->compose(node->get_state());
|
CPT(RenderState) next_state = state->compose(node->get_state());
|
||||||
|
|
||||||
|
const BillboardAttrib *billboard = state->get_billboard();
|
||||||
|
if (billboard != (const BillboardAttrib *)NULL) {
|
||||||
|
// Got to apply a billboard transform here.
|
||||||
|
CPT(TransformState) billboard_transform =
|
||||||
|
billboard->do_billboard(net_transform, _camera_transform);
|
||||||
|
next_render_transform = next_render_transform->compose(billboard_transform);
|
||||||
|
next_net_transform = next_net_transform->compose(billboard_transform);
|
||||||
|
}
|
||||||
|
|
||||||
if (node->is_geom_node()) {
|
if (node->is_geom_node()) {
|
||||||
qpGeomNode *geom_node;
|
qpGeomNode *geom_node;
|
||||||
DCAST_INTO_V(geom_node, node);
|
DCAST_INTO_V(geom_node, node);
|
||||||
@ -101,7 +132,7 @@ r_traverse(PandaNode *node, const TransformState *transform,
|
|||||||
Geom *geom = geom_node->get_geom(i);
|
Geom *geom = geom_node->get_geom(i);
|
||||||
CPT(RenderState) geom_state =
|
CPT(RenderState) geom_state =
|
||||||
next_state->compose(geom_node->get_geom_state(i));
|
next_state->compose(geom_node->get_geom_state(i));
|
||||||
_cull_handler->record_geom(geom, next_transform, geom_state);
|
_cull_handler->record_geom(geom, next_render_transform, geom_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +140,6 @@ r_traverse(PandaNode *node, const TransformState *transform,
|
|||||||
PandaNode::Children cr = node->get_children();
|
PandaNode::Children cr = node->get_children();
|
||||||
int num_children = cr.get_num_children();
|
int num_children = cr.get_num_children();
|
||||||
for (int i = 0; i < num_children; i++) {
|
for (int i = 0; i < num_children; i++) {
|
||||||
r_traverse(cr.get_child(i), next_transform, next_state, flags);
|
r_traverse(cr.get_child(i), next_render_transform, next_net_transform, next_state, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,17 +41,20 @@ public:
|
|||||||
qpCullTraverser();
|
qpCullTraverser();
|
||||||
|
|
||||||
void set_initial_state(const RenderState *initial_state);
|
void set_initial_state(const RenderState *initial_state);
|
||||||
void set_world_transform(const TransformState *world_transform);
|
void set_camera_transform(const TransformState *camera_transform);
|
||||||
|
void set_render_transform(const TransformState *render_transform);
|
||||||
void set_cull_handler(CullHandler *cull_handler);
|
void set_cull_handler(CullHandler *cull_handler);
|
||||||
|
|
||||||
void traverse(PandaNode *root);
|
void traverse(PandaNode *root);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void r_traverse(PandaNode *node, const TransformState *transform,
|
void r_traverse(PandaNode *node, const TransformState *render_transform,
|
||||||
|
const TransformState *net_transform,
|
||||||
const RenderState *state, int flags);
|
const RenderState *state, int flags);
|
||||||
|
|
||||||
CPT(RenderState) _initial_state;
|
CPT(RenderState) _initial_state;
|
||||||
CPT(TransformState) _world_transform;
|
CPT(TransformState) _camera_transform;
|
||||||
|
CPT(TransformState) _render_transform;
|
||||||
CullHandler *_cull_handler;
|
CullHandler *_cull_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,3 +148,22 @@ get_override(int n) const {
|
|||||||
nassertr(n >= 0 && n < (int)_attributes.size(), 0);
|
nassertr(n >= 0 && n < (int)_attributes.size(), 0);
|
||||||
return _attributes[n]._override;
|
return _attributes[n]._override;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: RenderState::get_billboard
|
||||||
|
// Access: Public
|
||||||
|
// Description: This function is provided as an optimization, to
|
||||||
|
// speed up the render-time checking for the existance
|
||||||
|
// of a BillboardAttrib on this state. It returns a
|
||||||
|
// pointer to the BillboardAttrib, if there is one, or
|
||||||
|
// NULL if there is not.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const BillboardAttrib *RenderState::
|
||||||
|
get_billboard() const {
|
||||||
|
if ((_flags & F_checked_billboard) == 0) {
|
||||||
|
// We pretend this function is const, even though it transparently
|
||||||
|
// modifies the internal billboard cache.
|
||||||
|
((RenderState *)this)->determine_billboard();
|
||||||
|
}
|
||||||
|
return _billboard;
|
||||||
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "renderState.h"
|
#include "renderState.h"
|
||||||
|
#include "billboardAttrib.h"
|
||||||
#include "bamReader.h"
|
#include "bamReader.h"
|
||||||
#include "bamWriter.h"
|
#include "bamWriter.h"
|
||||||
#include "datagramIterator.h"
|
#include "datagramIterator.h"
|
||||||
@ -38,6 +39,7 @@ RenderState::
|
|||||||
RenderState() {
|
RenderState() {
|
||||||
_saved_entry = _states.end();
|
_saved_entry = _states.end();
|
||||||
_self_compose = (RenderState *)NULL;
|
_self_compose = (RenderState *)NULL;
|
||||||
|
_flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -399,7 +401,7 @@ invert_compose(const RenderState *other) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: RenderState::add
|
// Function: RenderState::add_attrib
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns a new RenderState object that represents the
|
// Description: Returns a new RenderState object that represents the
|
||||||
// same as the source state, with the new RenderAttrib
|
// same as the source state, with the new RenderAttrib
|
||||||
@ -407,7 +409,7 @@ invert_compose(const RenderState *other) const {
|
|||||||
// same type, it is replaced.
|
// same type, it is replaced.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
CPT(RenderState) RenderState::
|
CPT(RenderState) RenderState::
|
||||||
add(const RenderAttrib *attrib, int override) const {
|
add_attrib(const RenderAttrib *attrib, int override) const {
|
||||||
RenderState *new_state = new RenderState;
|
RenderState *new_state = new RenderState;
|
||||||
back_insert_iterator<Attributes> result =
|
back_insert_iterator<Attributes> result =
|
||||||
back_inserter(new_state->_attributes);
|
back_inserter(new_state->_attributes);
|
||||||
@ -441,14 +443,14 @@ add(const RenderAttrib *attrib, int override) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: RenderState::remove
|
// Function: RenderState::remove_attrib
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns a new RenderState object that represents the
|
// Description: Returns a new RenderState object that represents the
|
||||||
// same as the source state, with the indicated
|
// same as the source state, with the indicated
|
||||||
// RenderAttrib removed
|
// RenderAttrib removed
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
CPT(RenderState) RenderState::
|
CPT(RenderState) RenderState::
|
||||||
remove(TypeHandle type) const {
|
remove_attrib(TypeHandle type) const {
|
||||||
RenderState *new_state = new RenderState;
|
RenderState *new_state = new RenderState;
|
||||||
back_insert_iterator<Attributes> result =
|
back_insert_iterator<Attributes> result =
|
||||||
back_inserter(new_state->_attributes);
|
back_inserter(new_state->_attributes);
|
||||||
@ -466,6 +468,23 @@ remove(TypeHandle type) const {
|
|||||||
return return_new(new_state);
|
return return_new(new_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: RenderState::get_attrib
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Looks for a RenderAttrib of the indicated type in the
|
||||||
|
// state, and returns it if it is found, or NULL if it
|
||||||
|
// is not.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const RenderAttrib *RenderState::
|
||||||
|
get_attrib(TypeHandle type) const {
|
||||||
|
Attributes::const_iterator ai;
|
||||||
|
ai = _attributes.find(Attribute(type));
|
||||||
|
if (ai != _attributes.end()) {
|
||||||
|
return (*ai)._attrib;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: RenderState::output
|
// Function: RenderState::output
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
@ -807,6 +826,21 @@ do_invert_compose(const RenderState *other) const {
|
|||||||
return return_new(new_state);
|
return return_new(new_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: RenderState::determine_billboard
|
||||||
|
// Access: Private
|
||||||
|
// Description: This is the private implementation of
|
||||||
|
// get_billboard().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void RenderState::
|
||||||
|
determine_billboard() {
|
||||||
|
const RenderAttrib *attrib = get_attrib(BillboardAttrib::get_class_type());
|
||||||
|
if (attrib != (const RenderAttrib *)NULL) {
|
||||||
|
_billboard = DCAST(BillboardAttrib, attrib);
|
||||||
|
}
|
||||||
|
_flags |= F_checked_billboard;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: RenderState::register_with_read_factory
|
// Function: RenderState::register_with_read_factory
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "ordered_vector.h"
|
#include "ordered_vector.h"
|
||||||
|
|
||||||
class GraphicsStateGuardianBase;
|
class GraphicsStateGuardianBase;
|
||||||
|
class BillboardAttrib;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : RenderState
|
// Class : RenderState
|
||||||
@ -77,13 +78,17 @@ PUBLISHED:
|
|||||||
CPT(RenderState) compose(const RenderState *other) const;
|
CPT(RenderState) compose(const RenderState *other) const;
|
||||||
CPT(RenderState) invert_compose(const RenderState *other) const;
|
CPT(RenderState) invert_compose(const RenderState *other) const;
|
||||||
|
|
||||||
CPT(RenderState) add(const RenderAttrib *attrib, int override = 0) const;
|
CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const;
|
||||||
CPT(RenderState) remove(TypeHandle type) const;
|
CPT(RenderState) remove_attrib(TypeHandle type) const;
|
||||||
|
|
||||||
|
const RenderAttrib *get_attrib(TypeHandle type) const;
|
||||||
|
|
||||||
void output(ostream &out) const;
|
void output(ostream &out) const;
|
||||||
void write(ostream &out, int indent_level) const;
|
void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
INLINE const BillboardAttrib *get_billboard() const;
|
||||||
|
|
||||||
CPT(RenderState) issue_delta_modify(const RenderState *other,
|
CPT(RenderState) issue_delta_modify(const RenderState *other,
|
||||||
GraphicsStateGuardianBase *gsg) const;
|
GraphicsStateGuardianBase *gsg) const;
|
||||||
CPT(RenderState) issue_delta_set(const RenderState *other,
|
CPT(RenderState) issue_delta_set(const RenderState *other,
|
||||||
@ -93,6 +98,7 @@ private:
|
|||||||
static CPT(RenderState) return_new(RenderState *state);
|
static CPT(RenderState) return_new(RenderState *state);
|
||||||
CPT(RenderState) do_compose(const RenderState *other) const;
|
CPT(RenderState) do_compose(const RenderState *other) const;
|
||||||
CPT(RenderState) do_invert_compose(const RenderState *other) const;
|
CPT(RenderState) do_invert_compose(const RenderState *other) const;
|
||||||
|
void determine_billboard();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef pset<const RenderState *, IndirectLess<RenderState> > States;
|
typedef pset<const RenderState *, IndirectLess<RenderState> > States;
|
||||||
@ -145,6 +151,14 @@ private:
|
|||||||
typedef ov_set<Attribute> Attributes;
|
typedef ov_set<Attribute> Attributes;
|
||||||
Attributes _attributes;
|
Attributes _attributes;
|
||||||
|
|
||||||
|
// We cache the pointer to the BillboardAttrib stored in the state,
|
||||||
|
// if there is one.
|
||||||
|
const BillboardAttrib *_billboard;
|
||||||
|
enum Flags {
|
||||||
|
F_checked_billboard = 0x0001,
|
||||||
|
};
|
||||||
|
short _flags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void register_with_read_factory();
|
static void register_with_read_factory();
|
||||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||||
|
@ -270,7 +270,7 @@ main(int argc, char *argv[]) {
|
|||||||
// Now we just need to make a scene graph for the camera to render.
|
// Now we just need to make a scene graph for the camera to render.
|
||||||
PT(PandaNode) render = new PandaNode("render");
|
PT(PandaNode) render = new PandaNode("render");
|
||||||
render->add_child(camera);
|
render->add_child(camera);
|
||||||
camera->set_scene(render);
|
camera->set_scene(NodeChain(render));
|
||||||
|
|
||||||
// Set up a data graph for tracking user input. For now, this uses
|
// Set up a data graph for tracking user input. For now, this uses
|
||||||
// the old-style graph interface.
|
// the old-style graph interface.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user