Support collision solids under LOD nodes
This commit is contained in:
parent
c0fffac008
commit
d850afd71a
|
|
@ -27,6 +27,7 @@
|
|||
#include "transformState.h"
|
||||
#include "geomNode.h"
|
||||
#include "geom.h"
|
||||
#include "lodNode.h"
|
||||
#include "nodePath.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "indent.h"
|
||||
|
|
@ -597,6 +598,14 @@ r_traverse(CollisionLevelState &level_state) {
|
|||
r_traverse(next_state);
|
||||
}
|
||||
|
||||
} else if (node->is_lod_node()) {
|
||||
// If it's an LODNode, visit the lowest level of detail.
|
||||
int index = DCAST(LODNode, node)->get_lowest_switch();
|
||||
if (index >= 0 && index < node->get_num_children()) {
|
||||
CollisionLevelState next_state(level_state, node->get_child(index));
|
||||
r_traverse(next_state);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Otherwise, visit all the children.
|
||||
int num_children = node->get_num_children();
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ all_windows_closed() const {
|
|||
// be instanced to each window's render tree as the
|
||||
// window is created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const NodePath &PandaFramework::
|
||||
NodePath &PandaFramework::
|
||||
get_models() {
|
||||
if (_models.is_empty()) {
|
||||
_models = NodePath("models");
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public:
|
|||
void close_all_windows();
|
||||
bool all_windows_closed() const;
|
||||
|
||||
const NodePath &get_models();
|
||||
NodePath &get_models();
|
||||
|
||||
void report_frame_rate(ostream &out) const;
|
||||
void reset_frame_rate();
|
||||
|
|
|
|||
|
|
@ -1,184 +0,0 @@
|
|||
// Filename: LOD.I
|
||||
// Created by: mike (09Jan97)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <math.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::Default Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODSwitch::
|
||||
LODSwitch() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODSwitch::
|
||||
LODSwitch(float in, float out) {
|
||||
set_range(in, out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODSwitch::
|
||||
LODSwitch(const LODSwitch ©) :
|
||||
_in(copy._in),
|
||||
_out(copy._out)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODSwitch::
|
||||
operator = (const LODSwitch ©) {
|
||||
_in = copy._in;
|
||||
_out = copy._out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::get_range
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODSwitch::
|
||||
get_range(float &in, float &out) const {
|
||||
in = get_in();
|
||||
out = get_out();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::get_in
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float LODSwitch::
|
||||
get_in() const {
|
||||
return sqrtf(_in);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::get_out
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float LODSwitch::
|
||||
get_out() const {
|
||||
return sqrtf(_out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::set_range
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODSwitch::
|
||||
set_range(float in, float out) {
|
||||
// We actually store the square of the switching distances. This
|
||||
// makes the LOD computation a little simpler.
|
||||
_in = in * in;
|
||||
_out = out * out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::in_range
|
||||
// Access: Public
|
||||
// Description: Computes the distance between two points and returns
|
||||
// true if the result is within the range for the LOD.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODSwitch::
|
||||
in_range(float dist_squared) const {
|
||||
return (dist_squared >= _out && dist_squared < _in);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::rescale
|
||||
// Access: Public
|
||||
// Description: Scales the switching distances by the square root of
|
||||
// the indicated factor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODSwitch::
|
||||
rescale(float factor_squared) {
|
||||
_in *= factor_squared;
|
||||
_out *= factor_squared;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::operator ==
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODSwitch::
|
||||
operator == (const LODSwitch &) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::operator !=
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODSwitch::
|
||||
operator != (const LODSwitch &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::operator <
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODSwitch::
|
||||
operator < (const LODSwitch &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::write_datagram
|
||||
// Access: Public
|
||||
// Description: Writes the contents of the LODSwitch out to the
|
||||
// datagram, presumably in preparation to writing to a
|
||||
// Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODSwitch::
|
||||
write_datagram(Datagram &destination) const {
|
||||
destination.add_float32(_in);
|
||||
destination.add_float32(_out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODSwitch::read_datagram
|
||||
// Access: Public
|
||||
// Description: Reads the contents of the LODSwitch from the
|
||||
// datagram, presumably in response to reading a Bam
|
||||
// file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODSwitch::
|
||||
read_datagram(DatagramIterator &source) {
|
||||
_in = source.get_float32();
|
||||
_out = source.get_float32();
|
||||
}
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
// Filename: LOD.cxx
|
||||
// Created by: mike (09Jan97)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include "LOD.h"
|
||||
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "indent.h"
|
||||
#include "config_gobj.h"
|
||||
|
||||
#define EXPCL EXPCL_PANDA
|
||||
#define EXPTP EXPTP_PANDA
|
||||
#define TYPE LODSwitch
|
||||
#define NAME LODSwitchVector
|
||||
|
||||
#include "vector_src.cxx"
|
||||
|
||||
float LOD::_stress_factor = lod_stress_factor;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LOD::
|
||||
LOD(void) {
|
||||
_center.set(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LOD::
|
||||
LOD(const LOD ©) :
|
||||
_center(copy._center),
|
||||
_switch_vector(copy._switch_vector)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LOD::
|
||||
~LOD(void) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::xform
|
||||
// Access: Public
|
||||
// Description: Transforms the LOD specification by the indicated
|
||||
// matrix.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LOD::
|
||||
xform(const LMatrix4f &mat) {
|
||||
_center = _center * mat;
|
||||
|
||||
// We'll take just the length of the y axis as the matrix's scale.
|
||||
LVector3f y;
|
||||
mat.get_row3(y,1);
|
||||
float factor_squared = y.length_squared();
|
||||
|
||||
LODSwitchVector::iterator si;
|
||||
for (si = _switch_vector.begin(); si != _switch_vector.end(); ++si) {
|
||||
(*si).rescale(factor_squared);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::compute_child
|
||||
// Access: Public
|
||||
// Description: Computes the distance between two points and returns
|
||||
// the index for the child of the LOD by testing against
|
||||
// the corresponding list of switching distances.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int LOD::
|
||||
compute_child(const LPoint3f &cam_pos, const LPoint3f ¢er) const {
|
||||
|
||||
LVector3f v = cam_pos - center;
|
||||
float dist = dot(v, v) * _stress_factor;
|
||||
LODSwitchVector::const_iterator i;
|
||||
int child = 0;
|
||||
for (i = _switch_vector.begin(), child = 0;
|
||||
i != _switch_vector.end(); ++i, ++child) {
|
||||
if ((*i).in_range(dist))
|
||||
break;
|
||||
}
|
||||
|
||||
if(debug_LOD_mode) {
|
||||
//not ifndef NDEBUG'ing this out since need it at Opt4 for perf measurements
|
||||
if(select_LOD_number>=0) {
|
||||
return select_LOD_number;
|
||||
}
|
||||
|
||||
// since lowest level LOD is lev 0, must invert the meaning of
|
||||
// so minimum_LOD_number 0 will screen out no LODs, and increasing it
|
||||
// will screen out successively higher levels
|
||||
int max_allowed_LOD_number = _switch_vector.size() - minimum_LOD_number;
|
||||
if(child > max_allowed_LOD_number) {
|
||||
child = max_allowed_LOD_number;
|
||||
}
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::write_datagram
|
||||
// Access: Public
|
||||
// Description: Writes the contents of the LOD out to the datagram,
|
||||
// presumably in preparation to writing to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LOD::
|
||||
write_datagram(Datagram &destination) const {
|
||||
_center.write_datagram(destination);
|
||||
|
||||
destination.add_uint16(_switch_vector.size());
|
||||
|
||||
LODSwitchVector::const_iterator si;
|
||||
for (si = _switch_vector.begin();
|
||||
si != _switch_vector.end();
|
||||
++si) {
|
||||
(*si).write_datagram(destination);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::read_datagram
|
||||
// Access: Public
|
||||
// Description: Reads the contents of the LOD from the datagram,
|
||||
// presumably in response to reading a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LOD::
|
||||
read_datagram(DatagramIterator &source) {
|
||||
_center.read_datagram(source);
|
||||
|
||||
_switch_vector.clear();
|
||||
|
||||
int num_switches = source.get_uint16();
|
||||
_switch_vector.reserve(num_switches);
|
||||
for (int i = 0; i < num_switches; i++) {
|
||||
_switch_vector.push_back(LODSwitch(0, 0));
|
||||
_switch_vector.back().read_datagram(source);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::output
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LOD::
|
||||
output(ostream &out) const {
|
||||
if (_switch_vector.empty()) {
|
||||
out << "no switches.";
|
||||
} else {
|
||||
LODSwitchVector::const_iterator si;
|
||||
si = _switch_vector.begin();
|
||||
out << "(" << (*si).get_in() << "/" << (*si).get_out() << ")";
|
||||
++si;
|
||||
while (si != _switch_vector.end()) {
|
||||
out << " (" << (*si).get_in() << "/" << (*si).get_out() << ")";
|
||||
++si;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::write
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LOD::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< "LOD, " << _switch_vector.size() << " switches:\n";
|
||||
LODSwitchVector::const_iterator si;
|
||||
int i = 0;
|
||||
for (si = _switch_vector.begin();
|
||||
si != _switch_vector.end();
|
||||
++si) {
|
||||
indent(out, indent_level + 2)
|
||||
<< i << ". in at " << (*si).get_in()
|
||||
<< ", out at " << (*si).get_out() << "\n";
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::set_stress_factor
|
||||
// Access: Published, Static
|
||||
// Description: Sets the factor that globally scales all LOD's. This
|
||||
// factor is applied to the square of the LOD distance,
|
||||
// so the larger the number, the lower the detail that
|
||||
// is presented. The normal value is 1.0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LOD::
|
||||
set_stress_factor(float stress_factor) {
|
||||
_stress_factor = stress_factor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LOD::get_stress_factor
|
||||
// Access: Published, Static
|
||||
// Description: Returns the factor that globally scales all LOD's.
|
||||
// See get_stress_factor().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float LOD::
|
||||
get_stress_factor() {
|
||||
return _stress_factor;
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
// Filename: LOD.h
|
||||
// Created by: mike (09Jan97)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LOD_H
|
||||
#define LOD_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "luse.h"
|
||||
#include "typedReferenceCount.h"
|
||||
|
||||
class Datagram;
|
||||
class DatagramIterator;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LODSwitch
|
||||
// Description : Defines a switching region for an LOD. An object
|
||||
// will be visible when it is closer than "in" units,
|
||||
// but further than "out" units from the camera.
|
||||
//
|
||||
// The sense of in vs. out distances is as if the object
|
||||
// were coming towards you from far away: it switches
|
||||
// "in" at the far distance, and switches "out" at the
|
||||
// close distance. Thus, "in" should be larger than
|
||||
// "out".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA LODSwitch {
|
||||
public:
|
||||
INLINE LODSwitch();
|
||||
INLINE LODSwitch(float in, float out);
|
||||
INLINE LODSwitch(const LODSwitch ©);
|
||||
INLINE void operator = (const LODSwitch ©);
|
||||
|
||||
INLINE void get_range(float &in, float &out) const;
|
||||
INLINE float get_in() const;
|
||||
INLINE float get_out() const;
|
||||
INLINE void set_range(float in, float out);
|
||||
INLINE bool in_range(float dist_squared) const;
|
||||
|
||||
INLINE void rescale(float factor_squared);
|
||||
|
||||
// We must declare these operators to allow VC++ to explicitly
|
||||
// export pvector<LODSwitch>, below. They don't do anything useful.
|
||||
INLINE bool operator == (const LODSwitch &other) const;
|
||||
INLINE bool operator != (const LODSwitch &other) const;
|
||||
INLINE bool operator < (const LODSwitch &other) const;
|
||||
|
||||
INLINE void write_datagram(Datagram &destination) const;
|
||||
INLINE void read_datagram(DatagramIterator &source);
|
||||
|
||||
protected:
|
||||
float _in;
|
||||
float _out;
|
||||
};
|
||||
|
||||
#define EXPCL EXPCL_PANDA
|
||||
#define EXPTP EXPTP_PANDA
|
||||
#define TYPE LODSwitch
|
||||
#define NAME LODSwitchVector
|
||||
|
||||
#include "vector_src.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LOD
|
||||
// Description : Computes whether a level-of-detail should be rendered
|
||||
// or not based on distance from the rendering camera.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA LOD {
|
||||
public:
|
||||
LOD();
|
||||
LOD(const LOD ©);
|
||||
~LOD();
|
||||
|
||||
void xform(const LMatrix4f &mat);
|
||||
|
||||
int compute_child(const LPoint3f &cam_pos,
|
||||
const LPoint3f ¢er) const;
|
||||
|
||||
void write_datagram(Datagram &destination) const;
|
||||
void read_datagram(DatagramIterator &source);
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
PUBLISHED:
|
||||
static void set_stress_factor(float stress_factor);
|
||||
static float get_stress_factor();
|
||||
|
||||
public:
|
||||
LPoint3f _center;
|
||||
LODSwitchVector _switch_vector;
|
||||
|
||||
private:
|
||||
static float _stress_factor;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const LOD &lod) {
|
||||
lod.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "LOD.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -10,7 +10,6 @@
|
|||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
LOD.I LOD.h \
|
||||
boundedObject.I boundedObject.h \
|
||||
config_gobj.h drawable.h \
|
||||
geom.I geom.h \
|
||||
|
|
@ -33,7 +32,6 @@
|
|||
textureStage.I textureStage.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
LOD.cxx \
|
||||
boundedObject.cxx \
|
||||
config_gobj.cxx drawable.cxx geom.cxx \
|
||||
geomContext.cxx \
|
||||
|
|
@ -48,7 +46,6 @@
|
|||
texCoordName.cxx textureStage.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
LOD.I LOD.h \
|
||||
boundedObject.I boundedObject.h \
|
||||
config_gobj.h \
|
||||
drawable.h geom.I geom.h \
|
||||
|
|
|
|||
|
|
@ -107,20 +107,6 @@ BamTextureMode bam_texture_mode;
|
|||
// texture file, which will presumably only be loaded once.
|
||||
const string fake_texture_image = config_gobj.GetString("fake-texture-image", "");
|
||||
|
||||
// must be set to true for LOD_number debugging items to work
|
||||
const bool debug_LOD_mode = config_gobj.GetBool("debug-LOD-mode", false);
|
||||
|
||||
// if this is >=0, select_child always returns this LOD number
|
||||
const int select_LOD_number = config_gobj.GetInt("select-LOD-number", -1);
|
||||
|
||||
// this controls the LOD child number returned by compute_child
|
||||
// use it to force the LOD alg to not select the highest level(s) of LOD
|
||||
// minimum_LOD_number=0 will screen out no LODs, and increasing it
|
||||
// will screen out successively higher levels
|
||||
const int minimum_LOD_number = config_gobj.GetInt("minimum-LOD-number", 0);
|
||||
|
||||
const float lod_stress_factor = config_gobj.GetFloat("lod-stress-factor", 1.0f);
|
||||
|
||||
// The default near and far plane distances.
|
||||
const float default_near = config_gobj.GetFloat("default-near", 1.0f);
|
||||
const float default_far = config_gobj.GetFloat("default-far", 1000.0f);
|
||||
|
|
|
|||
|
|
@ -44,11 +44,6 @@ enum BamTextureMode {
|
|||
extern EXPCL_PANDA BamTextureMode bam_texture_mode;
|
||||
extern EXPCL_PANDA const string fake_texture_image;
|
||||
|
||||
extern EXPCL_PANDA const bool debug_number_mode;
|
||||
extern EXPCL_PANDA const int select_LOD_number;
|
||||
extern EXPCL_PANDA const int minimum_LOD_number;
|
||||
extern EXPCL_PANDA const bool debug_LOD_mode;
|
||||
|
||||
extern const float default_near;
|
||||
extern const float default_far;
|
||||
extern const float default_fov;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include "drawable.cxx"
|
||||
#include "geomContext.cxx"
|
||||
#include "imageBuffer.cxx"
|
||||
#include "LOD.cxx"
|
||||
#include "material.cxx"
|
||||
#include "materialPool.cxx"
|
||||
#include "orthographicLens.cxx"
|
||||
|
|
|
|||
|
|
@ -16,27 +16,6 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE FadeLODNode::CData::
|
||||
CData() {
|
||||
_fade_time = 1.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::CData::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE FadeLODNode::CData::
|
||||
CData(const FadeLODNode::CData ©) :
|
||||
_lod(copy._lod) {
|
||||
_fade_time = copy._fade_time;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::Constructor
|
||||
// Access: Published
|
||||
|
|
@ -44,7 +23,9 @@ CData(const FadeLODNode::CData ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE FadeLODNode::
|
||||
FadeLODNode(const string &name) :
|
||||
PandaNode(name) {
|
||||
LODNode(name)
|
||||
{
|
||||
_fade_time = 1.0;
|
||||
_fade_mode = false;
|
||||
_previous_child = 0;
|
||||
}
|
||||
|
|
@ -56,128 +37,13 @@ FadeLODNode(const string &name) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE FadeLODNode::
|
||||
FadeLODNode(const FadeLODNode ©) :
|
||||
PandaNode(copy),
|
||||
_cycler(copy._cycler) {
|
||||
LODNode(copy)
|
||||
{
|
||||
_fade_time = copy._fade_time;
|
||||
_fade_mode = copy._fade_mode;
|
||||
_previous_child = copy._previous_child;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::add_switch
|
||||
// Access: Published
|
||||
// Description: Adds a switch range to the FadeLODNode. This implies
|
||||
// that the corresponding child node has been parented
|
||||
// to the node.
|
||||
//
|
||||
// The sense of in vs. out distances is as if the object
|
||||
// were coming towards you from far away: it switches
|
||||
// "in" at the far distance, and switches "out" at the
|
||||
// close distance. Thus, "in" should be larger than
|
||||
// "out".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FadeLODNode::
|
||||
add_switch(float in, float out) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lod._switch_vector.push_back(LODSwitch(in, out));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::set_switch
|
||||
// Access: Published
|
||||
// Description: Changes the switching range of a particular child of
|
||||
// the LODNode. See add_switch().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool FadeLODNode::
|
||||
set_switch(int index, float in, float out) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertr(index >= 0 && index < (int)cdata->_lod._switch_vector.size(), false);
|
||||
cdata->_lod._switch_vector[index].set_range(in, out);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::clear_switches
|
||||
// Access: Published
|
||||
// Description: Removes the set of switching ranges for the LODNode,
|
||||
// presumably in conjunction with removing all of its
|
||||
// children. See add_switch().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FadeLODNode::
|
||||
clear_switches(void) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lod._switch_vector.erase(cdata->_lod._switch_vector.begin(),
|
||||
cdata->_lod._switch_vector.end());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::get_num_switches
|
||||
// Access: Published
|
||||
// Description: Returns the number of switch ranges added to the
|
||||
// LODNode. This should correspond to the number of
|
||||
// children of the node in order for the FadeLODNode to
|
||||
// function correctly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int FadeLODNode::
|
||||
get_num_switches() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_lod._switch_vector.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::get_in
|
||||
// Access: Published
|
||||
// Description: Returns the "in" distance of the indicated switch
|
||||
// range. This should be larger than the "out" distance
|
||||
// of the same range.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float FadeLODNode::
|
||||
get_in(int index) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(index >= 0 && index < (int)cdata->_lod._switch_vector.size(), 0.0);
|
||||
return cdata->_lod._switch_vector[index].get_in();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::get_out
|
||||
// Access: Published
|
||||
// Description: Returns the "out" distance of the indicated switch
|
||||
// range. This should be smaller than the "in" distance
|
||||
// of the same range.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float FadeLODNode::
|
||||
get_out(int index) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(index >= 0 && index < (int)cdata->_lod._switch_vector.size(), 0.0);
|
||||
return cdata->_lod._switch_vector[index].get_out();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::set_center
|
||||
// Access: Published
|
||||
// Description: Specifies the center of the LOD. This is the point
|
||||
// that is compared to the camera (in camera space) to
|
||||
// determine the particular LOD that should be chosen.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FadeLODNode::
|
||||
set_center(const LPoint3f ¢er) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lod._center = center;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::get_center
|
||||
// Access: Published
|
||||
// Description: Returns the center of the LOD. This is the point
|
||||
// that is compared to the camera (in camera space) to
|
||||
// determine the particular LOD that should be chosen.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LPoint3f &FadeLODNode::
|
||||
get_center() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_lod._center;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::set_fade_time
|
||||
// Access: Published
|
||||
|
|
@ -185,8 +51,7 @@ get_center() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void FadeLODNode::
|
||||
set_fade_time(float t) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_fade_time = t;
|
||||
_fade_time = t;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -196,7 +61,6 @@ set_fade_time(float t) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float FadeLODNode::
|
||||
get_fade_time() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_fade_time;
|
||||
return _fade_time;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,39 +26,6 @@
|
|||
|
||||
TypeHandle FadeLODNode::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *FadeLODNode::CData::
|
||||
make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::CData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FadeLODNode::CData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
_lod.write_datagram(dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::CData::fillin
|
||||
// Access: Public, Virtual
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new LODNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FadeLODNode::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_lod.read_datagram(scan);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::make_copy
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -72,48 +39,6 @@ make_copy() const {
|
|||
return new FadeLODNode(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::safe_to_combine
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if it is generally safe to combine this
|
||||
// particular kind of PandaNode with other kinds of
|
||||
// PandaNodes, adding children or whatever. For
|
||||
// instance, an LODNode should not be combined with any
|
||||
// other PandaNode, because its set of children is
|
||||
// meaningful.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool FadeLODNode::
|
||||
safe_to_combine() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::xform
|
||||
// Access: Public, Virtual
|
||||
// Description: Transforms the contents of this PandaNode by the
|
||||
// indicated matrix, if it means anything to do so. For
|
||||
// most kinds of PandaNodes, this does nothing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FadeLODNode::
|
||||
xform(const LMatrix4f &mat) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lod.xform(mat);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::has_cull_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: Should be overridden by derived classes to return
|
||||
// true if cull_callback() has been defined. Otherwise,
|
||||
// returns false to indicate cull_callback() does not
|
||||
// need to be called for this node during the cull
|
||||
// traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool FadeLODNode::
|
||||
has_cull_callback() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::cull_callback
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -135,94 +60,90 @@ has_cull_callback() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool FadeLODNode::
|
||||
cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
PandaNode *node = data.node();
|
||||
CDReader cdata(_cycler);
|
||||
if (_fade_mode) {
|
||||
float in_alpha;
|
||||
float out_alpha;
|
||||
_fade_timer -= ClockObject::get_global_clock()->get_dt();
|
||||
if (_fade_timer <= (cdata->_fade_time / 2.0)) {
|
||||
//SECOND HALF OF FADE:
|
||||
//Fade out the old LOD with z write off and
|
||||
//draw the opaque new LOD with z write on
|
||||
out_alpha = (_fade_timer*2.0) / cdata->_fade_time;
|
||||
if (out_alpha < 0.0) {
|
||||
out_alpha = 0.0;
|
||||
}
|
||||
|
||||
CullTraverserData next_data_in(data, node->get_child(_fade_in));
|
||||
CullTraverserData next_data_out(data, node->get_child(_fade_out));
|
||||
|
||||
// Disable Transparency on new LOD
|
||||
next_data_in._state = next_data_in._state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_none), 0);
|
||||
// Enable Transparency on old LOD
|
||||
next_data_out._state = next_data_out._state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha), 0);
|
||||
// Start Fading the old LOD out
|
||||
next_data_out._state = next_data_out._state->add_attrib(ColorScaleAttrib::make(LVecBase4f(1.0,1.0,1.0,out_alpha)));
|
||||
// The new LOD is now opaque and has depth writing
|
||||
next_data_in._state = next_data_in._state->add_attrib(DepthWriteAttrib::make(DepthWriteAttrib::M_on), 0);
|
||||
// The old LOD is fading so it doesnt depth write
|
||||
next_data_out._state = next_data_out._state->add_attrib(DepthWriteAttrib::make(DepthWriteAttrib::M_off), 0);
|
||||
|
||||
|
||||
trav->traverse(next_data_in);
|
||||
trav->traverse(next_data_out);
|
||||
} else {
|
||||
// FIRST HALF OF FADE
|
||||
// Fade the new LOD in with z writing off
|
||||
// Keep drawing the old LOD opaque with z writing on
|
||||
in_alpha = (1.0 - (_fade_timer / cdata->_fade_time))*2.0;
|
||||
if (in_alpha > 1.0) {
|
||||
in_alpha = 1.0;
|
||||
}
|
||||
|
||||
CullTraverserData next_data_out(data, node->get_child(_fade_out));
|
||||
CullTraverserData next_data_in(data, node->get_child(_fade_in));
|
||||
float now = ClockObject::get_global_clock()->get_frame_time();
|
||||
float elapsed = now - _fade_start;
|
||||
|
||||
// Disable transparency on old LOD
|
||||
next_data_out._state = next_data_out._state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_none), 0);
|
||||
// Enable transparency on new LOD
|
||||
next_data_in._state = next_data_in._state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha), 0);
|
||||
// Start Fading in the new LOD
|
||||
next_data_in._state = next_data_in._state->add_attrib(ColorScaleAttrib::make(LVecBase4f(1.0,1.0,1.0,in_alpha)));
|
||||
// Enable depth write for the old LOD
|
||||
next_data_out._state = next_data_out._state->add_attrib(DepthWriteAttrib::make(DepthWriteAttrib::M_on), 0);
|
||||
// Disable depth write for the new LOD
|
||||
next_data_in._state = next_data_in._state->add_attrib(DepthWriteAttrib::make(DepthWriteAttrib::M_off), 0);
|
||||
|
||||
float half_fade_time = _fade_time / 2.0f;
|
||||
|
||||
if (elapsed < half_fade_time) {
|
||||
// FIRST HALF OF FADE
|
||||
// Fade the new LOD in with z writing off
|
||||
// Keep drawing the old LOD opaque with z writing on
|
||||
if (_fade_out >= 0 && _fade_out < get_num_children()) {
|
||||
CullTraverserData next_data_out(data, get_child(_fade_out));
|
||||
trav->traverse(next_data_out);
|
||||
}
|
||||
|
||||
if (_fade_in >= 0 && _fade_in < get_num_children()) {
|
||||
CullTraverserData next_data_in(data, get_child(_fade_in));
|
||||
|
||||
float in_alpha = elapsed / half_fade_time;
|
||||
if (in_alpha > 1.0f) {
|
||||
in_alpha = 1.0f;
|
||||
}
|
||||
LVecBase4f alpha_scale(1.0f, 1.0f, 1.0f, in_alpha);
|
||||
|
||||
next_data_in._state =
|
||||
next_data_in._state->compose(get_fade_out_state())->compose
|
||||
(RenderState::make(ColorScaleAttrib::make(alpha_scale)));
|
||||
|
||||
trav->traverse(next_data_in);
|
||||
}
|
||||
if (_fade_timer < 0) { // Fading Complete
|
||||
|
||||
} else if (elapsed < _fade_time) {
|
||||
//SECOND HALF OF FADE:
|
||||
//Fade out the old LOD with z write off and
|
||||
//draw the opaque new LOD with z write on
|
||||
if (_fade_in >= 0 && _fade_in < get_num_children()) {
|
||||
CullTraverserData next_data_in(data, get_child(_fade_in));
|
||||
trav->traverse(next_data_in);
|
||||
}
|
||||
|
||||
if (_fade_out >= 0 && _fade_out < get_num_children()) {
|
||||
CullTraverserData next_data_out(data, get_child(_fade_out));
|
||||
|
||||
float out_alpha = 1.0f - elapsed / half_fade_time;
|
||||
if (out_alpha < 0.0f) {
|
||||
out_alpha = 0.0f;
|
||||
}
|
||||
LVecBase4f alpha_scale(1.0f, 1.0f, 1.0f, out_alpha);
|
||||
|
||||
next_data_out._state =
|
||||
next_data_out._state->compose(get_fade_out_state())->compose
|
||||
(RenderState::make(ColorScaleAttrib::make(alpha_scale)));
|
||||
|
||||
trav->traverse(next_data_out);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Fading complete
|
||||
_fade_mode = false;
|
||||
|
||||
if (_fade_in >= 0 && _fade_in < get_num_children()) {
|
||||
CullTraverserData next_data_in(data, get_child(_fade_in));
|
||||
trav->traverse(next_data_in);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (data._net_transform->is_singular()) {
|
||||
// If we're under a singular transform, we can't compute the LOD;
|
||||
// select none of them instead.
|
||||
//select_child(get_num_children());
|
||||
return false;
|
||||
} else {
|
||||
LPoint3f camera_pos(0, 0, 0);
|
||||
// Get the LOD center in camera space
|
||||
CPT(TransformState) rel_transform =
|
||||
trav->get_camera_transform()->invert_compose(data._net_transform);
|
||||
LPoint3f center = cdata->_lod._center * rel_transform->get_mat();
|
||||
// Determine which child to traverse
|
||||
int index = cdata->_lod.compute_child(camera_pos, center);
|
||||
//printf("CHILD: %d PREVIOUS %d \n",index,_previous_child);
|
||||
if (index != _previous_child) { // Transition occurred
|
||||
_fade_mode = true;
|
||||
_fade_timer = cdata->_fade_time;
|
||||
_fade_out = _previous_child;
|
||||
_fade_in = index;
|
||||
_previous_child = index;
|
||||
CullTraverserData next_data_transition(data, node->get_child(_fade_out));
|
||||
int index = compute_child(trav, data);
|
||||
if (index != _previous_child) { // Transition occurred
|
||||
_fade_mode = true;
|
||||
_fade_start = ClockObject::get_global_clock()->get_frame_time();
|
||||
_fade_out = _previous_child;
|
||||
_fade_in = index;
|
||||
_previous_child = index;
|
||||
if (_fade_out >= 0 && _fade_out < get_num_children()) {
|
||||
CullTraverserData next_data_transition(data, get_child(_fade_out));
|
||||
trav->traverse(next_data_transition);
|
||||
} else {
|
||||
}
|
||||
|
||||
} else {
|
||||
if (index >= 0 && index < get_num_children()) {
|
||||
// No transition... handle things as usual
|
||||
// Traverse only one valid child
|
||||
CullTraverserData next_data_normal(data, node->get_child(index));
|
||||
CullTraverserData next_data_normal(data, get_child(index));
|
||||
trav->traverse(next_data_normal);
|
||||
}
|
||||
}
|
||||
|
|
@ -238,11 +159,28 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void FadeLODNode::
|
||||
output(ostream &out) const {
|
||||
PandaNode::output(out);
|
||||
CDReader cdata(_cycler);
|
||||
out << " ";
|
||||
cdata->_lod.output(out);
|
||||
out<< "Fade Time : " << cdata->_fade_time << endl;
|
||||
LODNode::output(out);
|
||||
out << " fade time: " << _fade_time;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FadeLODNode::get_fade_out_state
|
||||
// Access: Protected, Static
|
||||
// Description: Returns a RenderState for rendering the element that
|
||||
// is switching out of visibility.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) FadeLODNode::
|
||||
get_fade_out_state() {
|
||||
// Once someone asks for this pointer, we hold its reference count
|
||||
// and never free it.
|
||||
static CPT(RenderState) state = (const RenderState *)NULL;
|
||||
if (state == (const RenderState *)NULL) {
|
||||
state = RenderState::make
|
||||
(TransparencyAttrib::make(TransparencyAttrib::M_alpha),
|
||||
DepthWriteAttrib::make(DepthWriteAttrib::M_off));
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -264,8 +202,7 @@ register_with_read_factory() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void FadeLODNode::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
PandaNode::write_datagram(manager, dg);
|
||||
manager->write_cdata(dg, _cycler);
|
||||
LODNode::write_datagram(manager, dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -297,6 +234,5 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void FadeLODNode::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
PandaNode::fillin(scan, manager);
|
||||
manager->read_cdata(scan, _cycler);
|
||||
LODNode::fillin(scan, manager);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,49 +21,43 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "pandaNode.h"
|
||||
|
||||
#include "LOD.h"
|
||||
#include "lodNode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : FadeLODNode
|
||||
// Description : A Level-of-Detail node with alpha based switching.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA FadeLODNode : public PandaNode {
|
||||
class EXPCL_PANDA FadeLODNode : public LODNode {
|
||||
PUBLISHED:
|
||||
INLINE FadeLODNode(const string &name);
|
||||
|
||||
|
||||
protected:
|
||||
INLINE FadeLODNode(const FadeLODNode ©);
|
||||
public:
|
||||
virtual PandaNode *make_copy() const;
|
||||
virtual bool safe_to_combine() const;
|
||||
virtual void xform(const LMatrix4f &mat);
|
||||
virtual bool has_cull_callback() const;
|
||||
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
PUBLISHED:
|
||||
// The sense of in vs. out distances is as if the object were coming
|
||||
// towards you from far away: it switches "in" at the far distance,
|
||||
// and switches "out" at the close distance. Thus, "in" should be
|
||||
// larger than "out".
|
||||
|
||||
INLINE void add_switch(float in, float out);
|
||||
INLINE bool set_switch(int index, float in, float out);
|
||||
INLINE void clear_switches(void);
|
||||
|
||||
INLINE int get_num_switches() const;
|
||||
INLINE float get_in(int index) const;
|
||||
INLINE float get_out(int index) const;
|
||||
|
||||
INLINE void set_center(const LPoint3f ¢er);
|
||||
INLINE const LPoint3f &get_center() const;
|
||||
|
||||
INLINE void set_fade_time(float t);
|
||||
INLINE float get_fade_time() const;
|
||||
|
||||
private:
|
||||
static CPT(RenderState) get_fade_out_state();
|
||||
|
||||
private:
|
||||
float _fade_time;
|
||||
|
||||
// These values are used to implement the fade-in-transition, and
|
||||
// really shouldn't be stored here (because it is incompatible with
|
||||
// multiple cameras on the scene, or multiple instances of the
|
||||
// LODNode).
|
||||
bool _fade_mode;
|
||||
float _fade_start;
|
||||
int _fade_out;
|
||||
int _fade_in;
|
||||
int _previous_child;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
|
@ -72,30 +66,6 @@ protected:
|
|||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
private:
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
INLINE CData();
|
||||
INLINE CData(const CData ©);
|
||||
virtual CycleData *make_copy() const;
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
|
||||
virtual void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
LOD _lod;
|
||||
float _fade_time;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
typedef CycleDataReader<CData> CDReader;
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
bool _fade_mode;
|
||||
float _fade_timer;
|
||||
int _fade_out;
|
||||
int _fade_in;
|
||||
int _previous_child;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -16,13 +16,20 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::CData::
|
||||
CData() {
|
||||
CData() :
|
||||
_center(0.0f, 0.0f, 0.0f),
|
||||
_lowest(0),
|
||||
_highest(0),
|
||||
_got_force_switch(false),
|
||||
_force_switch(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -32,10 +39,105 @@ CData() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::CData::
|
||||
CData(const LODNode::CData ©) :
|
||||
_lod(copy._lod)
|
||||
_center(copy._center),
|
||||
_switch_vector(copy._switch_vector),
|
||||
_lowest(copy._lowest),
|
||||
_highest(copy._highest),
|
||||
_got_force_switch(copy._got_force_switch),
|
||||
_force_switch(copy._force_switch)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::Switch::
|
||||
Switch(float in, float out) {
|
||||
set_range(in, out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::get_in
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float LODNode::Switch::
|
||||
get_in() const {
|
||||
return _in;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::get_out
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float LODNode::Switch::
|
||||
get_out() const {
|
||||
return _out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::set_range
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
set_range(float in, float out) {
|
||||
_in = in;
|
||||
_out = out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::in_range
|
||||
// Access: Public
|
||||
// Description: Computes the distance between two points and returns
|
||||
// true if the result is within the range for the LOD.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LODNode::Switch::
|
||||
in_range(float dist) const {
|
||||
return (dist >= _out && dist < _in);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::rescale
|
||||
// Access: Public
|
||||
// Description: Scales the switching distances by the indicated factor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
rescale(float factor) {
|
||||
_in *= factor;
|
||||
_out *= factor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::write_datagram
|
||||
// Access: Public
|
||||
// Description: Writes the contents of the Switch out to the
|
||||
// datagram, presumably in preparation to writing to a
|
||||
// Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
write_datagram(Datagram &destination) const {
|
||||
destination.add_float32(_in);
|
||||
destination.add_float32(_out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Switch::read_datagram
|
||||
// Access: Public
|
||||
// Description: Reads the contents of the Switch from the datagram,
|
||||
// presumably in response to reading a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::Switch::
|
||||
read_datagram(DatagramIterator &source) {
|
||||
_in = source.get_float32();
|
||||
_out = source.get_float32();
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::Constructor
|
||||
// Access: Published
|
||||
|
|
@ -43,7 +145,7 @@ CData(const LODNode::CData ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::
|
||||
LODNode(const string &name) :
|
||||
SelectiveChildNode(name)
|
||||
PandaNode(name)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -54,7 +156,7 @@ LODNode(const string &name) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LODNode::
|
||||
LODNode(const LODNode ©) :
|
||||
SelectiveChildNode(copy),
|
||||
PandaNode(copy),
|
||||
_cycler(copy._cycler)
|
||||
{
|
||||
}
|
||||
|
|
@ -75,7 +177,8 @@ LODNode(const LODNode ©) :
|
|||
INLINE void LODNode::
|
||||
add_switch(float in, float out) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lod._switch_vector.push_back(LODSwitch(in, out));
|
||||
cdata->_switch_vector.push_back(Switch(in, out));
|
||||
cdata->check_limits();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -87,8 +190,9 @@ add_switch(float in, float out) {
|
|||
INLINE bool LODNode::
|
||||
set_switch(int index, float in, float out) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertr(index >= 0 && index < (int)cdata->_lod._switch_vector.size(), false);
|
||||
cdata->_lod._switch_vector[index].set_range(in, out);
|
||||
nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), false);
|
||||
cdata->_switch_vector[index].set_range(in, out);
|
||||
cdata->check_limits();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -102,8 +206,9 @@ set_switch(int index, float in, float out) {
|
|||
INLINE void LODNode::
|
||||
clear_switches(void) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lod._switch_vector.erase(cdata->_lod._switch_vector.begin(),
|
||||
cdata->_lod._switch_vector.end());
|
||||
cdata->_switch_vector.clear();
|
||||
cdata->_lowest = 0;
|
||||
cdata->_highest = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -117,7 +222,7 @@ clear_switches(void) {
|
|||
INLINE int LODNode::
|
||||
get_num_switches() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_lod._switch_vector.size();
|
||||
return cdata->_switch_vector.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -130,8 +235,8 @@ get_num_switches() const {
|
|||
INLINE float LODNode::
|
||||
get_in(int index) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(index >= 0 && index < (int)cdata->_lod._switch_vector.size(), 0.0);
|
||||
return cdata->_lod._switch_vector[index].get_in();
|
||||
nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), 0.0);
|
||||
return cdata->_switch_vector[index].get_in();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -144,8 +249,63 @@ get_in(int index) const {
|
|||
INLINE float LODNode::
|
||||
get_out(int index) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(index >= 0 && index < (int)cdata->_lod._switch_vector.size(), 0.0);
|
||||
return cdata->_lod._switch_vector[index].get_out();
|
||||
nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), 0.0);
|
||||
return cdata->_switch_vector[index].get_out();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::get_lowest_switch
|
||||
// Access: Published
|
||||
// Description: Returns the index number of the child with the lowest
|
||||
// level of detail; that is, the one that is designed to
|
||||
// be seen from the farthest away. This is usually the
|
||||
// first child, but it is not necessarily so.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int LODNode::
|
||||
get_lowest_switch() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_lowest;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::get_highest_switch
|
||||
// Access: Published
|
||||
// Description: Returns the index number of the child with the highest
|
||||
// level of detail; that is, the one that is designed to
|
||||
// be seen from the closest to the camera. This is
|
||||
// usually the last child, but it is not necessarily so.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int LODNode::
|
||||
get_highest_switch() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_highest;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::force_switch
|
||||
// Access: Published
|
||||
// Description: Forces the LODNode to show the indicated level
|
||||
// instead of the level that would normally be shown
|
||||
// based on the distance from the camera.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::
|
||||
force_switch(int index) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_force_switch = index;
|
||||
cdata->_got_force_switch = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::clear_force_switch
|
||||
// Access: Published
|
||||
// Description: Undoes the effect of a previous call to
|
||||
// force_switch() and releases the LODNode to once again
|
||||
// display the normal level.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LODNode::
|
||||
clear_force_switch() {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_got_force_switch = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -158,7 +318,7 @@ get_out(int index) const {
|
|||
INLINE void LODNode::
|
||||
set_center(const LPoint3f ¢er) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lod._center = center;
|
||||
cdata->_center = center;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -171,5 +331,5 @@ set_center(const LPoint3f ¢er) {
|
|||
INLINE const LPoint3f &LODNode::
|
||||
get_center() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_lod._center;
|
||||
return cdata->_center;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,26 @@ make_copy() const {
|
|||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::check_limits
|
||||
// Access: Public
|
||||
// Description: Ensures that the _lowest and _highest members are set
|
||||
// appropriately after a change to the set of switches.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::CData::
|
||||
check_limits() {
|
||||
_lowest = 0;
|
||||
_highest = 0;
|
||||
for (size_t i = 1; i < _switch_vector.size(); ++i) {
|
||||
if (_switch_vector[i].get_out() > _switch_vector[_lowest].get_out()) {
|
||||
_lowest = i;
|
||||
}
|
||||
if (_switch_vector[i].get_in() < _switch_vector[_highest].get_in()) {
|
||||
_highest = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::CData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -40,7 +60,16 @@ make_copy() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::CData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
_lod.write_datagram(dg);
|
||||
_center.write_datagram(dg);
|
||||
|
||||
dg.add_uint16(_switch_vector.size());
|
||||
|
||||
SwitchVector::const_iterator si;
|
||||
for (si = _switch_vector.begin();
|
||||
si != _switch_vector.end();
|
||||
++si) {
|
||||
(*si).write_datagram(dg);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -52,7 +81,24 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_lod.read_datagram(scan);
|
||||
_center.read_datagram(scan);
|
||||
|
||||
_switch_vector.clear();
|
||||
|
||||
int num_switches = scan.get_uint16();
|
||||
_switch_vector.reserve(num_switches);
|
||||
for (int i = 0; i < num_switches; i++) {
|
||||
Switch sw(0, 0);
|
||||
sw.read_datagram(scan);
|
||||
|
||||
if (manager->get_file_minor_ver() < 13) {
|
||||
// Before bam version 4.13, we stored the square of the
|
||||
// switching distance in the bam files.
|
||||
sw.set_range(sqrtf(sw.get_in()), sqrtf(sw.get_out()));
|
||||
}
|
||||
|
||||
_switch_vector.push_back(sw);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -93,7 +139,20 @@ safe_to_combine() const {
|
|||
void LODNode::
|
||||
xform(const LMatrix4f &mat) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lod.xform(mat);
|
||||
|
||||
cdata->_center = cdata->_center * mat;
|
||||
|
||||
// We'll take just the length of the y axis as the matrix's scale.
|
||||
LVector3f y;
|
||||
mat.get_row3(y, 1);
|
||||
float factor = y.length();
|
||||
|
||||
SwitchVector::iterator si;
|
||||
for (si = cdata->_switch_vector.begin();
|
||||
si != cdata->_switch_vector.end();
|
||||
++si) {
|
||||
(*si).rescale(factor);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -131,26 +190,15 @@ has_cull_callback() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool LODNode::
|
||||
cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
if (data._net_transform->is_singular()) {
|
||||
// If we're under a singular transform, we can't compute the LOD;
|
||||
// select none of them instead.
|
||||
select_child(get_num_children());
|
||||
|
||||
} else {
|
||||
CDReader cdata(_cycler);
|
||||
LPoint3f camera_pos(0, 0, 0);
|
||||
|
||||
// Get the LOD center in camera space
|
||||
CPT(TransformState) rel_transform =
|
||||
trav->get_camera_transform()->invert_compose(data._net_transform);
|
||||
LPoint3f center = cdata->_lod._center * rel_transform->get_mat();
|
||||
|
||||
// Determine which child to traverse
|
||||
int index = cdata->_lod.compute_child(camera_pos, center);
|
||||
select_child(index);
|
||||
int index = compute_child(trav, data);
|
||||
if (index >= 0 && index < get_num_children()) {
|
||||
CullTraverserData next_data(data, get_child(index));
|
||||
trav->traverse(next_data);
|
||||
}
|
||||
|
||||
return true;
|
||||
// Now return false indicating that we have already taken care of
|
||||
// the traversal from here.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -160,10 +208,90 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
output(ostream &out) const {
|
||||
SelectiveChildNode::output(out);
|
||||
PandaNode::output(out);
|
||||
CDReader cdata(_cycler);
|
||||
out << " ";
|
||||
cdata->_lod.output(out);
|
||||
if (cdata->_switch_vector.empty()) {
|
||||
out << "no switches.";
|
||||
} else {
|
||||
SwitchVector::const_iterator si;
|
||||
si = cdata->_switch_vector.begin();
|
||||
out << "(" << (*si).get_in() << "/" << (*si).get_out() << ")";
|
||||
++si;
|
||||
while (si != cdata->_switch_vector.end()) {
|
||||
out << " (" << (*si).get_in() << "/" << (*si).get_out() << ")";
|
||||
++si;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::is_lod_node
|
||||
// Access: Published, Virtual
|
||||
// Description: A simple downcast check. Returns true if this kind
|
||||
// of node happens to inherit from LODNode, false
|
||||
// otherwise.
|
||||
//
|
||||
// This is provided as a a faster alternative to calling
|
||||
// is_of_type(LODNode::get_class_type()).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool LODNode::
|
||||
is_lod_node() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LODNode::compute_child
|
||||
// Access: Protected
|
||||
// Description: Determines which child should be visible according to
|
||||
// the current camera position. If a child is visible,
|
||||
// returns its index number; otherwise, returns -1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int LODNode::
|
||||
compute_child(CullTraverser *trav, CullTraverserData &data) {
|
||||
if (data._net_transform->is_singular()) {
|
||||
// If we're under a singular transform, we can't compute the LOD;
|
||||
// select none of them instead.
|
||||
return -1;
|
||||
}
|
||||
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
if (cdata->_got_force_switch) {
|
||||
return cdata->_force_switch;
|
||||
}
|
||||
|
||||
// Get the LOD center in camera space
|
||||
// CPT(TransformState) rel_transform =
|
||||
// trav->get_camera_transform()->invert_compose(data._net_transform);
|
||||
|
||||
CPT(TransformState) rel_transform =
|
||||
trav->get_scene()->get_cull_center().get_net_transform()->
|
||||
invert_compose(data._net_transform);
|
||||
|
||||
LPoint3f center = cdata->_center * rel_transform->get_mat();
|
||||
|
||||
// Determine which child to traverse
|
||||
float dist = dot(center, LVector3f::forward());
|
||||
|
||||
for (int index = 0; index < (int)cdata->_switch_vector.size(); index++) {
|
||||
if (cdata->_switch_vector[index].in_range(dist)) {
|
||||
if (pgraph_cat.is_debug()) {
|
||||
pgraph_cat.debug()
|
||||
<< data._node_path << " at distance " << dist << ", selected child "
|
||||
<< index << "\n";
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
if (pgraph_cat.is_debug()) {
|
||||
pgraph_cat.debug()
|
||||
<< data._node_path << " at distance " << dist << ", no children in range.\n";
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -185,7 +313,7 @@ register_with_read_factory() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
SelectiveChildNode::write_datagram(manager, dg);
|
||||
PandaNode::write_datagram(manager, dg);
|
||||
manager->write_cdata(dg, _cycler);
|
||||
}
|
||||
|
||||
|
|
@ -218,6 +346,6 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void LODNode::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
SelectiveChildNode::fillin(scan, manager);
|
||||
PandaNode::fillin(scan, manager);
|
||||
manager->read_cdata(scan, _cycler);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "selectiveChildNode.h"
|
||||
|
||||
#include "LOD.h"
|
||||
#include "pandaNode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LODNode
|
||||
|
|
@ -32,7 +30,7 @@
|
|||
// from the camera and the table indicated in the
|
||||
// associated LOD object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA LODNode : public SelectiveChildNode {
|
||||
class EXPCL_PANDA LODNode : public PandaNode {
|
||||
PUBLISHED:
|
||||
INLINE LODNode(const string &name);
|
||||
|
||||
|
|
@ -47,6 +45,8 @@ public:
|
|||
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
virtual bool is_lod_node() const;
|
||||
|
||||
PUBLISHED:
|
||||
// The sense of in vs. out distances is as if the object were coming
|
||||
// towards you from far away: it switches "in" at the far distance,
|
||||
|
|
@ -61,9 +61,62 @@ PUBLISHED:
|
|||
INLINE float get_in(int index) const;
|
||||
INLINE float get_out(int index) const;
|
||||
|
||||
INLINE int get_lowest_switch() const;
|
||||
INLINE int get_highest_switch() const;
|
||||
|
||||
INLINE void force_switch(int index);
|
||||
INLINE void clear_force_switch();
|
||||
|
||||
INLINE void set_center(const LPoint3f ¢er);
|
||||
INLINE const LPoint3f &get_center() const;
|
||||
|
||||
protected:
|
||||
int compute_child(CullTraverser *trav, CullTraverserData &data);
|
||||
|
||||
protected:
|
||||
class Switch {
|
||||
public:
|
||||
INLINE Switch(float in, float out);
|
||||
INLINE float get_in() const;
|
||||
INLINE float get_out() const;
|
||||
|
||||
INLINE void set_range(float in, float out);
|
||||
INLINE bool in_range(float dist) const;
|
||||
|
||||
INLINE void rescale(float factor);
|
||||
|
||||
INLINE void write_datagram(Datagram &destination) const;
|
||||
INLINE void read_datagram(DatagramIterator &source);
|
||||
|
||||
private:
|
||||
float _in;
|
||||
float _out;
|
||||
};
|
||||
typedef pvector<Switch> SwitchVector;
|
||||
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
INLINE CData();
|
||||
INLINE CData(const CData ©);
|
||||
virtual CycleData *make_copy() const;
|
||||
|
||||
void check_limits();
|
||||
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
|
||||
virtual void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
LPoint3f _center;
|
||||
SwitchVector _switch_vector;
|
||||
size_t _lowest, _highest;
|
||||
|
||||
bool _got_force_switch;
|
||||
int _force_switch;
|
||||
};
|
||||
|
||||
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);
|
||||
|
|
@ -72,30 +125,14 @@ protected:
|
|||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
private:
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
INLINE CData();
|
||||
INLINE CData(const CData ©);
|
||||
virtual CycleData *make_copy() const;
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
|
||||
virtual void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
LOD _lod;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
typedef CycleDataReader<CData> CDReader;
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
SelectiveChildNode::init_type();
|
||||
PandaNode::init_type();
|
||||
register_type(_type_handle, "LODNode",
|
||||
SelectiveChildNode::get_class_type());
|
||||
PandaNode::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
|
|||
|
|
@ -1348,6 +1348,21 @@ is_geom_node() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::is_lod_node
|
||||
// Access: Published, Virtual
|
||||
// Description: A simple downcast check. Returns true if this kind
|
||||
// of node happens to inherit from LODNode, false
|
||||
// otherwise.
|
||||
//
|
||||
// This is provided as a a faster alternative to calling
|
||||
// is_of_type(LODNode::get_class_type()).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PandaNode::
|
||||
is_lod_node() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::as_light
|
||||
// Access: Published, Virtual
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@ PUBLISHED:
|
|||
INLINE const BoundingVolume &get_internal_bound() const;
|
||||
|
||||
virtual bool is_geom_node() const;
|
||||
virtual bool is_lod_node() const;
|
||||
virtual Light *as_light();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ static const unsigned short _bam_major_ver = 4;
|
|||
// Bumped to major version 3 on 12/8/00 to change float64's to float32's.
|
||||
// Bumped to major version 4 on 4/10/02 to store new scene graph.
|
||||
|
||||
static const unsigned short _bam_minor_ver = 12;
|
||||
static const unsigned short _bam_minor_ver = 13;
|
||||
// Bumped to minor version 1 on 4/10/03 to add CullFaceAttrib::reverse.
|
||||
// Bumped to minor version 1 on 4/10/03 to add CullFaceAttrib::reverse.
|
||||
// Bumped to minor version 2 on 4/12/03 to add num_components to texture.
|
||||
|
|
@ -48,6 +48,7 @@ static const unsigned short _bam_minor_ver = 12;
|
|||
// Bumped to minor version 10 on 04/23/04 to make ComputedVertices use uint32's.
|
||||
// Bumped to minor version 11 on 07/26/04 to add multitexture pointers.
|
||||
// Bumped to minor version 12 on 09/22/04 to add PandaNode::into_collide_mask.
|
||||
// Bumped to minor version 13 on 09/24/04 to store actual LODNode switch distances instead of squares.
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,12 +33,11 @@
|
|||
#end test_bin_target
|
||||
|
||||
#begin test_bin_target
|
||||
#define TARGET test_texmem
|
||||
#define SOURCES test_texmem.cxx
|
||||
#define TARGET test_lod
|
||||
#define SOURCES test_lod.cxx
|
||||
#end test_bin_target
|
||||
|
||||
#begin test_bin_target
|
||||
#define TARGET test_particles
|
||||
|
||||
#define SOURCES test_particles.cxx
|
||||
#define TARGET test_texmem
|
||||
#define SOURCES test_texmem.cxx
|
||||
#end test_bin_target
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
// Filename: lod_test.cxx
|
||||
// Created by:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "namedNode.h"
|
||||
|
||||
#include "eventHandler.h"
|
||||
#include "chancfg.h"
|
||||
#include "textNode.h"
|
||||
#include "eggLoader.h"
|
||||
#include "LOD.h"
|
||||
#include "LODNode.h"
|
||||
#include "pt_NamedNode.h"
|
||||
|
||||
extern PT_NamedNode render;
|
||||
extern PT_NamedNode egg_root;
|
||||
extern EventHandler event_handler;
|
||||
|
||||
extern int framework_main(int argc, char *argv[]);
|
||||
extern void (*define_keys)(EventHandler&);
|
||||
|
||||
void lod_keys(EventHandler& eh) {
|
||||
|
||||
PT(LODNode) lodnode = new LODNode("lodnode");
|
||||
new RenderRelation(egg_root, lodnode);
|
||||
|
||||
PT_NamedNode lodnode0 = loader.load_sync("smiley.egg");
|
||||
new RenderRelation(lodnode, lodnode0);
|
||||
lodnode->add_switch(10, 0);
|
||||
|
||||
PT_NamedNode lodnode1 = loader.load_sync("frowney.egg");
|
||||
new RenderRelation(lodnode, lodnode1);
|
||||
lodnode->add_switch(1000, 10);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
define_keys = &lod_keys;
|
||||
return framework_main(argc, argv);
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// Filename: test_lod.cxx
|
||||
// Created by: drose (24Sep04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandaFramework.h"
|
||||
#include "lodNode.h"
|
||||
#include "fadeLodNode.h"
|
||||
#include "loader.h"
|
||||
|
||||
PandaFramework framework;
|
||||
|
||||
char *filename_a = "smiley";
|
||||
char *filename_b = "frowney";
|
||||
|
||||
void
|
||||
create_lod_node(NodePath &models, const char *a, const char *b) {
|
||||
Loader loader;
|
||||
PT(PandaNode) smiley = loader.load_sync(a);
|
||||
PT(PandaNode) frowney = loader.load_sync(b);
|
||||
|
||||
PT(LODNode) lod = new FadeLODNode("lod");
|
||||
//PT(LODNode) lod = new LODNode("lod");
|
||||
if (!smiley.is_null()) {
|
||||
lod->add_child(smiley);
|
||||
lod->add_switch(10, 0);
|
||||
}
|
||||
if (!frowney.is_null()) {
|
||||
lod->add_child(frowney);
|
||||
lod->add_switch(1000, 10);
|
||||
}
|
||||
|
||||
models.attach_new_node(lod);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
framework.open_framework(argc, argv);
|
||||
framework.set_window_title("LOD Test");
|
||||
|
||||
WindowFramework *window = framework.open_window();
|
||||
if (window != (WindowFramework *)NULL) {
|
||||
// We've successfully opened a window.
|
||||
|
||||
window->enable_keyboard();
|
||||
window->setup_trackball();
|
||||
framework.get_models().instance_to(window->get_render());
|
||||
|
||||
create_lod_node(framework.get_models(),
|
||||
argc > 1 ? argv[1] : filename_a,
|
||||
argc > 2 ? argv[2] : filename_b);
|
||||
|
||||
window->center_trackball(framework.get_models());
|
||||
|
||||
framework.enable_default_keys();
|
||||
framework.main_loop();
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,649 +0,0 @@
|
|||
// Filename: test_particles.cxx
|
||||
// Created by:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "framework.h"
|
||||
|
||||
#include "eventHandler.h"
|
||||
#include "chancfg.h"
|
||||
#include <string>
|
||||
#include "renderModeTransition.h"
|
||||
#include "colorTransition.h"
|
||||
#include "cullFaceTransition.h"
|
||||
#include "depthTestTransition.h"
|
||||
#include "depthWriteTransition.h"
|
||||
#include "textureTransition.h"
|
||||
#include "lightTransition.h"
|
||||
#include "materialTransition.h"
|
||||
#include "transformTransition.h"
|
||||
#include "get_rel_pos.h"
|
||||
#include "boundingSphere.h"
|
||||
#include "geomSphere.h"
|
||||
#include "geomNode.h"
|
||||
#include "notify.h"
|
||||
#include "directionalLight.h"
|
||||
#include "renderRelation.h"
|
||||
#include "camera.h"
|
||||
#include "frustum.h"
|
||||
#include "orthoProjection.h"
|
||||
#include "perspectiveProjection.h"
|
||||
#include "textNode.h"
|
||||
#include "physicsManager.h"
|
||||
#include "particleSystem.h"
|
||||
#include "emitters.h"
|
||||
#include "particlefactories.h"
|
||||
#include "forces.h"
|
||||
#include "sparkleParticleRenderer.h"
|
||||
#include "pointParticleRenderer.h"
|
||||
#include "lineParticleRenderer.h"
|
||||
#include "geomParticleRenderer.h"
|
||||
#include "spriteParticleRenderer.h"
|
||||
#include "colorTransition.h"
|
||||
#include "particleSystemManager.h"
|
||||
#include "clockObject.h"
|
||||
#include "nodePath.h"
|
||||
#include "pointShapeTransition.h"
|
||||
#include "texture.h"
|
||||
#include "texturePool.h"
|
||||
#include "physicalNode.h"
|
||||
#include "forceNode.h"
|
||||
#include "linearEulerIntegrator.h"
|
||||
|
||||
// physics. particle systems.
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
// particle system manager params
|
||||
#define PARTICLE_SYSTEM_MANAGER_FRAME_STEPPING 1
|
||||
|
||||
// particle system params
|
||||
#define PARTICLE_SYSTEM_POOL_SIZE 1000
|
||||
#define PARTICLE_SYSTEM_BIRTH_RATE 0.01f
|
||||
//#define PARTICLE_SYSTEM_BIRTH_RATE 0.5f
|
||||
#define PARTICLE_SYSTEM_LITTER_SIZE 10
|
||||
#define PARTICLE_SYSTEM_LITTER_SPREAD 0
|
||||
|
||||
|
||||
//#define WIND_FORCE 0.5, 0, 0
|
||||
//#define NOISE_FORCE 0.02f
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
// particle factory selection
|
||||
#define POINT_PARTICLES
|
||||
//#define ZSPIN_PARTICLES
|
||||
//#define ORIENTED_PARTICLES
|
||||
|
||||
// particle renderer selection
|
||||
//#define POINT_PARTICLE_RENDERER
|
||||
#define LINE_PARTICLE_RENDERER
|
||||
//#define SPARKLE_PARTICLE_RENDERER
|
||||
//#define SPRITE_PARTICLE_RENDERER
|
||||
//#define GEOM_PARTICLE_RENDERER
|
||||
|
||||
// particle emitter selection
|
||||
//#define BOX_EMITTER
|
||||
//#define DISC_EMITTER
|
||||
//#define LINE_EMITTER
|
||||
//#define POINT_EMITTER
|
||||
//#define RECTANGLE_EMITTER
|
||||
//#define RING_EMITTER
|
||||
//#define SPHERE_SURFACE_EMITTER
|
||||
#define SPHERE_VOLUME_EMITTER
|
||||
//#define TANGENT_RING_EMITTER
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
// particle factory params
|
||||
#define PARTICLE_FACTORY_LIFESPAN_BASE 5.0f
|
||||
//#define PARTICLE_FACTORY_LIFESPAN_BASE 3.0f
|
||||
//#define PARTICLE_FACTORY_LIFESPAN_SPREAD 1.0f
|
||||
//#define PARTICLE_FACTORY_MASS_BASE 1.0f
|
||||
//#define PARTICLE_FACTORY_MASS_SPREAD 0.2f
|
||||
//#define PARTICLE_FACTORY_TERMINAL_VELOCITY_BASE PhysicsObject::_default_terminal_velocity
|
||||
//#define PARTICLE_FACTORY_TERMINAL_VELOCITY_SPREAD 0.0f
|
||||
|
||||
#ifdef ZSPIN_PARTICLES
|
||||
#define ZSPIN_PARTICLES_INITIAL_ANGLE 0.0f
|
||||
#define ZSPIN_PARTICLES_FINAL_ANGLE 0.0f
|
||||
#define ZSPIN_PARTICLES_INITIAL_ANGLE_SPREAD 90.0f
|
||||
#define ZSPIN_PARTICLES_FINAL_ANGLE_SPREAD 90.0f
|
||||
#endif
|
||||
|
||||
// particle renderer params
|
||||
#define SPRITE_PARTICLE_RENDERER_ALPHA_DISABLE false
|
||||
#define PARTICLE_RENDERER_ALPHA_MODE BaseParticleRenderer::PR_ALPHA_NONE
|
||||
//#define PARTICLE_RENDERER_ALPHA_MODE BaseParticleRenderer::PR_ALPHA_IN
|
||||
//#define PARTICLE_RENDERER_ALPHA_MODE BaseParticleRenderer::PR_ALPHA_OUT
|
||||
//#define PARTICLE_RENDERER_ALPHA_MODE BaseParticleRenderer::PR_ALPHA_USER
|
||||
//#define PARTICLE_RENDERER_USER_ALPHA 1.0
|
||||
|
||||
#ifdef GEOM_PARTICLE_RENDERER
|
||||
#elif defined POINT_PARTICLE_RENDERER
|
||||
#define POINT_PARTICLE_RENDERER_POINT_SIZE 1.0f
|
||||
// #define POINT_PARTICLE_RENDERER_STARTCOLOR Colorf(1.0f, 0.0f, 0.0f, 1.0f)
|
||||
// #define POINT_PARTICLE_RENDERER_ENDCOLOR Colorf(1.0f, 1.0f, 0.0f, 1.0f)
|
||||
// #define POINT_PARTICLE_RENDERER_BLEND_TYPE BaseParticleRenderer::PP_BLEND_LIFE
|
||||
// #define POINT_PARTICLE_RENDERER_BLEND_METHOD BaseParticleRenderer::PP_BLEND_LINEAR
|
||||
// #define POINT_PARTICLE_RENDERER_BLEND_METHOD BaseParticleRenderer::PP_BLEND_CUBIC
|
||||
|
||||
#elif defined LINE_PARTICLE_RENDERER
|
||||
#define LINE_PARTICLE_RENDERER_HEAD_COLOR Colorf(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
#define LINE_PARTICLE_RENDERER_TAIL_COLOR Colorf(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
#elif defined SPARKLE_PARTICLE_RENDERER
|
||||
// #define SPARKLE_PARTICLE_RENDERER_CENTER_COLOR Colorf(1.0f, 0.0f, 0.0f, 1.0f)
|
||||
// #define SPARKLE_PARTICLE_RENDERER_EDGE_COLOR Colorf(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
// #define SPARKLE_PARTICLE_RENDERER_BIRTH_RADIUS 0.004f
|
||||
// #define SPARKLE_PARTICLE_RENDERER_DEATH_RADIUS 1.0f
|
||||
// #define SPARKLE_PARTICLE_RENDERER_LIFE_SCALE SP_SCALE
|
||||
#elif defined SPRITE_PARTICLE_RENDERER
|
||||
// #define SPRITE_PARTICLE_RENDERER_TEXTURE_FILE "smoke.rgba"
|
||||
// #define SPRITE_PARTICLE_RENDERER_TEXTURE_FILE "lilsmiley.rgba"
|
||||
#define SPRITE_PARTICLE_RENDERER_TEXTURE_FILE "rock-floor.rgb"
|
||||
#define SPRITE_PARTICLE_RENDERER_COLOR Colorf(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
// #define SPRITE_PARTICLE_RENDERER_X_SCALE_FLAG true
|
||||
// #define SPRITE_PARTICLE_RENDERER_Y_SCALE_FLAG true
|
||||
#define SPRITE_PARTICLE_RENDERER_ANIM_ANGLE_FLAG true
|
||||
// #define SPRITE_PARTICLE_RENDERER_INITIAL_X_SCALE 0.1
|
||||
// #define SPRITE_PARTICLE_RENDERER_FINAL_X_SCALE 0.0
|
||||
// #define SPRITE_PARTICLE_RENDERER_INITIAL_Y_SCALE 0.0
|
||||
// #define SPRITE_PARTICLE_RENDERER_FINAL_Y_SCALE 0.5
|
||||
#define SPRITE_PARTICLE_RENDERER_NONANIMATED_THETA 45.0f
|
||||
#define SPRITE_PARTICLE_RENDERER_BLEND_METHOD BaseParticleRenderer::PP_BLEND_LINEAR
|
||||
// #define SPRITE_PARTICLE_RENDERER_BLEND_METHOD BaseParticleRenderer::PP_BLEND_CUBIC
|
||||
// #define SPRITE_PARTICLE_RENDERER_ALPHA_DISABLE false
|
||||
#endif
|
||||
|
||||
// particle emitter params
|
||||
|
||||
#define EMISSION_TYPE_EXPLICIT
|
||||
//#define EMISSION_TYPE_RADIATE
|
||||
//#define EMISSION_TYPE_CUSTOM
|
||||
|
||||
//#define EMITTER_AMPLITUDE 10.0
|
||||
#define EMITTER_AMPLITUDE 1.0
|
||||
//#define EMITTER_AMPLITUDE 0.5
|
||||
//#define EMITTER_AMPLITUDE_SPREAD 2.0
|
||||
//#define EMITTER_OFFSET_FORCE LVector3f(1.0, 1.0, 1.0)
|
||||
|
||||
#if defined EMISSION_TYPE_EXPLICIT
|
||||
#define EXPLICIT_LAUNCH_VEC LVector3f(-1.0f, -1.0f, 1.0f)
|
||||
// #define EXPLICIT_LAUNCH_VEC LVector3f(0.0f, 0.0f, 0.0f)
|
||||
#elif defined EMISSION_TYPE_RADIATE
|
||||
// #define RADIATE_ORIGIN LPoint3f(0.0f, 0.0f, 0.5f)
|
||||
#define RADIATE_ORIGIN LPoint3f(0.0f, 0.0f, 0.0f)
|
||||
#endif
|
||||
|
||||
#ifdef BOX_EMITTER
|
||||
#define BOX_EMITTER_MINBOUND LPoint3f(-1.0f, -1.0f, -1.0f)
|
||||
#define BOX_EMITTER_MAXBOUND LPoint3f(1.0f, 1.0f, 1.0f)
|
||||
#elif defined DISC_EMITTER
|
||||
#define DISC_EMITTER_RADIUS 1.0f
|
||||
#ifdef EMISSION_TYPE_CUSTOM
|
||||
#define DISC_EMITTER_OUTER_ANGLE 45.0f
|
||||
#define DISC_EMITTER_INNER_ANGLE 90.0f
|
||||
#define DISC_EMITTER_OUTER_MAGNITUDE 1.5f
|
||||
#define DISC_EMITTER_INNER_MAGNITUDE 1.5f
|
||||
#define DISC_EMITTER_CUBIC_LERPING false
|
||||
#endif
|
||||
#elif defined LINE_EMITTER
|
||||
#define LINE_EMITTER_ENDPOINT1 LPoint3f(-2.0f, 0.0f, 2.0f)
|
||||
#define LINE_EMITTER_ENDPOINT2 LPoint3f(2.0f, 0.0f, 2.0f)
|
||||
#elif defined POINT_EMITTER
|
||||
#define POINT_EMITTER_LOCATION LPoint3f(1.0f, 1.0f, 1.0f)
|
||||
#elif defined RECTANGLE_EMITTER
|
||||
#define RECTANGLE_EMITTER_MINBOUND LPoint2f(-1.0f, -1.0f)
|
||||
#define RECTANGLE_EMITTER_MAXBOUND LPoint2f(1.0f, 1.0f)
|
||||
#elif defined RING_EMITTER
|
||||
#define RING_EMITTER_RADIUS 0.5f
|
||||
#ifdef EMISSION_TYPE_CUSTOM
|
||||
#define RING_EMITTER_ANGLE 90.0f
|
||||
#endif
|
||||
#elif defined SPHERE_SURFACE_EMITTER
|
||||
#define SPHERE_SURFACE_EMITTER_RADIUS 1.0f
|
||||
#elif defined SPHERE_VOLUME_EMITTER
|
||||
#define SPHERE_VOLUME_EMITTER_RADIUS 1.0f
|
||||
#elif defined TANGENT_RING_EMITTER
|
||||
#define TANGENT_RING_EMITTER_RADIUS 1.0f
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
|
||||
PhysicsManager physics_manager;
|
||||
ParticleSystemManager ps_manager;
|
||||
|
||||
PT(ParticleSystem) particle_system = new ParticleSystem(PARTICLE_SYSTEM_POOL_SIZE);
|
||||
|
||||
static int particles_added = 0;
|
||||
|
||||
/*
|
||||
#if defined POINT_PARTICLES
|
||||
PT(PointParticleFactory) pf = new PointParticleFactory;
|
||||
#elif defined ZSPIN_PARTICLES
|
||||
PT(ZSpinParticleFactory) pf = new ZSpinParticleFactory;
|
||||
#elif defined ORIENTED_PARTICLES
|
||||
PT(OrientedParticleFactory) pf = new OrientedParticleFactory;
|
||||
#endif
|
||||
*/
|
||||
#if defined POINT_PARTICLES
|
||||
PT(BaseParticleFactory) pf = new PointParticleFactory;
|
||||
#elif defined ZSPIN_PARTICLES
|
||||
PT(BaseParticleFactory) pf = new ZSpinParticleFactory;
|
||||
#elif defined ORIENTED_PARTICLES
|
||||
PT(BaseParticleFactory) pf = new OrientedParticleFactory;
|
||||
#endif
|
||||
|
||||
#if defined GEOM_PARTICLE_RENDERER
|
||||
PT(GeomParticleRenderer) pr = new GeomParticleRenderer;
|
||||
#elif defined POINT_PARTICLE_RENDERER
|
||||
PT(PointParticleRenderer) pr = new PointParticleRenderer;
|
||||
#elif defined LINE_PARTICLE_RENDERER
|
||||
PT(LineParticleRenderer) pr = new LineParticleRenderer;
|
||||
#elif defined SPARKLE_PARTICLE_RENDERER
|
||||
PT(SparkleParticleRenderer) pr = new SparkleParticleRenderer;
|
||||
#elif defined SPRITE_PARTICLE_RENDERER
|
||||
PT(SpriteParticleRenderer) pr = new SpriteParticleRenderer;
|
||||
#endif
|
||||
|
||||
#if defined BOX_EMITTER
|
||||
PT(BoxEmitter) pe = new BoxEmitter;
|
||||
#elif defined DISC_EMITTER
|
||||
PT(DiscEmitter) pe = new DiscEmitter;
|
||||
#elif defined LINE_EMITTER
|
||||
PT(LineEmitter) pe = new LineEmitter;
|
||||
#elif defined POINT_EMITTER
|
||||
PT(PointEmitter) pe = new PointEmitter;
|
||||
#elif defined RECTANGLE_EMITTER
|
||||
PT(RectangleEmitter) pe = new RectangleEmitter;
|
||||
#elif defined RING_EMITTER
|
||||
PT(RingEmitter) pe = new RingEmitter;
|
||||
#elif defined SPHERE_SURFACE_EMITTER
|
||||
PT(SphereSurfaceEmitter) pe = new SphereSurfaceEmitter;
|
||||
#elif defined TANGENT_RING_EMITTER
|
||||
PT(TangentRingEmitter) pe = new TangentRingEmitter;
|
||||
#elif defined SPHERE_VOLUME_EMITTER
|
||||
PT(SphereVolumeEmitter) pe = new SphereVolumeEmitter;
|
||||
#endif
|
||||
|
||||
PT(Texture) texture;
|
||||
|
||||
#ifdef WIND_FORCE
|
||||
PT(LinearVectorForce) wind_force = new LinearVectorForce(WIND_FORCE);
|
||||
#endif
|
||||
#ifdef NOISE_FORCE
|
||||
PT(LinearNoiseForce) noise_force = new LinearNoiseForce(NOISE_FORCE);
|
||||
#endif
|
||||
|
||||
PT(PhysicalNode) pn = new PhysicalNode;
|
||||
PT(ForceNode) fn = new ForceNode;
|
||||
|
||||
static void
|
||||
event_csn_update(CPT_Event) {
|
||||
float dt = ClockObject::get_global_clock()->get_dt();
|
||||
|
||||
physics_manager.do_physics(dt);
|
||||
ps_manager.do_particles(dt);
|
||||
}
|
||||
|
||||
static void
|
||||
event_add_particles(CPT_Event) {
|
||||
|
||||
// guard against additional "P" presses (bad things happen)
|
||||
if(particles_added) return;
|
||||
particles_added = 1;
|
||||
|
||||
// renderer setup
|
||||
#ifdef PARTICLE_RENDERER_ALPHA_MODE
|
||||
pr->set_alpha_mode(PARTICLE_RENDERER_ALPHA_MODE);
|
||||
#endif
|
||||
#ifdef PARTICLE_RENDERER_USER_ALPHA
|
||||
pr->set_user_alpha(PARTICLE_RENDERER_USER_ALPHA);
|
||||
#endif
|
||||
|
||||
#ifdef GEOM_PARTICLE_RENDERER
|
||||
#elif defined POINT_PARTICLE_RENDERER
|
||||
#ifdef POINT_PARTICLE_RENDERER_POINT_SIZE
|
||||
pr->set_point_size(POINT_PARTICLE_RENDERER_POINT_SIZE);
|
||||
#endif
|
||||
#ifdef POINT_PARTICLE_RENDERER_STARTCOLOR
|
||||
pr->set_color1(POINT_PARTICLE_RENDERER_STARTCOLOR);
|
||||
#endif
|
||||
#ifdef POINT_PARTICLE_RENDERER_ENDCOLOR
|
||||
pr->set_color2(POINT_PARTICLE_RENDERER_ENDCOLOR);
|
||||
#endif
|
||||
#ifdef POINT_PARTICLE_RENDERER_BLEND_TYPE
|
||||
pr->set_blend_type(POINT_PARTICLE_RENDERER_BLEND_TYPE);
|
||||
#endif
|
||||
#ifdef POINT_PARTICLE_RENDERER_BLEND_METHOD
|
||||
pr->set_blend_method(POINT_PARTICLE_RENDERER_BLEND_METHOD);
|
||||
#endif
|
||||
#elif defined LINE_PARTICLE_RENDERER
|
||||
#ifdef LINE_PARTICLE_RENDERER_HEAD_COLOR
|
||||
pr->set_head_color(LINE_PARTICLE_RENDERER_HEAD_COLOR);
|
||||
#endif
|
||||
#ifdef LINE_PARTICLE_RENDERER_TAIL_COLOR
|
||||
pr->set_tail_color(LINE_PARTICLE_RENDERER_TAIL_COLOR);
|
||||
#endif
|
||||
#elif defined SPARKLE_PARTICLE_RENDERER
|
||||
#ifdef SPARKLE_PARTICLE_RENDERER_CENTER_COLOR
|
||||
pr->set_center_color(SPARKLE_PARTICLE_RENDERER_CENTER_COLOR);
|
||||
#endif
|
||||
#ifdef SPARKLE_PARTICLE_RENDERER_EDGE_COLOR
|
||||
pr->set_edge_color(SPARKLE_PARTICLE_RENDERER_EDGE_COLOR);
|
||||
#endif
|
||||
#ifdef SPARKLE_PARTICLE_RENDERER_LIFE_SCALE
|
||||
pr->set_life_scale(SPARKLE_PARTICLE_RENDERER_LIFE_SCALE);
|
||||
#endif
|
||||
#ifdef SPARKLE_PARTICLE_RENDERER_BIRTH_RADIUS
|
||||
pr->set_birth_mag(SPARKLE_PARTICLE_RENDERER_BIRTH_RADIUS);
|
||||
#endif
|
||||
#ifdef SPARKLE_PARTICLE_RENDERER_DEATH_RADIUS
|
||||
pr->set_death_mag(SPARKLE_PARTICLE_RENDERER_DEATH_RADIUS);
|
||||
#endif
|
||||
#elif defined SPRITE_PARTICLE_RENDERER
|
||||
pr->set_texture(texture);
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_COLOR
|
||||
pr->set_color(SPRITE_PARTICLE_RENDERER_COLOR);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_X_SCALE_FLAG
|
||||
pr->set_x_scale_flag(SPRITE_PARTICLE_RENDERER_X_SCALE_FLAG);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_Y_SCALE_FLAG
|
||||
pr->set_y_scale_flag(SPRITE_PARTICLE_RENDERER_Y_SCALE_FLAG);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_ANIM_ANGLE_FLAG
|
||||
pr->set_anim_angle_flag(SPRITE_PARTICLE_RENDERER_ANIM_ANGLE_FLAG);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_INITIAL_X_SCALE
|
||||
pr->set_initial_x_scale(SPRITE_PARTICLE_RENDERER_INITIAL_X_SCALE);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_FINAL_X_SCALE
|
||||
pr->set_final_x_scale(SPRITE_PARTICLE_RENDERER_FINAL_X_SCALE);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_INITIAL_Y_SCALE
|
||||
pr->set_initial_y_scale(SPRITE_PARTICLE_RENDERER_INITIAL_Y_SCALE);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_FINAL_Y_SCALE
|
||||
pr->set_final_y_scale(SPRITE_PARTICLE_RENDERER_FINAL_Y_SCALE);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_NONANIMATED_THETA
|
||||
pr->set_nonanimated_theta(SPRITE_PARTICLE_RENDERER_NONANIMATED_THETA);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_BLEND_METHOD
|
||||
pr->set_alpha_blend_method(SPRITE_PARTICLE_RENDERER_BLEND_METHOD);
|
||||
#endif
|
||||
#ifdef SPRITE_PARTICLE_RENDERER_ALPHA_DISABLE
|
||||
pr->set_alpha_disable(SPRITE_PARTICLE_RENDERER_ALPHA_DISABLE);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// factory setup
|
||||
|
||||
#ifdef PARTICLE_FACTORY_LIFESPAN_BASE
|
||||
pf->set_lifespan_base(PARTICLE_FACTORY_LIFESPAN_BASE);
|
||||
#endif
|
||||
#ifdef PARTICLE_FACTORY_LIFESPAN_SPREAD
|
||||
pf->set_lifespan_spread(PARTICLE_FACTORY_LIFESPAN_SPREAD);
|
||||
#endif
|
||||
#ifdef PARTICLE_FACTORY_MASS_BASE
|
||||
pf->set_mass_base(PARTICLE_FACTORY_MASS_BASE);
|
||||
#endif
|
||||
#ifdef PARTICLE_FACTORY_MASS_SPREAD
|
||||
pf->set_mass_spread(PARTICLE_FACTORY_MASS_SPREAD);
|
||||
#endif
|
||||
#ifdef PARTICLE_FACTORY_TERMINAL_VELOCITY_BASE
|
||||
pf->set_terminal_velocity_base(PARTICLE_FACTORY_TERMINAL_VELOCITY_BASE);
|
||||
#endif
|
||||
#ifdef PARTICLE_FACTORY_TERMINAL_VELOCITY_SPREAD
|
||||
pf->set_terminal_velocity_spread(PARTICLE_FACTORY_TERMINAL_VELOCITY_SPREAD);
|
||||
#endif
|
||||
|
||||
#if defined ZSPIN_PARTICLES
|
||||
#ifdef ZSPIN_PARTICLES_INITIAL_ANGLE
|
||||
pf->set_initial_angle(ZSPIN_PARTICLES_INITIAL_ANGLE);
|
||||
#endif
|
||||
#ifdef ZSPIN_PARTICLES_FINAL_ANGLE
|
||||
pf->set_final_angle(ZSPIN_PARTICLES_FINAL_ANGLE);
|
||||
#endif
|
||||
#ifdef ZSPIN_PARTICLES_INITIAL_ANGLE_SPREAD
|
||||
pf->set_initial_angle_spread(ZSPIN_PARTICLES_INITIAL_ANGLE_SPREAD);
|
||||
#endif
|
||||
#ifdef ZSPIN_PARTICLES_FINAL_ANGLE_SPREAD
|
||||
pf->set_final_angle_spread(ZSPIN_PARTICLES_FINAL_ANGLE_SPREAD);
|
||||
#endif
|
||||
#elif defined ORIENTED_PARTICLES
|
||||
#endif
|
||||
|
||||
// emitter setup
|
||||
#ifdef EMITTER_AMPLITUDE
|
||||
pe->set_amplitude(EMITTER_AMPLITUDE);
|
||||
#endif
|
||||
#ifdef EMITTER_AMPLITUDE_SPREAD
|
||||
pe->set_amplitude_spread(EMITTER_AMPLITUDE_SPREAD);
|
||||
#endif
|
||||
#ifdef EMITTER_OFFSET_FORCE
|
||||
pe->set_offset_force(EMITTER_OFFSET_FORCE);
|
||||
#endif
|
||||
|
||||
#if defined EMISSION_TYPE_EXPLICIT
|
||||
pe->set_emission_type(BaseParticleEmitter::ET_EXPLICIT);
|
||||
#ifdef EXPLICIT_LAUNCH_VEC
|
||||
pe->set_explicit_launch_vector(EXPLICIT_LAUNCH_VEC);
|
||||
#endif
|
||||
#elif defined EMISSION_TYPE_RADIATE
|
||||
pe->set_emission_type(BaseParticleEmitter::ET_RADIATE);
|
||||
#ifdef RADIATE_ORIGIN
|
||||
pe->set_radiate_origin(RADIATE_ORIGIN);
|
||||
#endif
|
||||
#elif defined EMISSION_TYPE_CUSTOM
|
||||
pe->set_emission_type(BaseParticleEmitter::ET_CUSTOM);
|
||||
#endif
|
||||
|
||||
#ifdef BOX_EMITTER
|
||||
#ifdef BOX_EMITTER_MINBOUND
|
||||
pe->set_min_bound(BOX_EMITTER_MINBOUND);
|
||||
#endif
|
||||
#ifdef BOX_EMITTER_MAXBOUND
|
||||
pe->set_max_bound(BOX_EMITTER_MAXBOUND);
|
||||
#endif
|
||||
#elif defined DISC_EMITTER
|
||||
#ifdef DISC_EMITTER_RADIUS
|
||||
pe->set_radius(DISC_EMITTER_RADIUS);
|
||||
#endif
|
||||
#ifdef EMISSION_TYPE_CUSTOM
|
||||
#ifdef DISC_EMITTER_OUTER_ANGLE
|
||||
pe->set_outer_angle(DISC_EMITTER_OUTER_ANGLE);
|
||||
#endif
|
||||
#ifdef DISC_EMITTER_INNER_ANGLE
|
||||
pe->set_inner_angle(DISC_EMITTER_INNER_ANGLE);
|
||||
#endif
|
||||
#ifdef DISC_EMITTER_OUTER_MAGNITUDE
|
||||
pe->set_outer_magnitude(DISC_EMITTER_OUTER_MAGNITUDE);
|
||||
#endif
|
||||
#ifdef DISC_EMITTER_INNER_MAGNITUDE
|
||||
pe->set_inner_magnitude(DISC_EMITTER_INNER_MAGNITUDE);
|
||||
#endif
|
||||
#ifdef DISC_EMITTER_CUBIC_LERPING
|
||||
pe->set_cubic_lerping(DISC_EMITTER_CUBIC_LERPING);
|
||||
#endif
|
||||
#endif
|
||||
#elif defined LINE_EMITTER
|
||||
#ifdef LINE_EMITTER_ENDPOINT1
|
||||
pe->set_endpoint1(LINE_EMITTER_ENDPOINT1);
|
||||
#endif
|
||||
#ifdef LINE_EMITTER_ENDPOINT2
|
||||
pe->set_endpoint2(LINE_EMITTER_ENDPOINT2);
|
||||
#endif
|
||||
#elif defined POINT_EMITTER
|
||||
#ifdef POINT_EMITTER_LOCATION
|
||||
pe->set_location(POINT_EMITTER_LOCATION);
|
||||
#endif
|
||||
#elif defined RECTANGLE_EMITTER
|
||||
#ifdef RECTANGLE_EMITTER_MINBOUND
|
||||
pe->set_min_bound(RECTANGLE_EMITTER_MINBOUND);
|
||||
#endif
|
||||
#ifdef RECTANGLE_EMITTER_MAXBOUND
|
||||
pe->set_max_bound(RECTANGLE_EMITTER_MAXBOUND);
|
||||
#endif
|
||||
#elif defined RING_EMITTER
|
||||
#ifdef RING_EMITTER_RADIUS
|
||||
pe->set_radius(RING_EMITTER_RADIUS);
|
||||
#endif
|
||||
#ifdef EMISSION_TYPE_CUSTOM
|
||||
#ifdef RING_EMITTER_ANGLE
|
||||
pe->set_aoe(RING_EMITTER_ANGLE);
|
||||
#endif
|
||||
#endif
|
||||
#elif defined SPHERE_SURFACE_EMITTER
|
||||
#ifdef SPHERE_SURFACE_EMITTER_RADIUS
|
||||
pe->set_radius(SPHERE_SURFACE_EMITTER_RADIUS);
|
||||
#endif
|
||||
#elif defined TANGENT_RING_EMITTER
|
||||
#ifdef TANGENT_RING_EMITTER_RADIUS
|
||||
pe->set_radius(TANGENT_RING_EMITTER_RADIUS);
|
||||
#endif
|
||||
#elif defined SPHERE_VOLUME_EMITTER
|
||||
#ifdef SPHERE_VOLUME_EMITTER_RADIUS
|
||||
pe->set_radius(SPHERE_VOLUME_EMITTER_RADIUS);
|
||||
#endif
|
||||
#endif // emitter type
|
||||
|
||||
// system setup
|
||||
particle_system->set_birth_rate(PARTICLE_SYSTEM_BIRTH_RATE);
|
||||
particle_system->set_litter_size(PARTICLE_SYSTEM_LITTER_SIZE);
|
||||
particle_system->set_litter_spread(PARTICLE_SYSTEM_LITTER_SPREAD);
|
||||
particle_system->set_emitter(pe);
|
||||
particle_system->set_renderer(pr);
|
||||
particle_system->set_factory(pf);
|
||||
|
||||
particle_system->set_render_parent(render);
|
||||
|
||||
pn->add_physical(particle_system);
|
||||
new RenderRelation(render, pn);
|
||||
|
||||
#ifdef WIND_FORCE
|
||||
fn->add_force(wind_force);
|
||||
#endif
|
||||
#ifdef NOISE_FORCE
|
||||
fn->add_force(noise_force);
|
||||
#endif
|
||||
new RenderRelation(render, fn);
|
||||
|
||||
physics_manager.attach_linear_integrator(new LinearEulerIntegrator);
|
||||
physics_manager.attach_physical(particle_system);
|
||||
#ifdef WIND_FORCE
|
||||
physics_manager.add_linear_force(wind_force);
|
||||
#endif
|
||||
|
||||
#ifdef PARTICLE_SYSTEM_MANAGER_FRAME_STEPPING
|
||||
ps_manager.set_frame_stepping(PARTICLE_SYSTEM_MANAGER_FRAME_STEPPING);
|
||||
#endif
|
||||
ps_manager.attach_particlesystem(particle_system);
|
||||
|
||||
#ifdef NOISE_FORCE
|
||||
particle_system->add_linear_force(noise_force);
|
||||
#endif
|
||||
|
||||
nout << "Added particles." << endl;
|
||||
event_handler.add_hook("NewFrame", event_csn_update);
|
||||
}
|
||||
|
||||
static void set_pool_size(int size) {
|
||||
nout << "setting pool size to " << size << endl;
|
||||
particle_system->set_pool_size(size);
|
||||
}
|
||||
|
||||
static void
|
||||
event_more_particles(CPT_Event) {
|
||||
static int index = 0;
|
||||
static int sizes[] = {
|
||||
10,
|
||||
999,
|
||||
998,
|
||||
999,
|
||||
1000,
|
||||
1001,
|
||||
1002,
|
||||
1003,
|
||||
1004,
|
||||
1000,
|
||||
16*1000,
|
||||
4*1000,
|
||||
3*1000,
|
||||
2*1000,
|
||||
1000,
|
||||
0,
|
||||
};
|
||||
|
||||
if(!particles_added) return;
|
||||
|
||||
if (0 == sizes[index]) index = 0;
|
||||
set_pool_size(sizes[index]);
|
||||
index++;
|
||||
}
|
||||
|
||||
static void
|
||||
event_switch_particle_factory_type(CPT_Event) {
|
||||
static int index = 0;
|
||||
|
||||
if(!particles_added) return;
|
||||
|
||||
cout << "Switching to a";
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
cout << " point";
|
||||
pf = new PointParticleFactory;
|
||||
particle_system->set_factory(pf);
|
||||
break;
|
||||
case 1:
|
||||
cout << " z-spin";
|
||||
pf = new ZSpinParticleFactory;
|
||||
particle_system->set_factory(pf);
|
||||
break;
|
||||
case 2:
|
||||
cout << "n oriented";
|
||||
pf = new OrientedParticleFactory;
|
||||
particle_system->set_factory(pf);
|
||||
break;
|
||||
}
|
||||
|
||||
cout << " particle factory" << endl;
|
||||
|
||||
index++;
|
||||
if (index > 2) index = 0;
|
||||
}
|
||||
|
||||
void demo_keys(EventHandler&) {
|
||||
new RenderRelation( lights, dlight );
|
||||
have_dlight = true;
|
||||
|
||||
event_handler.add_hook("p", event_add_particles);
|
||||
event_handler.add_hook("m", event_more_particles);
|
||||
event_handler.add_hook(",", event_switch_particle_factory_type);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
define_keys = &demo_keys;
|
||||
|
||||
#ifdef SPRITE_PARTICLE_RENDERER
|
||||
texture = TexturePool::load_texture(SPRITE_PARTICLE_RENDERER_TEXTURE_FILE);
|
||||
#endif
|
||||
|
||||
return framework_main(argc, argv);
|
||||
}
|
||||
Loading…
Reference in New Issue