Panda3D

fog.cxx

00001 // Filename: fog.cxx
00002 // Created by:  drose (14Mar02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "pandabase.h"
00016 
00017 #include "fog.h"
00018 
00019 #include "mathNumbers.h"
00020 #include "nodePath.h"
00021 #include "transformState.h"
00022 #include "bamReader.h"
00023 #include "bamWriter.h"
00024 #include "datagram.h"
00025 #include "datagramIterator.h"
00026 
00027 #include <stddef.h>
00028 
00029 TypeHandle Fog::_type_handle;
00030 
00031 ostream &
00032 operator << (ostream &out, Fog::Mode mode) {
00033   switch (mode) {
00034   case Fog::M_linear:
00035     return out << "linear";
00036 
00037   case Fog::M_exponential:
00038     return out << "exponential";
00039 
00040   case Fog::M_exponential_squared:
00041     return out << "exponential-squared";
00042   }
00043 
00044   return out << "**invalid**(" << (int)mode << ")";
00045 }
00046 
00047 ////////////////////////////////////////////////////////////////////
00048 //     Function: Fog::Constructor
00049 //       Access: Published
00050 //  Description:
00051 ////////////////////////////////////////////////////////////////////
00052 Fog::
00053 Fog(const string &name) : 
00054   PandaNode(name) 
00055 {
00056   _mode = M_linear;
00057   _color.set(1.0f, 1.0f, 1.0f, 1.0f);
00058   _linear_onset_point.set(0.0f, 0.0f, 0.0f);
00059   _linear_opaque_point.set(0.0f, 100.0f, 0.0f);
00060   _exp_density = 0.5f;
00061   _linear_fallback_cosa = -1.0f;
00062   _linear_fallback_onset = 0.0f;
00063   _linear_fallback_opaque = 0.0f;
00064   _transformed_onset = 0.0f;
00065   _transformed_opaque = 0.0f;
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: Fog::Copy Constructor
00070 //       Access: Protected
00071 //  Description:
00072 ////////////////////////////////////////////////////////////////////
00073 Fog::
00074 Fog(const Fog &copy) :
00075   PandaNode(copy)
00076 {
00077   _mode = copy._mode;
00078   _color = copy._color;
00079   _linear_onset_point = copy._linear_onset_point;
00080   _linear_opaque_point = copy._linear_opaque_point;
00081   _exp_density = copy._exp_density;
00082   _linear_fallback_cosa = copy._linear_fallback_cosa;
00083   _linear_fallback_onset = copy._linear_fallback_onset;
00084   _linear_fallback_opaque = copy._linear_fallback_opaque;
00085   _transformed_onset = copy._transformed_onset;
00086   _transformed_opaque = copy._transformed_opaque;
00087 }
00088 
00089 ////////////////////////////////////////////////////////////////////
00090 //     Function: Fog::Destructor
00091 //       Access: Public, Virtual
00092 //  Description:
00093 ////////////////////////////////////////////////////////////////////
00094 Fog::
00095 ~Fog() {
00096 }
00097 
00098 ////////////////////////////////////////////////////////////////////
00099 //     Function: Fog::make_copy
00100 //       Access: Public, Virtual
00101 //  Description: Returns a newly-allocated Node that is a shallow copy
00102 //               of this one.  It will be a different Node pointer,
00103 //               but its internal data may or may not be shared with
00104 //               that of the original Node.
00105 ////////////////////////////////////////////////////////////////////
00106 PandaNode *Fog::
00107 make_copy() const {
00108   return new Fog(*this);
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //     Function: Fog::xform
00113 //       Access: Public, Virtual
00114 //  Description: Transforms the contents of this node by the indicated
00115 //               matrix, if it means anything to do so.  For most
00116 //               kinds of nodes, this does nothing.
00117 ////////////////////////////////////////////////////////////////////
00118 void Fog::
00119 xform(const LMatrix4 &mat) {
00120   _linear_onset_point = _linear_onset_point * mat;
00121   _linear_opaque_point = _linear_opaque_point * mat;
00122 }
00123 
00124 ////////////////////////////////////////////////////////////////////
00125 //     Function: Fog::output
00126 //       Access: Public
00127 //  Description:
00128 ////////////////////////////////////////////////////////////////////
00129 void Fog::
00130 output(ostream &out) const {
00131   out << "fog: " << _mode;
00132   switch (_mode) {
00133   case M_linear:
00134     out << "(" << _linear_onset_point << ") -> ("
00135         << _linear_opaque_point << ")";
00136     break;
00137 
00138   case M_exponential:
00139   case M_exponential_squared:
00140     out << _exp_density;
00141     break;
00142   };
00143 }
00144 
00145 ////////////////////////////////////////////////////////////////////
00146 //     Function: Fog::adjust_to_camera
00147 //       Access: Public
00148 //  Description: This function is intended to be called by the cull
00149 //               traverser to compute the appropriate camera-relative
00150 //               onset and opaque distances, based on the fog node's
00151 //               position within the scene graph (if linear fog is in
00152 //               effect).
00153 ////////////////////////////////////////////////////////////////////
00154 void Fog::
00155 adjust_to_camera(const TransformState *camera_transform) {
00156   LVector3 forward = LVector3::forward();
00157 
00158   LPoint3 onset_point, opaque_point;
00159   if (get_num_parents() != 0) {
00160     // Linear fog is relative to the fog's net transform in the scene
00161     // graph.
00162     NodePath this_np(this);
00163 
00164     CPT(TransformState) rel_transform = 
00165       camera_transform->invert_compose(this_np.get_net_transform());
00166     
00167     const LMatrix4 &mat = rel_transform->get_mat();
00168 
00169     // How far out of whack are we?
00170     LVector3 fog_vector = (_linear_opaque_point - _linear_onset_point) * mat;
00171     fog_vector.normalize();
00172     PN_stdfloat cosa = fog_vector.dot(forward);
00173     if (cabs(cosa) < _linear_fallback_cosa) {
00174       // The fog vector is too far from the eye vector; use the
00175       // fallback mode.
00176       _transformed_onset = _linear_fallback_onset;
00177       _transformed_opaque = _linear_fallback_opaque;
00178 
00179     } else {
00180       _transformed_onset = forward.dot(_linear_onset_point * mat);
00181       _transformed_opaque = forward.dot(_linear_opaque_point * mat);
00182     }
00183 
00184   } else {
00185     // Not a camera-relative fog.
00186     _transformed_onset = forward.dot(_linear_onset_point);
00187     _transformed_opaque = forward.dot(_linear_opaque_point);
00188   }
00189 }
00190 
00191 ////////////////////////////////////////////////////////////////////
00192 //     Function: Fog::get_linear_range
00193 //       Access: Public
00194 //  Description: Retrieves the current onset and offset ranges.
00195 ////////////////////////////////////////////////////////////////////
00196 void Fog::
00197 get_linear_range(PN_stdfloat &onset, PN_stdfloat &opaque) {
00198   onset = _transformed_onset;
00199   opaque = _transformed_opaque;
00200 }
00201 
00202 ////////////////////////////////////////////////////////////////////
00203 //     Function: Fog::register_with_read_factory
00204 //       Access: Public, Static
00205 //  Description: Tells the BamReader how to create objects of type
00206 //               Fog.
00207 ////////////////////////////////////////////////////////////////////
00208 void Fog::
00209 register_with_read_factory() {
00210   BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00211 }
00212 
00213 ////////////////////////////////////////////////////////////////////
00214 //     Function: Fog::write_datagram
00215 //       Access: Public, Virtual
00216 //  Description: Writes the contents of this object to the datagram
00217 //               for shipping out to a Bam file.
00218 ////////////////////////////////////////////////////////////////////
00219 void Fog::
00220 write_datagram(BamWriter *manager, Datagram &dg) {
00221   PandaNode::write_datagram(manager, dg);
00222 
00223   dg.add_int8(_mode);
00224   _color.write_datagram(dg);
00225   _linear_onset_point.write_datagram(dg);
00226   _linear_opaque_point.write_datagram(dg);
00227   dg.add_stdfloat(_exp_density);
00228   dg.add_stdfloat(_linear_fallback_cosa);
00229   dg.add_stdfloat(_linear_fallback_onset);
00230   dg.add_stdfloat(_linear_fallback_opaque);
00231 }
00232 
00233 ////////////////////////////////////////////////////////////////////
00234 //     Function: Fog::make_from_bam
00235 //       Access: Protected, Static
00236 //  Description: This function is called by the BamReader's factory
00237 //               when a new object of type Fog is encountered
00238 //               in the Bam file.  It should create the Fog
00239 //               and extract its information from the file.
00240 ////////////////////////////////////////////////////////////////////
00241 TypedWritable *Fog::
00242 make_from_bam(const FactoryParams &params) {
00243   Fog *node = new Fog("");
00244   DatagramIterator scan;
00245   BamReader *manager;
00246 
00247   parse_params(params, scan, manager);
00248   node->fillin(scan, manager);
00249 
00250   return node;
00251 }
00252 
00253 ////////////////////////////////////////////////////////////////////
00254 //     Function: Fog::fillin
00255 //       Access: Protected
00256 //  Description: This internal function is called by make_from_bam to
00257 //               read in all of the relevant data from the BamFile for
00258 //               the new Fog.
00259 ////////////////////////////////////////////////////////////////////
00260 void Fog::
00261 fillin(DatagramIterator &scan, BamReader *manager) {
00262   PandaNode::fillin(scan, manager);
00263 
00264   _mode = (Mode)scan.get_int8();
00265   _color.read_datagram(scan);
00266   _linear_onset_point.read_datagram(scan);
00267   _linear_opaque_point.read_datagram(scan);
00268   _exp_density = scan.get_stdfloat();
00269   _linear_fallback_cosa = scan.get_stdfloat();
00270   _linear_fallback_onset = scan.get_stdfloat();
00271   _linear_fallback_opaque = scan.get_stdfloat();
00272 }
 All Classes Functions Variables Enumerations