Polylight Color storage corrected and SeaPatch removed

This commit is contained in:
Shalin Shodhan 2004-07-27 17:42:24 +00:00
parent 0d0b75e738
commit 2a6d6944b6
15 changed files with 127 additions and 1330 deletions

View File

@ -79,7 +79,6 @@
renderEffects.I renderEffects.h \
renderModeAttrib.I renderModeAttrib.h \
renderState.I renderState.h \
seaPatchNode.h seaPatchNode.I \
sceneGraphAnalyzer.h \
sceneGraphReducer.I sceneGraphReducer.h \
sceneSetup.I sceneSetup.h \
@ -172,7 +171,6 @@
sceneGraphAnalyzer.cxx \
sceneGraphReducer.cxx \
sceneSetup.cxx \
seaPatchNode.cxx \
selectiveChildNode.cxx \
sequenceNode.cxx \
showBoundsEffect.cxx \
@ -256,7 +254,6 @@
renderEffects.I renderEffects.h \
renderModeAttrib.I renderModeAttrib.h \
renderState.I renderState.h \
seaPatchNode.I seaPatchNode.h \
sceneGraphAnalyzer.h \
sceneGraphReducer.I sceneGraphReducer.h \
sceneSetup.I sceneSetup.h \

View File

@ -72,7 +72,6 @@
#include "renderEffects.h"
#include "renderModeAttrib.h"
#include "renderState.h"
#include "seaPatchNode.h"
#include "selectiveChildNode.h"
#include "sequenceNode.h"
#include "showBoundsEffect.h"
@ -225,7 +224,6 @@ init_libpgraph() {
RenderEffects::init_type();
RenderModeAttrib::init_type();
RenderState::init_type();
SeaPatchNode::init_type();
SelectiveChildNode::init_type();
SequenceNode::init_type();
ShowBoundsEffect::init_type();

View File

@ -67,7 +67,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg) {
while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) {
gsg->set_state_and_transform(base->_state->compose(state), base->_transform);
base->_geom->draw(gsg);
base = base->_next;
}
@ -79,7 +79,6 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg) {
while (decal != (CullableObject *)NULL) {
gsg->set_state_and_transform(decal->_state->compose(state), decal->_transform);
decal->_geom->draw(gsg);
decal = decal->_next;
}
}

View File

@ -29,6 +29,7 @@
#include "pvector.h"
#include "pset.h"
class GraphicsStateGuardianBase;
class TransformState;
class RenderState;

View File

@ -137,16 +137,16 @@ bool FadeLODNode::
cull_callback(CullTraverser *trav, CullTraverserData &data) {
PandaNode *node = data.node();
CDReader cdata(_cycler);
if(_fade_mode) {
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)) {
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) {
if (out_alpha < 0.0) {
out_alpha = 0.0;
}
@ -167,13 +167,12 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
trav->traverse(next_data_in);
trav->traverse(next_data_out);
}
else {
} 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) {
if (in_alpha > 1.0) {
in_alpha = 1.0;
}
@ -194,18 +193,16 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
trav->traverse(next_data_out);
trav->traverse(next_data_in);
}
if(_fade_timer < 0) { // Fading Complete
if (_fade_timer < 0) { // Fading Complete
_fade_mode = false;
}
}
else {
} 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 {
} else {
LPoint3f camera_pos(0, 0, 0);
// Get the LOD center in camera space
CPT(TransformState) rel_transform =
@ -214,16 +211,15 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
// 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;
if (index != _previous_child) { // Transition occurred
_fade_mode = true;
_fade_timer = cdata->_fade_time;
_fade_out = _previous_child;
_fade_in = index;
_previous_child = index;
_previous_child = index;
CullTraverserData next_data_transition(data, node->get_child(_fade_out));
trav->traverse(next_data_transition);
}
else {
} else {
// No transition... handle things as usual
// Traverse only one valid child
CullTraverserData next_data_normal(data, node->get_child(index));

View File

@ -27,7 +27,6 @@
#include "renderEffects.cxx"
#include "renderModeAttrib.cxx"
#include "renderState.cxx"
#include "seaPatchNode.cxx"
#include "sceneGraphAnalyzer.cxx"
#include "sceneGraphReducer.cxx"
#include "selectiveChildNode.cxx"

View File

@ -74,7 +74,7 @@ add_light(const string &lightname, const NodePath &newlight) {
nassertr(newlight.node() != (PolylightNode *)NULL,false);
// Check if light name is unique
if(_lightgroup.find(lightname) != _lightgroup.end()) {
if (_lightgroup.find(lightname) != _lightgroup.end()) {
cerr << "Light name already exists. Please choose another name\n";
return false;
}
@ -96,7 +96,7 @@ INLINE bool PolylightEffect::
remove_light(const string &lightname) {
// Check if light name exists
if(_lightgroup.find(lightname) == _lightgroup.end()) {
if (_lightgroup.find(lightname) == _lightgroup.end()) {
cerr << "Light name does not exist\n";
return false;
}
@ -155,7 +155,7 @@ get_weight() const {
// _contribution_type is a string that controls how
// this division occurs.
// "proximal" : A light only contributes if the node
// is inside its volume
// is inside its volume
// "all" : All lights added to the effect are used in
// division irrespective of their light volumes
////////////////////////////////////////////////////////////////////

View File

@ -57,71 +57,66 @@ do_poly_light(const CullTraverserData *data, const TransformState *node_transfor
r = 1.0;
g = 1.0;
b = 1.0;
if(is_enabled()) {
if (is_enabled()) {
LIGHTGROUP::const_iterator light_iter;
// Cycle through all the lights in this effect's lightgroup
for (light_iter = _lightgroup.begin(); light_iter != _lightgroup.end(); light_iter++){
const PolylightNode *light = DCAST(PolylightNode,light_iter->second.node());
// light holds the current PolylightNode
if(light->is_enabled()) { // if enabled get all the properties
float light_radius = light->get_radius();
PolylightNode::Attenuation_Type light_attenuation = light->get_attenuation();
float light_a0 = light->get_a0();
float light_a1 = light->get_a1();
float light_a2 = light->get_a2();
if(light_a0 == 0 && light_a1 == 0 && light_a2 == 0) { // To prevent division by zero
// light holds the current PolylightNode
if (light->is_enabled()) { // if enabled get all the properties
float light_radius = light->get_radius();
PolylightNode::Attenuation_Type light_attenuation = light->get_attenuation();
float light_a0 = light->get_a0();
float light_a1 = light->get_a1();
float light_a2 = light->get_a2();
if (light_a0 == 0 && light_a1 == 0 && light_a2 == 0) { // To prevent division by zero
light_a0 = 1.0;
}
Colorf light_color;
if(light->is_flickering()) { // If flickering, modify color
light_color = light->flicker();
}
else {
light_color = light->get_color();
}
// Calculate the distance of the node from the light
//dist = light_iter->second->get_distance(data->_node_path.get_node_path());
}
Colorf light_color;
if (light->is_flickering()) { // If flickering, modify color
light_color = light->flicker();
} else {
light_color = light->get_color_scenegraph();
}
// Calculate the distance of the node from the light
//dist = light_iter->second->get_distance(data->_node_path.get_node_path());
const NodePath lightnp = light_iter->second;
LPoint3f point = data->_node_path.get_node_path().get_relative_point(lightnp,
light->get_pos());
dist = (point - _effect_center).length();
if(dist < light_radius) { // If node is in range of this light
if(light_attenuation == PolylightNode::ALINEAR) {
light_scale = (light_radius - dist)/light_radius;
}
else if(light_attenuation == PolylightNode::AQUADRATIC) {
fd = 1.0 / (light_a0 + light_a1 * dist + light_a2 * dist * dist);
if(fd < 1.0) {
light_scale = fd;
}
else {
light_scale = 1.0;
}
}
else {
light_scale = 1.0;
}
// Keep accumulating each lights contribution... we divide by
// number of lights later.
Rcollect += light_color[0] * light_scale;
Gcollect += light_color[1] * light_scale;
Bcollect += light_color[2] * light_scale;
num_lights++;
} // if dist< radius
} // if light is enabled
if (dist < light_radius) { // If node is in range of this light
if (light_attenuation == PolylightNode::ALINEAR) {
light_scale = (light_radius - dist)/light_radius;
} else if (light_attenuation == PolylightNode::AQUADRATIC) {
fd = 1.0 / (light_a0 + light_a1 * dist + light_a2 * dist * dist);
if (fd < 1.0) {
light_scale = fd;
} else {
light_scale = 1.0;
}
} else {
light_scale = 1.0;
}
// Keep accumulating each lights contribution... we divide by
// number of lights later.
Rcollect += light_color[0] * light_scale;
Gcollect += light_color[1] * light_scale;
Bcollect += light_color[2] * light_scale;
num_lights++;
} // if dist< radius
} // if light is enabled
} // for all lights
if( _contribution_type == CALL) {
if ( _contribution_type == CALL) {
// Sometimes to prevent snapping of color at light volume boundaries
// just divide total contribution by all the lights in the effect
// whether or not they contribute color
// just divide total contribution by all the lights in the effect
// whether or not they contribute color
num_lights = _lightgroup.size();
}
if(num_lights == 0) {
if (num_lights == 0) {
no_lights_closeby = true;
num_lights = 1;
}
@ -129,7 +124,7 @@ do_poly_light(const CullTraverserData *data, const TransformState *node_transfor
Gcollect /= num_lights;
Bcollect /= num_lights;
if(!no_lights_closeby) {
if (!no_lights_closeby) {
//r = 1.0 + ((1.0 - _weight) + Rcollect * _weight);
//g = 1.0 + ((1.0 - _weight) + Gcollect * _weight);
//b = 1.0 + ((1.0 - _weight) + Bcollect * _weight);
@ -163,7 +158,7 @@ compare_to_impl(const RenderEffect *other) const {
DCAST_INTO_R(ta, other, 0);
if (_enabled != ta->_enabled) {
return _enabled ? 1 : -1;
return _enabled ? 1 : -1;
}
if (_contribution_type != ta->_contribution_type) {
@ -171,7 +166,7 @@ compare_to_impl(const RenderEffect *other) const {
}
if (_weight != ta->_weight) {
return _weight < ta->_weight ? -1 :1;
return _weight < ta->_weight ? -1 :1;
}
if (_lightgroup != ta->_lightgroup) {

View File

@ -33,10 +33,10 @@
////////////////////////////////////////////////////////////////////
// Class : PolylightEffect
// Description : A PolylightEffect can be used on a node to define a
// LightGroup for that node. A LightGroup contains
// LightGroup for that node. A LightGroup contains
// Polylights which are essentially nodes that add
// color to the polygons of a model based on distance.
// PolylightNode is a cheap way to get lighting effects
// color to the polygons of a model based on distance.
// PolylightNode is a cheap way to get lighting effects
// specially for night scenes
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA PolylightEffect : public RenderEffect {

View File

@ -359,7 +359,8 @@ get_step_size() const {
////////////////////////////////////////////////////////////////////
INLINE void PolylightNode::
set_color(Colorf color) {
PandaNode::set_attrib(ColorAttrib::make_flat(color));
//PandaNode::set_attrib(ColorAttrib::make_flat(color));
_color = color;
}
////////////////////////////////////////////////////////////////////
@ -369,12 +370,18 @@ set_color(Colorf color) {
////////////////////////////////////////////////////////////////////
INLINE void PolylightNode::
set_color(float r, float g, float b) {
/*
Colorf color;
color[0] = r;
color[1] = g;
color[2] = b;
color[3] = 1.0;
PandaNode::set_attrib(ColorAttrib::make_flat(color));
*/
_color[0] = r;
_color[1] = g;
_color[2] = b;
_color[3] = 1.0;
}
////////////////////////////////////////////////////////////////////
@ -384,6 +391,19 @@ set_color(float r, float g, float b) {
////////////////////////////////////////////////////////////////////
INLINE Colorf PolylightNode::
get_color() const {
return _color;
}
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::get_color_scenegraph
// Access: Published
// Description: This differs from get_color in that when applying
// the light color we need to make sure that a color
// flattening external to the PolylightNode is not
// ignored.
////////////////////////////////////////////////////////////////////
INLINE Colorf PolylightNode::
get_color_scenegraph() const {
const RenderAttrib *attrib =
PandaNode::get_attrib(ColorAttrib::get_class_type());
@ -394,7 +414,7 @@ get_color() const {
}
}
return Colorf(1.0f, 1.0f, 1.0f, 1.0f);
return _color;
}

View File

@ -70,36 +70,34 @@ Colorf PolylightNode::flicker() const {
float r,g,b;
Colorf color;
color = get_color();
color = get_color_scenegraph();
r = color[0];
g = color[1];
b = color[2];
float variation= 0.0;
if(_flicker_type == FRANDOM) {
if (_flicker_type == FRANDOM) {
//srand((int)ClockObject::get_global_clock()->get_frame_time());
variation = (rand()%100);// * ClockObject::get_global_clock()->get_dt();
variation /= 100.0;
//printf("Random Variation: %f\n",variation);
variation += _offset;
variation *= _scale;
}
else if(_flicker_type == FSIN) {
double now = ClockObject::get_global_clock()->get_frame_time();
variation /= 100.0;
//printf("Random Variation: %f\n",variation);
variation += _offset;
variation *= _scale;
} else if (_flicker_type == FSIN) {
double now = ClockObject::get_global_clock()->get_frame_time();
variation = sinf(now*_sin_freq);// * ClockObject::get_global_clock()->get_dt();
//printf("Variation: %f\n",variation);
variation += _offset;
variation *= _scale;
}
else if(_flicker_type == FCUSTOM) {
//printf("Variation: %f\n",variation);
variation += _offset;
variation *= _scale;
} else if (_flicker_type == FCUSTOM) {
// fixed point list of variation values coming soon...
//double index = (ClockObject::get_global_clock()->get_frame_time() % len(fixed_points)) * ClockObject::get_global_clock()->get_dt();
//index *= _speed;
/*if(!(int)index > len(fixed_points) {
variation = _fixed_points[(int)index];
variation += _offset;
variation *= _scale;
}*/
//index *= _speed;
/*if (!(int)index > len(fixed_points) {
variation = _fixed_points[(int)index];
variation += _offset;
variation *= _scale;
}*/
}
//printf("Variation: %f\n",variation);
r+=variation;
@ -107,7 +105,7 @@ Colorf PolylightNode::flicker() const {
b+=variation;
/* CLAMPING
if(fabs(r - color[0]) > 0.5 || fabs(g - color[1]) > 0.5 || fabs(b - color[2]) > 0.5) {
if (fabs(r - color[0]) > 0.5 || fabs(g - color[1]) > 0.5 || fabs(b - color[2]) > 0.5) {
r = color[0];
g = color[1];
b = color[2];
@ -126,7 +124,7 @@ Colorf PolylightNode::flicker() const {
//
// Two PolylightNodes are considered equivalent if they
// consist of exactly the same properties
// Otherwise, they are different; different
// Otherwise, they are different; different
// PolylightNodes will be ranked in a consistent but
// undefined ordering; the ordering is useful only for
// placing the PolylightNodes in a sorted container like an
@ -136,62 +134,62 @@ int PolylightNode::
compare_to(const PolylightNode &other) const {
if (_enabled != other._enabled) {
return _enabled ? 1 :-1;
return _enabled ? 1 :-1;
}
if (_radius != other._radius) {
return _radius < other._radius ? -1 :1;
return _radius < other._radius ? -1 :1;
}
LVecBase3f position = get_pos();
LVecBase3f other_position = other.get_pos();
if (position != other_position) {
return position < other_position ? -1 :1;
return position < other_position ? -1 :1;
}
Colorf color = get_color();
Colorf other_color = other.get_color();
if (color != other_color) {
return color < other_color ? -1 :1;
return color < other_color ? -1 :1;
}
if (_attenuation_type != other._attenuation_type) {
return _attenuation_type < other._attenuation_type ? -1 :1;
return _attenuation_type < other._attenuation_type ? -1 :1;
}
if (_a0 != other._a0) {
return _a0 < other._a0 ? -1 :1;
return _a0 < other._a0 ? -1 :1;
}
if (_a1 != other._a1) {
return _a1 < other._a1 ? -1 :1;
return _a1 < other._a1 ? -1 :1;
}
if (_a2 != other._a2) {
return _a2 < other._a2 ? -1 :1;
return _a2 < other._a2 ? -1 :1;
}
if (_flickering != other._flickering) {
return _flickering ? 1 :-1;
return _flickering ? 1 :-1;
}
if (_flicker_type != other._flicker_type) {
return _flicker_type < other._flicker_type ? -1 :1;
return _flicker_type < other._flicker_type ? -1 :1;
}
if (_offset != other._offset) {
return _offset < other._offset ? -1 :1;
return _offset < other._offset ? -1 :1;
}
if (_scale != other._scale) {
return _scale < other._scale ? -1 :1;
return _scale < other._scale ? -1 :1;
}
if (_step_size != other._step_size) {
return _step_size < other._step_size ? -1 :1;
return _step_size < other._step_size ? -1 :1;
}
if (_sin_freq != other._sin_freq) {
return _sin_freq < other._sin_freq ? -1 :1;
return _sin_freq < other._sin_freq ? -1 :1;
}

View File

@ -43,9 +43,9 @@ PUBLISHED:
// have a simpler constructor and require the programmer
// to use set_* methods.
PolylightNode(const string &name, float x = 0.0, float y = 0.0, float z = 0.0,
float r = 1.0, float g = 1.0, float b = 1.0,
float radius=50.0, string attenuation_type= "linear",
bool flickering =false, string flicker_type="random");
float r = 1.0, float g = 1.0, float b = 1.0,
float radius=50.0, string attenuation_type= "linear",
bool flickering =false, string flicker_type="random");
*/
enum Flicker_Type {
@ -68,6 +68,7 @@ PUBLISHED:
INLINE void set_color(Colorf color);
INLINE void set_color(float r, float g, float b);
INLINE Colorf get_color() const;
INLINE Colorf get_color_scenegraph() const;
INLINE void set_radius(float r);
INLINE float get_radius() const;
INLINE bool set_attenuation(Attenuation_Type type);
@ -107,7 +108,7 @@ public:
private:
bool _enabled;
LVecBase3f _position;
//Colorf _color;
Colorf _color;
float _radius;
Attenuation_Type _attenuation_type;
float _a0;

View File

@ -1,550 +0,0 @@
// Filename: seaPatchNode.I
// Created by: sshodhan (18Jun04)
//
////////////////////////////////////////////////////////////////////
//
// 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 .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::operator ==
// Access: Published
// Description: Returns true if the two lights are equivalent
// that is, all their properties are same
////////////////////////////////////////////////////////////////////
INLINE bool SeaPatchNode::
operator == (const SeaPatchNode &other) const {
return (compare_to(other) == 0);
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::operator !=
// Access: Published
// Description: Returns true if the two lights are not equivalent.
////////////////////////////////////////////////////////////////////
INLINE bool SeaPatchNode::
operator != (const SeaPatchNode &other) const {
return (compare_to(other) != 0);
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::operator <
// Access: Published
// Description: Returns true if this SeaPatchNode sorts before the other
// one, false otherwise. The sorting order of two
// nonequivalent SeaPatchNodes is consistent but undefined,
// and is useful only for storing SeaPatchNodes in a sorted
// container like an STL set.
////////////////////////////////////////////////////////////////////
INLINE bool SeaPatchNode::
operator < (const SeaPatchNode &other) const {
return (compare_to(other) < 0);
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::is_enabled
// Access: Published
// Description: Is this light is enabled/disabled?
////////////////////////////////////////////////////////////////////
INLINE bool SeaPatchNode::
is_enabled() const {
return _enabled;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::enable
// Access: Published
// Description: Enable this light
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
enable(){
_enabled=true;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::disable
// Access: Published
// Description: Disable this light
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
disable(){
_enabled=false;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::set_amp
// Access: Published
// Description: Set Wave Amplitude
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_amp(float amplitude) {
_amplitude = amplitude;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::set_freq
// Access: Published
// Description: Set Wave Frequency
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_freq(float frequency) {
_frequency = frequency;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::get_amp
// Access: Published
// Description: Get Wave amplitude
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_amp() const {
return _amplitude;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::get_freq
// Access: Published
// Description: Get Wave frequency
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_freq() const {
return _frequency;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::set_passive_move
// Access: Published
// Description: This is the U and V speed at which textures will
// slide in default mode. This is kind of like an
// idle cylce for the ocean water
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_passive_move(LVecBase2f UV) {
_passive_move = UV;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::get_passive_move
// Access: Published
// Description: This is the U and V speed at which textures will
// slide in default mode. This is kind of like an
// idle cylce for the ocean water
////////////////////////////////////////////////////////////////////
INLINE LVecBase2f SeaPatchNode::
get_passive_move() const {
return _passive_move;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::get_center
// Access: Published
// Description: Center for fade out effect
////////////////////////////////////////////////////////////////////
INLINE LPoint3f SeaPatchNode::
get_center() const {
return _center;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::get_radius
// Access: Published
// Description: Radius for fade out effect
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_radius() const {
return _radius;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::get_threshold
// Access: Published
// Description: Threshold for fade out effect
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_threshold() const {
return _threshold;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::set_center
// Access: Published
// Description: Center for fade out effect
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_center(LPoint3f center) {
_center = center;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::set_radius
// Access: Published
// Description: Radius for fade out effect
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_radius(float r) {
_radius = r;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::set_threshold
// Access: Published
// Description: Radius for fade out effect
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_threshold(float t) {
_threshold = t;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::set_noise_amp
// Access: Published
// Description: Set Noise Amplitude
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_noise_amp(float x) {
_noise_amp = x;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::get_noise_amp
// Access: Published
// Description: Amplitude of noise
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_noise_amp() const {
return _noise_amp;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::enable_noise_uv
// Access: Published
// Description: Apply noise to UVs
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
enable_noise_uv() {
_noise_on_uv = true;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::disable_noise_uv
// Access: Published
// Description: Disable applying noise to UVs
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
disable_noise_uv() {
_noise_on_uv = false;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::is_noise_on_uv
// Access: Published
// Description: Check if noise is on
////////////////////////////////////////////////////////////////////
INLINE bool SeaPatchNode::
is_noise_on_uv() const {
return _noise_on_uv;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::set_noise_f
// Access: Published
// Description: Set Noise Frequency
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_noise_f(float f) {
_noise_f = f;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::get_noise_f
// Access: Published
// Description: Get Noise Frequency
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_noise_f() {
return _noise_f;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::Weight
// Description:
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
Weight(float t) {
return (2.0*fabs(t)-3.0) * t*t + 1.0;
}
////////////////////////////////////////////////////////////////////
// Function: Mod
// Description: An implementation of modulo (%) that is correct for
// negative numbers.
////////////////////////////////////////////////////////////////////
INLINE int SeaPatchNode::
Mod(int quotient, int divisor) {
return (quotient >= 0) ?
(quotient % divisor) :
(divisor-1 - ((-quotient-1) % divisor));
}
////////////////////////////////////////////////////////////////////
// Function: set_xsize
// Description: A scale factor for x values to noise function
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_xsize(float xs) {
_xsize = xs;
}
////////////////////////////////////////////////////////////////////
// Function: set_ysize
// Description: A scale factor for y values to noise function
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_ysize(float ys) {
_ysize = ys;
}
////////////////////////////////////////////////////////////////////
// Function: get_xsize
// Description: A scale factor for x values to noise function
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_xsize() const {
return _xsize;
}
////////////////////////////////////////////////////////////////////
// Function: get_ysize
// Description: A scale factor for y values to noise function
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_ysize() const {
return _ysize;
}
////////////////////////////////////////////////////////////////////
// Function: set_u_scale
// Description: U coordinate computation scale
// We recompute UVs every frame based on world coords
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_u_scale(float us) {
_u_scale = us;
}
////////////////////////////////////////////////////////////////////
// Function: set_v_scale
// Description: V coordinate computation scale
// We recompute UVs every frame based on world coords
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_v_scale(float vs) {
_v_scale = vs;
}
////////////////////////////////////////////////////////////////////
// Function: get_u_scale
// Description: U coordinate computation scale
// We recompute UVs every frame based on world coords
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_u_scale() const {
return _u_scale;
}
////////////////////////////////////////////////////////////////////
// Function: get_v_scale
// Description: V coordinate computation scale
// We recompute UVs every frame based on world coords
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_v_scale() const {
return _v_scale;
}
////////////////////////////////////////////////////////////////////
// Function: get_height
// Description: Get the height of any point in the grid
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_height(float x, float y) const {
return ((sin(_wave_movement + (x / _wavelength[0]) )
+ sin(_wave_movement + (y / _wavelength[1]))) * _amplitude);
}
////////////////////////////////////////////////////////////////////
// Function: get_normal
// Description: return the normal to any point in the grid
////////////////////////////////////////////////////////////////////
INLINE LVecBase3f SeaPatchNode::
get_normal(float x, float y) const {
float h, h1, h2;
h = get_height(x,y);
h1 = get_height(x - 0.3, y + 0.2);
h2 = get_height(x - 0.4, y - 0.1);
LVecBase3f a,b,N,s,a1, b1;
a[0] = x - 0.3;
a[1] = y + 0.2;
a[2] = h1;
b[0] = x - 0.4;
b[1] = y - 0.1;
b[2] = h2;
s[0] = x;
s[1] = y;
s[2] = h;
a1 = a - s;
b1 = b - s;
N = cross(a1,b1);
float length = (float)sqrt(N[0]*N[0] + N[1]*N[1] + N[2]*N[2]);
if(length == 0.0) {
length = 1.0;
}
N[0] /= length;
N[1] /= length;
N[2] /= length;
return N;
}
////////////////////////////////////////////////////////////////////
// Function: set_cscale
// Description: Color scale for the vertex color... its just an
// additive term
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_cscale(float cs) {
_color_scale = cs;
}
////////////////////////////////////////////////////////////////////
// Function: set_ascale
// Description: Alpha scale for the vertex color... its just an
// additive term
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_ascale(float as) {
_alpha_scale = as;
}
////////////////////////////////////////////////////////////////////
// Function: get_cscale
// Description: Color scale for the vertex color... its just an
// additive term
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_cscale() const {
return _color_scale;
}
////////////////////////////////////////////////////////////////////
// Function: get_ascale
// Description: Alpha scale for the vertex color... its just an
// additive term
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_ascale() const {
return _alpha_scale;
}
////////////////////////////////////////////////////////////////////
// Function: set_light_color
// Description: Vertex color has an additive light component
// Contributes 1/3 of the color
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_light_color(Colorf c) {
_light_color = c;
}
////////////////////////////////////////////////////////////////////
// Function: get_light_color
// Description: Vertex color has an additive light component
// Contributes 1/3 of the color
////////////////////////////////////////////////////////////////////
INLINE Colorf SeaPatchNode::
get_light_color() const {
return _light_color;
}
////////////////////////////////////////////////////////////////////
// Function: get_u_sin_scale
// Description: Pass a sin wave through the UV scaling
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_u_sin_scale() const {
return _u_sin_scale;
}
////////////////////////////////////////////////////////////////////
// Function: get_v_sin_scale
// Description: Pass a sin wave through the UV scaling
////////////////////////////////////////////////////////////////////
INLINE float SeaPatchNode::
get_v_sin_scale() const {
return _v_sin_scale;
}
////////////////////////////////////////////////////////////////////
// Function: set_u_sin_scale
// Description: Pass a sin wave through the UV scaling
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_u_sin_scale(float s) {
_u_sin_scale = s;
}
////////////////////////////////////////////////////////////////////
// Function: set_u_sin_scale
// Description: Pass a sin wave through the UV scaling
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_v_sin_scale(float s) {
_v_sin_scale = s;
}
////////////////////////////////////////////////////////////////////
// Function: get_wavelength
// Description: Get the wavelength dividing factor
////////////////////////////////////////////////////////////////////
INLINE LVecBase2f SeaPatchNode::
get_wavelength() const {
return _wavelength;
}
////////////////////////////////////////////////////////////////////
// Function: set_wavelength
// Description: Set the wavelength dividing factor
////////////////////////////////////////////////////////////////////
INLINE void SeaPatchNode::
set_wavelength(LVecBase2f w) {
_wavelength = w;
}

View File

@ -1,472 +0,0 @@
// Filename: seaPatchNode.cxx
// Created by: sshodhan (18Jun04)
//
////////////////////////////////////////////////////////////////////
//
// 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 "config_pgraph.h"
#include "nodePath.h"
#include "clockObject.h"
#include "dcast.h"
#include "cullTraverserData.h"
#include "cullTraverser.h"
#include "seaPatchNode.h"
#include "geomNode.h"
#include "geom.h"
#include <math.h>
TypeHandle SeaPatchNode::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::Constructor
// Access: Published
// Description: Use SeaPatchNode() to construct a new
// SeaPatchNode object.
////////////////////////////////////////////////////////////////////
SeaPatchNode::
SeaPatchNode(const string &name) :
PandaNode(name)
{
// center
LPoint3f c;
c[0] = 0.0;
c[1] = 0.0;
c[2] = 0.0;
_center = c;
_enabled = true;
// continuously increasing parameter to advance the wave
_wave_movement = 0.0;
_wavelength = 25.0;
_amplitude = 0.05;
_frequency = 0.01;
// from threshold -> radius the waves will fade out
_radius = 100.0;
_threshold = 80.0;
// sliding of UVs
_passive_move[0] = 0.0001;
_passive_move[1] = 0.0001;
// UV noise
_noise_amp = 0.001;
_noise_on_uv = true;
_noise_f = 10.0;
_noise_detail = 4;
_xsize = 256.0;
_ysize = 256.0;
_u_scale = 256.0;
_v_scale = 256.0;
_u_sin_scale = 1/100.0;
_v_sin_scale = 1/100.0;
// randomize noise tables
noise_init();
// shading
_alpha_scale = 1.0;
_color_scale = 1.0;
_light_color = Colorf(0.2, 0.4, 0.6, 1.0);
_alpha_mode = ANONE;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::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 SeaPatchNode::
has_cull_callback() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::cull_callback
// Access: Public, Virtual
// Description: If has_cull_callback() returns true, this function
// will be called during the cull traversal to perform
// any additional operations that should be performed at
// cull time. This may include additional manipulation
// of render state or additional visible/invisible
// decisions, or any other arbitrary operation.
//
// By the time this function is called, the node has
// already passed the bounding-volume test for the
// viewing frustum, and the node's transform and state
// have already been applied to the indicated
// CullTraverserData object.
//
// The return value is true if this node should be
// visible, or false if it should be culled.
////////////////////////////////////////////////////////////////////
bool SeaPatchNode::
cull_callback(CullTraverser *trav, CullTraverserData &data) {
PandaNode *node = data.node(); // Get SeaPatchNode
// Get net transoformation matrix
LMatrix4f net_trans_mat =
data._node_path.get_node_path().get_net_transform()->get_mat();
if(is_enabled()) {
// Go through all the children, find Geom nodes and pass waves
recurse_children(node,net_trans_mat);
// Advance the wave for all children
_wave_movement += _frequency; // Advance the wave
}
// Continue traversal
int num_children = node->get_num_children();
for(int i = 0; i < num_children; i++) {
CullTraverserData child_data(data, node->get_child(i));
trav->traverse(child_data);
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::recurse_children
// Access: Published
// Description: Dig out the GeomNodes and do_wave on them
////////////////////////////////////////////////////////////////////
void SeaPatchNode::
recurse_children(PandaNode *node, LMatrix4f net_trans_mat) {
if (node->is_of_type(GeomNode::get_class_type())) {
GeomNode *geom_node = DCAST(GeomNode, node);
int num_geoms = geom_node->get_num_geoms();
for(int j =0; j < num_geoms; j++) {
PT(Geom) geom = geom_node->get_geom(j);
do_wave(geom, net_trans_mat);
}
}
PandaNode::Children cr = node->get_children();
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
recurse_children(cr.get_child(i), net_trans_mat);
}
}
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::do_wave
// Access: Published
// Description: pass sine wave through geometry
// add UV noise and movement
// apply vertex color based shading
////////////////////////////////////////////////////////////////////
void SeaPatchNode::
do_wave(Geom * geom, LMatrix4f net_trans_mat) {
float dist;
unsigned int num_vertices = geom->get_num_vertices();
PTA_ushort vindex;
PTA_ushort tindex;
PTA_ushort cindex;
PTA_ushort nindex;
PTA_Vertexf vert;
PTA_TexCoordf texc;
PTA_Colorf colors;
PTA_Normalf norms;
Colorf c;
GeomBindType btypet;
float u = 0.0, v = 0.0;
float unoise,vnoise;
float height_change;
// Get vertices and UVs
geom->get_coords(vert, vindex);
geom->get_texcoords(texc, btypet, tindex);
for (unsigned int k = 0; k < num_vertices; k++) { // For all vertices
LPoint3f V = vert[k] * net_trans_mat; // multiply with net transform
LPoint3f new_center = _center * net_trans_mat;
height_change = (sin(_wave_movement + (V[0] / _wavelength[0]) )
+ sin(_wave_movement + (V[1] / _wavelength[1]))) * _amplitude; // Do the wave
// need this distance for fading out waves
// ** add fading out to getHeight function
dist = (float) sqrt( pow(V[0] - new_center[0],2) + pow(V[1] - new_center[1],2));
if(dist > _threshold) {
if(dist >= _radius) {
vert[k][2] = 0.0; // completely faded out
}
else {
vert[k][2] = height_change * ((_radius - dist)/ _radius); // linear fade
}
}
else {
vert[k][2] = height_change;
}
// Recompute normals based on height
norms.push_back(get_normal(V[0],V[1]));
nindex.push_back(k);
geom->set_normals(norms, G_PER_VERTEX, nindex);
// Vertex color based shading
// ** add shade_mode (high, low , all, none)
c[0] = (_color_scale + _light_color[0] + (height_change / (2 * _amplitude)))/3.0;
c[1] = (_color_scale + _light_color[1] + (height_change / (2 * _amplitude)))/3.0;
c[2] = (_color_scale + _light_color[2] + (height_change / (2 * _amplitude)))/3.0;
if(_alpha_mode == AHIGH) {
c[3] = (_alpha_scale + _light_color[3] + (1.0 - (height_change / (2 * _amplitude))))/3.0;
}
else if(_alpha_mode == ALOW) {
c[3] = (_alpha_scale + _light_color[3] + (height_change / (2 * _amplitude)))/3.0;
}
else if(_alpha_mode == ATOTAL) {
c[3] = (_alpha_scale + _light_color[3]) /2.0;
}
else if(_alpha_mode == ANONE) {
c[3] = 1.0;
}
colors.push_back(c);
cindex.push_back(k);
// UV COMPUTATION
// Divide vertex X and Y coords by some scale
// Also, pass sin wave through the scale for UV scaling
// ** Need to make this transform independant
_u_scale += sin (_wave_movement) * _u_sin_scale;
_v_scale += sin (_wave_movement) * _v_sin_scale;
if(_u_scale == 0) {
_u_scale = 1;
}
if(_v_scale == 0) {
_v_scale = 1;
}
u = V[0] / _u_scale;
v = V[1] / _v_scale;
// UV Noise (using the DQ Pirates noise function)
if(_noise_on_uv) {
unoise = do_noise(V[0], V[1], ClockObject::get_global_clock()->get_frame_time(), 0);
vnoise = do_noise(V[0], V[1], ClockObject::get_global_clock()->get_frame_time(), 1);
u += unoise;
v += vnoise;
}
// Texture sliding
texc[k][0] = u + _move_variable[0];
texc[k][1] = v + _move_variable[1];
}
// Apply vertex shading
geom->set_colors (colors, G_PER_VERTEX , cindex);
_move_variable[0] += _passive_move[0];
_move_variable[1] += _passive_move[1];
if(_move_variable[0] > 1.0) {
_move_variable[0] = 0.0;
}
if(_move_variable[1] > 1.0) {
_move_variable[1] = 0.0;
}
}
////////////////////////////////////////////////////////////////////
// Function: NoiseWave::Constructor
// Access: Public, Scheme
// Description: Initialize noise permutation and gradient table
// This function is adapted from the old DQ pirates code
// Everything is done for both U and V noise
////////////////////////////////////////////////////////////////////
void SeaPatchNode::
noise_init() {
int i, j, k, t;
// Randomize the permutation table.
// U TABLE
for (i = 0; i < noise_table_size; i++) {
_perm_tab_u[i] = i;
}
for (i = 0; i < (noise_table_size / 2); i++) {
j = rand() % noise_table_size;
k = rand() % noise_table_size;
t = _perm_tab_u[j];
_perm_tab_u[j] = _perm_tab_u[k];
_perm_tab_u[k] = t;
}
// Randomize the permutation table.
// V TABLE
for (i = 0; i < noise_table_size; i++) {
_perm_tab_v[i] = i;
}
for (i = 0; i < (noise_table_size / 2); i++) {
j = rand() % noise_table_size;
k = rand() % noise_table_size;
t = _perm_tab_v[j];
_perm_tab_v[j] = _perm_tab_v[k];
_perm_tab_v[k] = t;
}
// Choose a number of random unit vectors for the gradient table.
// U TABLE
for (i = 0; i < noise_table_size; i++) {
float m_u;
do {
_grad_tab_u[i][0] = (float)(rand() - (RAND_MAX / 2)) / (RAND_MAX / 2);
_grad_tab_u[i][1] = (float)(rand() - (RAND_MAX / 2)) / (RAND_MAX / 2);
_grad_tab_u[i][2] = (float)(rand() - (RAND_MAX / 2)) / (RAND_MAX / 2);
m_u = _grad_tab_u[i].dot(_grad_tab_u[i]);
} while (m_u == 0.0 || m_u > 1.0);
_grad_tab_u[i] /= sqrt(m_u);
}
// Choose a number of random unit vectors for the gradient table.
// V TABLE
for (i = 0; i < noise_table_size; i++) {
float m_v;
do {
_grad_tab_v[i][0] = (float)(rand() - (RAND_MAX / 2)) / (RAND_MAX / 2);
_grad_tab_v[i][1] = (float)(rand() - (RAND_MAX / 2)) / (RAND_MAX / 2);
_grad_tab_v[i][2] = (float)(rand() - (RAND_MAX / 2)) / (RAND_MAX / 2);
m_v = _grad_tab_v[i].dot(_grad_tab_v[i]);
} while (m_v == 0.0 || m_v > 1.0);
_grad_tab_v[i] /= sqrt(m_v);
}
}
////////////////////////////////////////////////////////////////////
// Function: NoiseWave::PlainNoise
// Access: Protected
// Description: 3D noise function
// Takes x, y position , time, some scale s
// uvi determines if its U noise or V noise
////////////////////////////////////////////////////////////////////
float SeaPatchNode::
plain_noise(float x, float y, float z, unsigned int s, int uvi ) {
x *= s;
y *= s;
z *= s;
int a = (int)floor(x);
int b = (int)floor(y);
int c = (int)floor(z);
float sum = 0.0;
int i, j, k;
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
for (k = 0; k < 2; k++) {
if(uvi ==0 ) {
int n_u = _perm_tab_u[Mod(c + k,noise_table_size)];
n_u = _perm_tab_u[Mod(b + j + n_u , noise_table_size)];
n_u = _perm_tab_u[Mod(a + i + n_u , noise_table_size)];
LVecBase3f v_u(x - a - i, y - b - j, z - c - k);
sum += Weight(v_u[0]) * Weight(v_u[1]) * Weight(v_u[2]) *
(_grad_tab_u[n_u].dot(v_u));
}
else {
int n_v = _perm_tab_v[Mod(c + k , noise_table_size)];
n_v = _perm_tab_v[Mod(b + j + n_v , noise_table_size)];
n_v = _perm_tab_v[Mod(a + i + n_v , noise_table_size)];
LVecBase3f v_v(x - a - i, y - b - j, z - c - k);
sum += Weight(v_v[0]) * Weight(v_v[1]) * Weight(v_v[2]) *
(_grad_tab_v[n_v].dot(v_v));
}
}
}
}
return sum / s;
}
////////////////////////////////////////////////////////////////////
// Function: NoiseWave::do_noise
// Access: Protected
// Description: Based on detail additively compute various level
// of detail noises
////////////////////////////////////////////////////////////////////
float SeaPatchNode::
do_noise(float x, float y, float t, int uvi) {
unsigned int s = 1;
x /= _xsize;
y /= _ysize;
t *= _noise_f * 0.1;
float sum = 0.0;
int i;
for (i = 0; i <= _noise_detail; i++) {
sum += plain_noise(x, y, t, s, uvi);
s *= 2;
}
return sum * _noise_amp;
}
////////////////////////////////////////////////////////////////////
// Function: set_alpha_mode
// Description: Alpha Modes are AHIGH, ALOW, ATOTAL, ANONE
// high and low are height based affecting high and low
// points respectively. total affects all vertices
// none is no alpha. you have to manually setTransparency
////////////////////////////////////////////////////////////////////
void SeaPatchNode::
set_alpha_mode(Alpha_Type a) {
_alpha_mode = a;
}
// ** IMPLEMENT compare_to properly once API is more finalized
////////////////////////////////////////////////////////////////////
// Function: SeaPatchNode::compare_to
// Access: Published
// Description: Returns a number less than zero if this SeaPatchNode
// sorts before the other one, greater than zero if it
// sorts after, or zero if they are equivalent.
//
// Two SeaPatchNodes are considered equivalent if they
// consist of exactly the same properties
// Otherwise, they are different; different
// SeaPatchNodes will be ranked in a consistent but
// undefined ordering; the ordering is useful only for
// placing the SeaPatchNodes in a sorted container like an
// STL set.
////////////////////////////////////////////////////////////////////
int SeaPatchNode::
compare_to(const SeaPatchNode &other) const {
if (_enabled != other._enabled) {
return _enabled ? 1 :-1;
}
if (_wave_movement != other._wave_movement) {
return _wave_movement < other._wave_movement ? -1 : 1;
}
return 0;
}

View File

@ -1,185 +0,0 @@
// Filename: seaPatchNode.h
// Created by: sshodhan (18Jun04)
//
////////////////////////////////////////////////////////////////////
//
// 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 SEAPATCHNODE_H
#define SEAPATCHNODE_H
#include "pandabase.h"
#include "luse.h"
#include "nodePath.h"
#include "pmap.h"
#include "notify.h"
#include "pandaNode.h"
#include "geom.h"
#include "geomNode.h"
#include "pmap.h"
#include "lvecBase3.h"
static const int noise_table_size = 64;
////////////////////////////////////////////////////////////////////
// Class : SeaPatchNode
// Description : A SeaPatchNode
// Modeled after the old DQ SeaPatchNode
// Any Geometry parented to a SeaPatchNode will have
// - waves
// - UV noise and transforms
// - vertex color and height based shading
// Looking to work on:
// - multiple sine waves at different resolutions (for base waves
// and detail waves)
// - independant control over multiple layers parented to the same
// SeaPatchNode (or should this just be done through multiple
// copies of the SeaPatchNode? Need to make copy constructor and =
// - perturbing normals (bump mapping, pixel level stuff?)
// - wakes, decals
// - damping floating objects
// - reflecting things like a flaming ship, torches, sun, moon
// - tiling to make ocean
// - offload UV manipulation to texture matrix?
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA SeaPatchNode : public PandaNode{
PUBLISHED:
enum Alpha_Type {
AHIGH,
ALOW,
ATOTAL,
ANONE,
};
SeaPatchNode(const string &name);
INLINE void enable();
INLINE void disable();
INLINE bool is_enabled() const;
// Comparison methods
INLINE bool operator == (const SeaPatchNode &other) const;
INLINE bool operator != (const SeaPatchNode &other) const;
INLINE bool operator < (const SeaPatchNode &other) const;
int compare_to(const SeaPatchNode &other) const;
INLINE void set_amp(float amplitude);
INLINE void set_freq(float frequency);
INLINE float get_amp() const;
INLINE float get_freq() const;
INLINE LVecBase2f get_wavelength() const;
INLINE void set_wavelength(LVecBase2f w);
INLINE void set_passive_move(LVecBase2f UV);
INLINE LVecBase2f get_passive_move() const;
INLINE LPoint3f get_center() const;
INLINE float get_radius() const;
INLINE float get_threshold() const;
INLINE void set_center(LPoint3f center);
INLINE void set_radius(float r);
INLINE void set_threshold(float t);
INLINE void set_noise_amp(float x);
INLINE float get_noise_amp() const;
INLINE void enable_noise_uv();
INLINE void disable_noise_uv();
INLINE bool is_noise_on_uv() const;
INLINE void set_noise_f(float f);
INLINE float get_noise_f();
INLINE float Weight(float t) ;
INLINE int Mod(int quotient, int divisor);
INLINE void set_xsize(float xs);
INLINE void set_ysize(float ys);
INLINE float get_xsize() const;
INLINE float get_ysize() const;
INLINE void set_u_scale(float us);
INLINE void set_v_scale(float vs);
INLINE float get_u_scale() const;
INLINE float get_v_scale() const;
INLINE float get_height(float x, float y) const;
INLINE void set_cscale(float cs);
INLINE void set_ascale(float as);
INLINE float get_cscale() const;
INLINE float get_ascale() const;
INLINE LVecBase3f get_normal(float x, float y) const;
INLINE void set_light_color(Colorf c);
INLINE Colorf get_light_color() const;
INLINE float get_u_sin_scale() const;
INLINE float get_v_sin_scale() const;
INLINE void set_u_sin_scale(float s);
INLINE void set_v_sin_scale(float s);
void set_alpha_mode(Alpha_Type a);
private:
bool _enabled;
float _wave_movement;
float _amplitude;
float _frequency;
LVecBase2f _wavelength;
LVecBase2f _passive_move;
LVecBase2f _move_variable;
LPoint3f _center;
float _radius;
float _noise_amp;
bool _noise_on_uv;
float _noise_f;
int _perm_tab_u[noise_table_size];
LVecBase3f _grad_tab_u[noise_table_size];
int _perm_tab_v[noise_table_size];
LVecBase3f _grad_tab_v[noise_table_size];
int _noise_detail;
float _xsize;
float _ysize;
float _u_scale;
float _v_scale;
float _color_scale;
float _alpha_scale;
Colorf _light_color;
float _u_sin_scale;
float _v_sin_scale;
float _threshold;
Alpha_Type _alpha_mode;
public:
virtual bool has_cull_callback() const;
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
void recurse_children(PandaNode *node, LMatrix4f mat);
void do_wave(Geom *geom, LMatrix4f mat);
void noise_init();
float plain_noise(float x, float y, float z, unsigned int s, int uvi );
float do_noise(float x, float y, float t, int uvi);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
PandaNode::init_type();
register_type(_type_handle, "SeaPatchNode",
PandaNode::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "seaPatchNode.I"
#endif