Remove the 'old' 3D clouds code.

This commit is contained in:
ehofman
2005-06-25 11:22:06 +00:00
parent 095367f760
commit 8e0ecbeb8f
70 changed files with 0 additions and 20921 deletions

View File

@@ -425,7 +425,6 @@ AC_CONFIG_FILES([ \
simgear/scene/material/Makefile \
simgear/scene/model/Makefile \
simgear/scene/sky/Makefile \
simgear/scene/sky/clouds3d/Makefile \
simgear/scene/tgdb/Makefile \
simgear/screen/Makefile \
simgear/serial/Makefile \

View File

@@ -1,7 +1,5 @@
includedir = @includedir@/scene/sky
SUBDIRS = clouds3d
lib_LIBRARIES = libsgsky.a
include_HEADERS = \

View File

@@ -1,54 +0,0 @@
includedir = @includedir@/scene/sky/clouds3d
# enable the following line once extgl.c get's added to the distro
EXTRA_DIST = extgl.c extgl.h
if EXTGL_NEEDED
EXTGL_SOURCE = extgl.c extgl.h
else
EXTGL_SOURCE =
endif
lib_LIBRARIES = libsgclouds3d.a
include_HEADERS = \
SkySceneLoader.hpp \
SkyUtil.hpp
libsgclouds3d_a_SOURCES = \
$(EXTGL_SOURCE) \
vec3fv.cpp vec3fv.hpp vec3f.hpp vec4f.hpp vec2f.hpp \
mat16fv.cpp mat16fv.hpp \
mat33.hpp mat33impl.hpp \
mat44.hpp mat44impl.hpp \
tri.cpp tri.hpp \
plane.cpp plane.hpp \
camera.cpp camera.hpp \
camutils.cpp camutils.hpp \
glut_shapes.c glut_shapes.h \
minmaxbox.cpp minmaxbox.hpp \
SkyAABBTree.hpp \
SkyArchive.cpp SkyArchive.hpp \
SkyBoundingVolume.hpp \
SkyBVTree.hpp SkyBVTreeSplitter.hpp \
SkyCloud.cpp SkyCloud.hpp \
SkyCloudParticle.hpp \
SkyContext.cpp SkyContext.hpp \
SkyDynamicTextureManager.cpp SkyDynamicTextureManager.hpp \
SkyLight.cpp SkyLight.hpp \
SkyMaterial.cpp SkyMaterial.hpp \
SkyMinMaxBox.cpp SkyMinMaxBox.hpp \
SkyRenderable.hpp \
SkyRenderableInstance.hpp \
SkyRenderableInstanceCloud.cpp SkyRenderableInstanceCloud.hpp \
SkyRenderableInstanceGeneric.hpp \
SkyRenderableInstanceGroup.cpp SkyRenderableInstanceGroup.hpp \
SkySceneLoader.cpp \
SkySceneManager.cpp SkySceneManager.hpp \
SkySingleton.hpp \
SkyTexture.hpp \
SkyTextureManager.cpp SkyTextureManager.hpp \
SkyTextureState.cpp SkyTextureState.hpp \
SkyUtil.cpp
INCLUDES = -I$(top_srcdir)

View File

@@ -1,19 +0,0 @@
//============================================================================
// File : SkyAABBTree.hpp
//
// Author : Wesley Hunt
//
// Content : axis-aligned bounding box tree
//
//============================================================================
#ifndef __SKYAABBTREE_HPP__
#define __SKYAABBTREE_HPP__
#include "SkyBVTree.hpp"
#include "SkyBVTreeSplitter.hpp"
template <class object>
class SkyAABBTree : public SkyBVTree<object, SkyMinMaxBox, SkyAABBTreeSplitter<object> >
{};
#endif //__SKYAABBTREE_HPP__

File diff suppressed because it is too large Load Diff

View File

@@ -1,243 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyArchive.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyArchive.hpp
*
* A hierarchical archive Class for storing data.
*/
#ifndef __SKYARCHIVE_HPP__
#define __SKYARCHIVE_HPP__
// #pragma warning( disable : 4786 )
#include "vec2f.hpp"
#include "vec3f.hpp"
#include "vec4f.hpp"
#include "SkyUtil.hpp"
#include <map> // for std::multimap
//! Types supported by the archive system
enum SkyArchiveTypeCode
{
BOOL_TYPE,
INT8_TYPE,
INT16_TYPE,
INT32_TYPE,
UINT8_TYPE,
UINT16_TYPE,
UINT32_TYPE,
FLOAT32_TYPE,
FLOAT64_TYPE,
STRING_TYPE,
VEC2F_TYPE,
VEC3F_TYPE,
VEC4F_TYPE,
ARCHIVE_TYPE,
ANY_TYPE,
NULL_TYPE
};
struct SkyArchiveEntry;
struct StringLessFunctor
{
bool operator() (const char* p1, const char* p2) const
{
return ::strcmp( p1, p2) < 0;
}
};
//============================================================================
//
// Class : SkyArchive
//
//! A simple hierarchical archive file useful for loading and saving data.
//
/*! SkyArchive bundles information so that an application can store,
manipulate, and retrieve data in a storage-independent manner. Information
stored in an SkyArchive file can be modified without breaking
compatibility with the code that retrieves the data. In essence, it can be
thought of as a very basic database mechanism.
A SkyArchive is simply a container. The class defines methods that allow
you to put information in a SkyArchive, determine the information in a
SkyArchive, and retrieve information from a SkyArchive. It's important
to note that the SkyArchive is a recursive storage mechanism; a
SkyArchive itself can hold one or more other SkyArchives.
Data are added to an archive in fields. The datum in a field is associated
with a name, number of bytes, and a type code. The name can be anything you
choose and is not required to be unique. The number of bytes must be accurate.
The type code must be one of the SkyArchiveTypeCode enums. Several of the Add
functions have been specialized for the common base types. It isn't necessary
to provide the number of bytes when using the specialized functions, since it can be
inferred from the type code.
The functions that retrieve fields from an archive are similar to the ones
that add data, only their roles are reversed. As with the Add functions,
there are several specialized functions for the common base types while
custom information can be retrieved using the generic FindData function.
Querying the contents of an archive is provided through the GetInfo
functions. These functions are important as they allow you to write
code that can intelligently determine how to retrieve information at
run-time: you no longer have to hardcode the order in which you retrieve
data from your files.
archive data fields are held in using an STL multimap. The multimap key
is a QString (field name) and the data is held in a SkyArchiveEntry
structure (see SkyArchive.cpp for details of this structure).
The fields are stored in alphabetical order based on the key names.
*/
class SkyArchive
{
public:
//=========================================================================
// Creation & Destruction
//=========================================================================
// Empty archive: no name, no data fields.
SkyArchive();
// Creates a named archive with no data fields.
SkyArchive( const char* pName);
// Deep copy the contents of one archive to another.
SkyArchive( const SkyArchive& src);
// Deep copy the contents of one archive to another.
SkyArchive& operator=( const SkyArchive& src);
~SkyArchive();
//=========================================================================
// Basic SkyArchive Information
//=========================================================================
// Returns true if the archive contains no data fields.
bool IsEmpty() const;
//! Returns the archive's name.
const char* GetName() const { return _pName; };
//=========================================================================
// Adding Content to SkyArchive
//=========================================================================
// Adds a new datafield to the archive.
SKYRESULT AddData(const char* pName,
SkyArchiveTypeCode eType,
const void* pData,
unsigned int iNumBytes,
unsigned int iNumItems = 1);
SKYRESULT AddBool( const char* pName, bool aBool);
SKYRESULT AddInt8( const char* pName, char anInt8);
SKYRESULT AddInt16( const char* pName, short anInt16);
SKYRESULT AddInt32( const char* pName, int anInt32);
SKYRESULT AddUInt8( const char* pName, unsigned char anUInt8);
SKYRESULT AddUInt16( const char* pName, unsigned short anUInt16);
SKYRESULT AddUInt32( const char* pName, unsigned int anUInt32);
SKYRESULT AddFloat32( const char* pName, float aFloat32);
SKYRESULT AddFloat64( const char* pName, double aFloat64);
SKYRESULT AddString( const char* pName, const char* pString);
SKYRESULT AddArchive( const SkyArchive& anArchive);
// Vector types (MJH:: only supports float versions for now!!!)
SKYRESULT AddVec2f( const char* pName, const Vec2f& aPoint2f);
SKYRESULT AddVec3f( const char* pName, const Vec3f& aPoint3f);
SKYRESULT AddVec4f( const char* pName, const Vec4f& aPoint4f);
//=========================================================================
// Retrieving Content from SkyArchive
//=========================================================================
// Retrieves the specified datafield the archive, if it exists.
SKYRESULT FindData( const char* pName,
SkyArchiveTypeCode eType,
void** const pData,
unsigned int* pNumBytes,
unsigned int index = 0) const;
SKYRESULT FindBool( const char* pName, bool* pBool, unsigned int index = 0) const;
SKYRESULT FindInt8( const char* pName, char* pInt8, unsigned int index = 0) const;
SKYRESULT FindInt16( const char* pName, short* pInt16, unsigned int index = 0) const;
SKYRESULT FindInt32( const char* pName, int* pInt32, unsigned int index = 0) const;
SKYRESULT FindUInt8( const char* pName, unsigned char* pUInt8, unsigned int index = 0) const;
SKYRESULT FindUInt16( const char* pName, unsigned short* pUInt16, unsigned int index = 0) const;
SKYRESULT FindUInt32( const char* pName, unsigned int* pUInt32, unsigned int index = 0) const;
SKYRESULT FindFloat32(const char* pName, float* pFloat32, unsigned int index = 0) const;
SKYRESULT FindFloat64(const char* pName, double* pFloat64, unsigned int index = 0) const;
SKYRESULT FindString( const char* pName, char** const pString, unsigned int index = 0) const;
SKYRESULT FindArchive(const char* pName, SkyArchive* pArchive, unsigned int index = 0) const;
SKYRESULT FindVec2f( const char* pName, Vec2f* pVec2f, unsigned int index = 0) const;
SKYRESULT FindVec3f( const char* pName, Vec3f* pVec3f, unsigned int index = 0) const;
SKYRESULT FindVec4f( const char* pName, Vec4f* pVec4f, unsigned int index = 0) const;
SKYRESULT AccessArchive(const char* pName, SkyArchive** pArchive, unsigned int index = 0) const;
//=========================================================================
// Querying Contents of SkyArchive
//=========================================================================
// Computes the number of fields that contain the given name and type.
SKYRESULT GetInfo(const char* pName,
SkyArchiveTypeCode eType,
unsigned int* pNumFound = NULL) const;
// Returns information about the key at the specified index.
SKYRESULT GetInfo(unsigned int iNameIndex,
char** pNameFound,
SkyArchiveTypeCode* pTypeCode,
unsigned int* pNumFound);
// Computes the number of unique key names in _dataTableable.
unsigned int GetNumUniqueNames() const;
// Remove the contents of the SkyArchive.
SKYRESULT MakeEmpty();
// Loads the contents from a file.
SKYRESULT Load(const char* pFileName);
// Commits the contents of a SkyArchive to file storage.
SKYRESULT Save(const char* pFileName) const;
private:
char* _pName; // this archive's name
//=========================================================================
// Data storage
//=========================================================================
typedef std::multimap<char*, SkyArchiveEntry*, StringLessFunctor> SkyArchiveMMap;
typedef SkyArchiveMMap::const_iterator SkyMMapConstIter;
typedef SkyArchiveMMap::iterator SkyMMapIter;
SkyArchiveMMap _dataTable; // this is where the data reside.
// Performs a deep-copy of one archive's archive_mmap_t to another.
void _CopyDataTable( const SkyArchiveMMap& src);
// Locates an archive entry in _dataTable
const SkyArchiveEntry* _FindEntry( const char* pName,
unsigned int index,
SkyArchiveTypeCode eType) const;
// Saves the archive to a file stream.
SKYRESULT _Save(FILE* pDestFile) const;
// Initializes the archive from a file stream.
SKYRESULT _Load(FILE* pSrcFile);
};
#endif //__SKYARCHIVE_HPP__

View File

@@ -1,297 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyBVTree.hpp
//------------------------------------------------------------------------------
// Empyrean / SkyWorks : Copyright 2002 Mark J. Harris
//------------------------------------------------------------------------------
/**
* @file SkyBVTree.hpp
*
* This source was written by Wesley Hunt. Many thanks to him for providing it.
*/
//-----------------------------------------------------------------------------
// SkyBVTree.hpp
//
// Author: Wesley Hunt (hunt@cs.unc.edu)
// Date: 2000/12/19
//-----------------------------------------------------------------------------
// Overview
// --------
// declare an SkyBVTree with whatever object type and bounding volume type you
// want. The hard part is to pass in a NodeSplitter class that determines how
// to split a node up. See below for a description of its requirements.
// Finally, use that tree like so:
// * BeginTree()
// * AddObject(Object, ObjectBV)
// * ...
// * EndTree()
// < Do whatever you want with GetRoot() >
// < Use GetLeftChild() and GetRightChild() to traverse the nodes >
//
// The class hierarchy is designed for a flexible, simple public interface.
// This pushes some extra complexity into the class hierarchy, but there are two
// main advantages to the final approach:
// 1. There are no interface requirements for the Object and BoundingVolume
// template parameters. This means you don't have to modify your existing
// class interfaces to use them with the tree.
// 2. All the dependent logic for dealing with the bounding volumes is pushed
// into the NodeSplitter class. So there is one centralized location for
// adapting your bounding volume classes to work with the tree. See the
// description of the NodeSplitter template requirements for more details.
//
// Class Descriptions
// ------------------
//
// SkyBaseBVTree
// -------------
// declares the node class that the tree holds. It exposes
// the public functions of the nodes and defines protected accessors that
// the derived tree class can use to manipulate nodes and build the tree.
//
// Node
// ----
// This is the class that gives access to the tree. You can access each
// object and bounding volume owned by a node, along with that node's
// children.
//
// NodeObject
// ----------------
// An aggregation of an object and its associated bounding volume.
// Each node in the tree essentially owns an array of NodeObjects. This
// array is passed to the NodeSplitter class to allow it to examine a
// node's contained objects before making a decision on how to split the
// node up.
//
// SkyBVTree
// ---------
// The main tree class. To use it, supply and object type, a bounding volume
// type, and a NodeSplitter class that is used to split the nodes up during
// tree construction.
//
// Template class requirements
// ---------------------------
//
// Object
// ------
// None
//
// BoundingVolume
// --------------
// None
//
// NodeSplitter
// ------------
// This is the user-supplied class that decides how to split a node during
// tree construction. It is given an array of NodeObjects that the node owns and
// is responsible for determining the node's bounding volume as well as how to
// split the node up into left and right children.
// The required API is as follows:
//
// * a constructor that takes an array of NodeObject and an unsigned int giving
// the size of the array. These are the objects owned by the node to be split.
// * a method GetNodeBV() that returns the BoundingVolume of the node.
// Typically this is the union of the bounding volumes of the objects owned
// by the node.
// * A unary function operator used to partition the objects in the node. The
// operator must take a single NodeObject as a parameter and return as
// a bool whether to place the NodeObject in the left or right child.
// Basically, it should be compatible with std::partition using NodeObjects.
// * A binary function operator used to sort the objects. If a partition fails,
// the nodes are then sorted based on this function and half are sent to each child.
// This operator must define a total ordering of the NodeObjects.
// Basically, it should be compatible with std::sort using NodeObjects.
//
// Example:
// struct NodeSplitter
// {
// NodeSplitter(const NodeObject* objs, unsigned int numObjs);
// BoundingVolume& GetNodeBV() const;
// // Partition predicate
// bool operator()(const NodeObject& obj) const;
// // Sort predicate
// bool operator()(const NodeObject& obj1, const NodeObject& obj2) const;
// };
//
//-----------------------------------------------------------------------------
#ifndef __SKYBVTREE_HPP__
#define __SKYBVTREE_HPP__
#include <algorithm>
#include <vector>
//-----------------------------------------------------------------------------
// SkyBaseBVTree<Object, BoundingVolume>
//-----------------------------------------------------------------------------
// See header description for details.
//-----------------------------------------------------------------------------
template <class Object, class BoundingVolume>
class SkyBaseBVTree
{
public:
typedef BoundingVolume BV;
class NodeObject;
public:
class Node
{
friend class SkyBaseBVTree<Object, BoundingVolume>;
public:
Node() : _pObjs(NULL), _iNumObjs(0) {}
Node(NodeObject* pObjs, unsigned int iNumObjs) : _pObjs(pObjs), _iNumObjs(iNumObjs) {}
// Public interface
const Object& GetObj(unsigned int index) const { assert(_iNumObjs != 0 && _pObjs != NULL && index < _iNumObjs); return _pObjs[index].GetObj(); }
const BV& GetBV(unsigned int index) const { assert(_iNumObjs != 0 && _pObjs != NULL && index < _iNumObjs); return _pObjs[index].GetBV(); }
unsigned int GetNumObjs() const { assert(_iNumObjs != 0 && _pObjs != NULL); return _iNumObjs; }
const BV& GetNodeBV() const { assert(_iNumObjs != 0 && _pObjs != NULL); return _volume; }
const Node* GetLeftChild() const { assert(_iNumObjs != 0 && _pObjs != NULL); return this+1; }
const Node* GetRightChild() const { assert(_iNumObjs != 0 && _pObjs != NULL); return this+(GetLeftChild()->GetNumObjs()<<1); }
bool IsLeaf() const { assert(_iNumObjs != 0 && _pObjs != NULL); return _iNumObjs == 1; }
private:
// List of Objects owned by the node
NodeObject *_pObjs;
unsigned int _iNumObjs;
BV _volume;
};
public:
class NodeObject
{
public:
NodeObject(const Object& o, const BV& v) : _obj(o), _volume(v) {}
const Object& GetObj() const { return _obj; }
const BV& GetBV() const { return _volume; }
private:
Object _obj;
BV _volume;
};
protected:
// Give non-const access to the node for descendant classes to build the tree
BV& GetNodeBV(Node* pNode) { assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL); return pNode->_volume; }
Node* GetLeftChild(Node* pNode) { assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL); return pNode+1; }
Node* GetRightChild(Node* pNode) { assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL); return pNode+(GetLeftChild(pNode)->GetNumObjs()<<1); }
NodeObject* GetObjs(Node* pNode) { assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL); return pNode->_pObjs; }
// Links a node's children by assigning the given number of objects to each child
// assumes the node has already had it's objects partitioned
void LinkNodeChildren(Node* pNode, unsigned int iLeftNumObjs)
{
assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL);
GetLeftChild(pNode)->_pObjs = pNode->_pObjs;
GetLeftChild(pNode)->_iNumObjs = iLeftNumObjs;
GetRightChild(pNode)->_pObjs = pNode->_pObjs + iLeftNumObjs;
GetRightChild(pNode)->_iNumObjs = pNode->_iNumObjs - iLeftNumObjs;
}
};
//------------------------------------------------------------------------------
// Function : ClearVector
// Description :
//------------------------------------------------------------------------------
/**
* @fn ClearVector(std::vector<T>& vec)
* @brief This utility function uses the std::vector::swap trick to free the memory of a vector
*
* This is necessary since clear() doesn't actually free anything.
*/
template<class T>
void ClearVector(std::vector<T>& vec)
{
std::vector<T>().swap(vec);
}
//-----------------------------------------------------------------------------
// SkyBVTree<Object, BoundingVolume, NodeSplitter>
//-----------------------------------------------------------------------------
// See header description for details.
//-----------------------------------------------------------------------------
template <class Object, class BoundingVolume, class NodeSplitter>
class SkyBVTree : public SkyBaseBVTree<Object, BoundingVolume>
{
public:
typedef SkyBaseBVTree<Object, BoundingVolume> BaseTree;
typedef typename SkyBaseBVTree<Object, BoundingVolume>::BV BV;
typedef typename BaseTree::NodeObject NodeObject;
typedef typename BaseTree::Node Node;
void Clear()
{
BeginTree();
}
void BeginTree(unsigned int iNumObjs = 0)
{
ClearVector(_objList);
ClearVector(_nodes);
if (iNumObjs > 0) _objList.reserve(iNumObjs);
}
void AddObject(const Object &obj, const BV& volume)
{
_objList.push_back(NodeObject(obj, volume));
}
void EndTree()
{
if (_objList.size() == 0) return;
// Initialize the root node with all the objects
_nodes.push_back(Node(&_objList[0], _objList.size()));
// create room for the other nodes. They are initialized in BuildTree().
_nodes.reserve(_objList.size()*2-1);
_nodes.resize(_objList.size()*2-1);
BuildTree(&_nodes[0]);
}
const Node *GetRoot() const { return _nodes.empty() ? NULL : &_nodes[0]; }
// Memory usage info
unsigned int CalcMemUsage() const
{
unsigned int usage = 0;
usage += sizeof(*this);
usage += _objList.capacity() * sizeof(_objList[0]);
usage += _nodes.capacity() * sizeof(_nodes[0]);
return usage;
}
public:
private:
// Does the real work
void BuildTree(Node *pCurNode)
{
int iLeftNumObjs;
{
// Initialize the node splitter with the current node
NodeSplitter splitter(GetObjs(pCurNode), pCurNode->GetNumObjs());
// set the node's bounding volume using the splitter
GetNodeBV(pCurNode) = splitter.GetNodeBV();
// When a node has one object we can stop
if (pCurNode->GetNumObjs() == 1) return;
// Try and partition the objects
iLeftNumObjs = std::partition(GetObjs(pCurNode), &GetObjs(pCurNode)[pCurNode->GetNumObjs()], splitter) - GetObjs(pCurNode);
if ((iLeftNumObjs == 0) || (iLeftNumObjs == pCurNode->GetNumObjs()))
{
// Partition failed. Sort and split again to force a complete tree
std::sort(GetObjs(pCurNode), &GetObjs(pCurNode)[pCurNode->GetNumObjs()], splitter);
iLeftNumObjs = pCurNode->GetNumObjs() / 2;
}
}
LinkNodeChildren(pCurNode, iLeftNumObjs);
BuildTree(GetLeftChild(pCurNode));
BuildTree(GetRightChild(pCurNode));
}
std::vector<Node> _nodes;
std::vector<NodeObject> _objList;
};
#endif //__SKYBVTREE_HPP__

View File

@@ -1,242 +0,0 @@
//============================================================================
// File : SkyBVTreeSplitter.hpp
//
// Author : Wesley Hunt
//
// Content : NodeSplitter classes for SkyBVTrees using SkyBoundingBox or
// SkyBoundingSphere (not implemented).
//
//============================================================================
#ifndef __SKYBVTREESPLITTER_HPP__
#define __SKYBVTREESPLITTER_HPP__
//----------------------------------------------------------------------------
//-- Includes ----------------------------------------------------------------
//----------------------------------------------------------------------------
#include "SkyBVTree.hpp"
#include "SkyMinMaxBox.hpp"
//#include <Mlx/MlxBoundingSphere.hpp>
//#if _MSC_VER == 1200
//#include <Auxlib/AuxCompileTimeChecker.hpp>
//#endif
//----------------------------------------------------------------------------
//-- Forward Declarations ----------------------------------------------------
//----------------------------------------------------------------------------
// A strategy for splitting nodes compatible with bounding boxes and spheres.
template<class Object> class SkyBoundingBoxSplitter;
// SkyBVTree compatible node splitters implemented using the above strategy.
template<class Object> class SkyAABBTreeSplitter;
//template<class Object> class SkySphereTreeSplitter;
//----------------------------------------------------------------------------
//-- Defines, Constants, Enumerated Types ------------------------------------
//----------------------------------------------------------------------------
const float rLongObjectPercentageTolerance = 0.75f;
//----------------------------------------------------------------------------
// SkyBoundingBoxSplitter
//----------------------------------------------------------------------------
// This class defines a NodeSplitter strategy that has the functionality
// required by SkyBVTree's NodeSplitter template class. Can be used with
// SkyMinMaxBox and SkyBoundingSphere.
//
// It defines a two-tiered split strategy:
//
// * First it tries to separate large objects from any smaller objects.
// * If there are no large objects, it splits along the midpoint of the longest
// axis defined by the objects.
// * Finally, if all else fails, it defines a total ordering along the longest
// axis based on the center of each node.
//----------------------------------------------------------------------------
template<class Object>
class SkyBoundingBoxSplitter
{
public:
typedef typename SkyBaseBVTree<Object, SkyMinMaxBox>::NodeObject NodeObjectBox;
//typedef SkyBaseBVTree<Object, SkyBoundingSphere>::NodeObject NodeObjectSphere;
#if _MSC_VER == 1200
// !!! WRH HACK MSVC++6 SP5 Workaround.
// VC6 can't disambiguate this constructor because it doesn't consider the two
// NodeObject templates to be different classes for the purposes of
// overloading. It won't recognize that the second template parameters are
// different. Forcing them to be explicit template specializations fixes
// the problem.
template<class BV>
SkyBoundingBoxSplitter(const SkyBaseBVTree<Object, BV>::NodeObject*, unsigned int)
{
//AUX_STATIC_CHECK(false, VisualC_6_WorkAround); ???
}
template<>
#endif
SkyBoundingBoxSplitter(const NodeObjectBox* pObjs, unsigned int iNumObjs)
{
for (unsigned int i = 0; i < iNumObjs; ++i)
{
_nodeBBox.Union(pObjs[i].GetBV());
}
Init(pObjs, iNumObjs);
}
/*#if _MSC_VER == 1200
template<>
#endif
SkyBoundingBoxSplitter(const NodeObjectSphere* objs,
#ifdef _PLATFORM_XBOX
Int32
#else
UInt32
#endif
numObjs)
{
for (int i=0; i<numObjs; ++i)
{
SkyMinMaxBox box;
box.AddPoint(objs[i].GetBV().GetCenter());
box.Bloat(objs[i].GetBV().GetRadius());
_nodeBBox.Union(box);
}
Init(objs, numObjs);
}*/
template<class nodeObj>
bool SplitLeft(const nodeObj& obj) const
{
if (_bIsolateLongObjects)
return GetSplitAxisLength(obj.GetBV()) < _rMaxObjectLength;
else
return GetSplitAxisCenter(obj.GetBV()) < _rSplitValue;
}
template<class nodeObj>
bool LessThan(const nodeObj& obj1, const nodeObj& obj2) const
{
return GetSplitAxisCenter(obj1.GetBV()) < GetSplitAxisCenter(obj2.GetBV());
}
const SkyMinMaxBox& GetNodeBBox() const { return _nodeBBox; }
private:
template<class nodeObj>
void Init(const nodeObj* pObjs, unsigned int iNumObjs)
{
_iSplitAxis = FindSplitAxis(_nodeBBox);
_rSplitValue = FindSplitValue(_nodeBBox, _iSplitAxis);
_rMaxObjectLength = GetSplitAxisLength(_nodeBBox) * rLongObjectPercentageTolerance;
_bIsolateLongObjects = false;
for (unsigned int i = 0; i < iNumObjs; ++i)
{
if (GetSplitAxisLength(pObjs[i].GetBV()) > _rMaxObjectLength)
{
_bIsolateLongObjects = true;
break;
}
}
}
int FindSplitAxis(const SkyMinMaxBox& bbox)
{
int iAxis = 0, i;
Vec3f vecExt = bbox.GetMax() - bbox.GetMin();
for (i = 1; i < 3; ++i) if (vecExt[i] > vecExt[iAxis]) iAxis = i;
return iAxis;
}
float FindSplitValue(const SkyMinMaxBox& bbox, int iSplitAxis)
{
return (bbox.GetMin()[iSplitAxis] + bbox.GetMax()[iSplitAxis])*0.5f;
}
/*float GetSplitAxisLength(const SkyBoundingSphere& sphere) const
{
return 2.f*sphere.GetRadius();
}*/
float GetSplitAxisLength(const SkyMinMaxBox& bbox) const
{
return bbox.GetMax()[_iSplitAxis] - bbox.GetMin()[_iSplitAxis];
}
float GetSplitAxisCenter(const SkyMinMaxBox& bbox) const
{
return (bbox.GetMin()[_iSplitAxis] + bbox.GetMax()[_iSplitAxis]) * 0.5f;
}
/*float GetSplitAxisCenter(const SkyBoundingSphere& sphere) const
{
return sphere.GetCenter()[SplitAxis];
}*/
int _iSplitAxis;
float _rSplitValue;
bool _bIsolateLongObjects;
float _rMaxObjectLength;
SkyMinMaxBox _nodeBBox;
};
//----------------------------------------------------------------------------
// SkyAABBTreeSplitter
//----------------------------------------------------------------------------
// A NodeSplitter that is compatible with SkyBVTree for SkyMinMaxBox.
// Implemented using the SkyBoundingBoxSplitter strategy.
//----------------------------------------------------------------------------
template<class Object>
class SkyAABBTreeSplitter
{
public:
typedef SkyMinMaxBox BV;
typedef typename SkyBaseBVTree<Object, BV>::NodeObject NodeObject;
SkyAABBTreeSplitter(const NodeObject* pObjs, unsigned int iNumObjs) : _splitter(pObjs, iNumObjs) {}
const BV& GetNodeBV() const { return _splitter.GetNodeBBox(); }
bool operator()(const NodeObject& obj) const
{
return _splitter.SplitLeft(obj);
}
bool operator()(const NodeObject& obj1, const NodeObject& obj2) const
{
return _splitter.LessThan(obj1, obj2);
}
private:
SkyBoundingBoxSplitter<Object> _splitter;
};
//----------------------------------------------------------------------------
// SkySphereTreeSplitter
//----------------------------------------------------------------------------
// A NodeSplitter that is compatible with SkyBVTree for SkyBoundingSphere.
// Implemented using the SkyBoundingBoxSplitter strategy.
//----------------------------------------------------------------------------
/*template<class Object>
class SkySphereTreeSplitter
{
public:
typedef SkyBoundingSphere BV;
typedef SkyBaseBVTree<Object, BV>::NodeObject NodeObject;
MlxSphereTreeSplitter(const NodeObject* pObjs, unsigned int iNumObjs) : _splitter(pObjs, iNumObjs)
{
_nodeBV = pObjs[0].GetBV();
for (unsigned int i = 1; i < iNumObjs; ++i) _nodeBV.Union(pObjs[i].GetBV());
}
const BV& GetNodeBV() const { return _nodeBV; }
bool operator()(const NodeObject& obj) const
{
return _splitter.SplitLeft(obj);
}
bool operator()(const NodeObject& obj1, const NodeObject& obj2) const
{
return _splitter.LessThan(obj1, obj2);
}
private:
BV _nodeBV;
SkyBoundingBoxSplitter<Object> _splitter;
};*/
#endif //__SKYBVTREESPLITTER_HPP__

View File

@@ -1,151 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyBoundingVolume.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyBoundingVolume.hpp
*
* Base class interface definition for a bounding volume.
*/
#ifndef __SKYBOUNDINGVOLUME_HPP__
#define __SKYBOUNDINGVOLUME_HPP__
#include "vec3f.hpp"
#include "mat44.hpp"
// forward to reduce unnecessary dependencies
class Camera;
//------------------------------------------------------------------------------
/**
* @class SkyBoundingVolume
* @brief An abstract base class for bounding volumes (AABB,OBB,Sphere,etc.)
*
* This base class maintains a center and a radius, so it is effectively a bounding
* sphere. Derived classes may represent other types of bounding volumes, but they
* should be sure to update the radius and center, because some objects will treat
* all bounding volumes as spheres.
*
*/
class SkyBoundingVolume
{
public:
//! Constructor
SkyBoundingVolume() : _vecCenter(0, 0, 0), _rRadius(0) {}
//! Destructor
virtual ~SkyBoundingVolume() {}
//------------------------------------------------------------------------------
// Function : SetCenter
// Description :
//------------------------------------------------------------------------------
/**
* @fn SetCenter(const Vec3f &center)
* @brief Sets the center of the bounding volume.
*/
virtual void SetCenter(const Vec3f &center) { _vecCenter = center; }
//------------------------------------------------------------------------------
// Function : SetRadius
// Description :
//------------------------------------------------------------------------------
/**
* @fn SetRadius(float radius)
* @brief Sets the radius of the bounding volume.
*/
virtual void SetRadius(float radius) { _rRadius = radius; }
//------------------------------------------------------------------------------
// Function : Vec3f& GetCenter
// Description :
//------------------------------------------------------------------------------
/**
* @fn Vec3f& GetCenter() const
* @brief Returns the center of the bounding volume.
*/
virtual const Vec3f& GetCenter() const { return _vecCenter; }
//------------------------------------------------------------------------------
// Function : GetRadius
// Description :
//------------------------------------------------------------------------------
/**
* @fn GetRadius() const
* @brief Returns the radius ofthe bounding volume.
*/
virtual float GetRadius() const { return _rRadius; }
//------------------------------------------------------------------------------
// Function : ViewFrustumCull
// Description :
//------------------------------------------------------------------------------
/**
* @fn ViewFrustumCull( const Camera &cam, const Mat44f &mat )
* @brief Cull a bounding volume.
*
* Returns false if the bounding volume is entirely outside the camera's frustum,
* true otherwise.
*/
virtual bool ViewFrustumCull( const Camera &cam, const Mat44f &mat ) = 0;
//------------------------------------------------------------------------------
// Function : AddPoint
// Description :
//------------------------------------------------------------------------------
/*
* @fn AddPoint( const Vec3f &pt )
* @brief Add a point to a bounding volume.
*
* One way to create a bounding volume is to add points. What should/could happen
* is that the BV will store an object space BV and then when a call to SetPosition
* is called, the stored values will be transformed and stored separately, so that
* the original values always exist.
*
*/
//virtual void AddPoint( const Vec3f &point ) = 0;
//------------------------------------------------------------------------------
// Function : AddPoint
// Description :
//------------------------------------------------------------------------------
/*
* @fn AddPoint( float x, float y, float z )
* @brief Add a point to a bounding volume.
*
* @see AddPoint(const Vec3f &pt)
*/
//virtual void AddPoint( float x, float y, float z ) = 0;
//------------------------------------------------------------------------------
// Function : Clear
// Description :
//------------------------------------------------------------------------------
/*
* @fn Clear()
* @brief Clear all data from the bounding volume.
*/
//virtual void Clear() = 0;
protected:
Vec3f _vecCenter;
float _rRadius;
};
#endif //__SKYBOUNDINGVOLUME_HPP__

File diff suppressed because it is too large Load Diff

View File

@@ -1,178 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyCloud.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyCloud.hpp
*
* Interface definition for class SkyCloud.
*/
#ifndef __SKYCLOUD_HPP__
#define __SKYCLOUD_HPP__
// warning for truncation of template name for browse info
#pragma warning( disable : 4786)
#include "SkyCloudParticle.hpp"
#include "SkyRenderable.hpp"
#include "SkyMinMaxBox.hpp"
#include "camera.hpp"
#include "SkyArchive.hpp"
#include "mat33.hpp"
#include <plib/sg.h>
class SkyMaterial;
class SkyLight;
class SkyRenderableInstance;
//------------------------------------------------------------------------------
/**
* @class SkyCloud
* @brief A renderable that represents a volumetric cloud.
*
* A SkyCloud is made up of particles, and is rendered using particle splatting.
* SkyCloud is intended to represent realisticly illuminated volumetric clouds
* through which the viewer and / or other objects can realistically pass.
*
* Realistic illumination is performed by the Illuminate() method, which uses a
* graphics hardware algorithm to precompute and store multiple forward scattering
* of light by each particle in the cloud. Clouds may be illuminated by multiple
* light sources. The light from each source is precomputed and stored at each
* particle. Each light's contribution is stored separately so that we can
* compute view-dependent (anisotropic) scattering at run-time. This gives realistic
* effects such as the "silver lining" that you see on a thick cloud when it crosses
* in front of the sun.
*
* At run-time, the cloud is rendered by drawing each particle as a view-oriented
* textured billboard (splat), with lighting computed from the precomputed illumination
* as follows: for each light source <i>l</i>, compute the scattering function (See _PhaseFunction())
* based on the view direction and the direction from the particle to the viewer. This
* scattering function modulates the lighting contribution of <i>l</i>. The modulated
* contributions are then added and used to modulate the color of the particle. The result
* is view-dependent scattering.
*
* If the phase (scattering) function is not enabled (see IsPhaseFunctionEnabled()), then the
* contributions of the light sources are simply added.
*
* @see SkyRenderableInstanceCloud, SkyCloudParticle, SkySceneManager
*/
class SkyCloud : public SkyRenderable
{
public:
SkyCloud();
virtual ~SkyCloud();
virtual SKYRESULT Update(const Camera &cam, SkyRenderableInstance* pInstance = NULL);
virtual SKYRESULT Display(const Camera &camera, SkyRenderableInstance *pInstance = NULL);
SKYRESULT DisplaySplit(const Camera &camera,
const Vec3f &vecSplitPoint,
bool bBackHalf,
SkyRenderableInstance *pInstance = NULL);
SKYRESULT Illuminate( SkyLight *pLight,
SkyRenderableInstance* pInstance,
bool bReset = false);
virtual SkyMinMaxBox* CopyBoundingVolume() const;
//! Enables the use of a scattering function for anisotropic light scattering.
void EnablePhaseFunction(bool bEnable) { _bUsePhaseFunction = bEnable; }
//! Returns true if the use of a scattering function is enabled.
bool IsPhaseFunctionEnabled() const { return _bUsePhaseFunction; }
SKYRESULT Save(SkyArchive &archive) const;
SKYRESULT Load(const SkyArchive &archive, float rScale = 1.0f,double latitude=0.0, double longitude=0.0);
SKYRESULT Load(const unsigned char *data, unsigned int size, float rScale = 1.0f,double latitude=0.0,double longitude=0.0);
void Rotate(const Mat33f& rot);
void Translate(const Vec3f& trans);
void Scale(const float scale);
protected: // methods
enum SortDirection
{
SKY_CLOUD_SORT_TOWARD,
SKY_CLOUD_SORT_AWAY
};
void _SortParticles( const Vec3f& vecViewDir,
const Vec3f& vecSortPoint,
SortDirection dir);
void _CreateSplatTexture( unsigned int iResolution);
float _PhaseFunction(const Vec3f& vecLightDir, const Vec3f& vecViewDir);
protected: // datatypes
typedef std::vector<SkyCloudParticle*> ParticleArray;
typedef ParticleArray::iterator ParticleIterator;
typedef ParticleArray::const_iterator ParticleConstIterator;
typedef std::vector<Vec3f> DirectionArray;
typedef DirectionArray::iterator DirectionIterator;
class ParticleAwayComparator
{
public:
bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
{
return ((*pA) < (*pB));
}
};
class ParticleTowardComparator
{
public:
bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
{
return ((*pA) > (*pB));
}
};
protected: // data
ParticleArray _particles; // cloud particles
// particle sorting functors for STL sort.
ParticleTowardComparator _towardComparator;
ParticleAwayComparator _awayComparator;
DirectionArray _lightDirections; // light directions in cloud space (cached)
SkyMinMaxBox _boundingBox; // bounds
bool _bUsePhaseFunction;
Vec3f _vecLastSortViewDir;
Vec3f _vecLastSortCamPos;
Vec3f _vecSortPos;
float _rSplitDistance;
static SkyMaterial *s_pMaterial; // shared material for clouds.
static SkyMaterial *s_pShadeMaterial;// shared material for illumination pass.
static unsigned int s_iShadeResolution; // the resolution of the viewport used for shading
static float s_rAlbedo; // the cloud albedo
static float s_rExtinction; // the extinction of the clouds
static float s_rTransparency; // the transparency of the clouds
static float s_rScatterFactor; // How much the clouds scatter
static float s_rSortAngleErrorTolerance; // how far the view must turn to cause a resort.
static float s_rSortSquareDistanceTolerance; // how far the view must move to cause a resort.
};
#endif //__SKYCLOUD_HPP__

View File

@@ -1,175 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyCloudParticle.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyCloudParticle.hpp
*
* Definition of a simple cloud particle class.
*/
#ifndef __SKYCLOUDPARTICLE_HPP__
#define __SKYCLOUDPARTICLE_HPP__
#include "vec3f.hpp"
#include "vec4f.hpp"
#include <vector>
//------------------------------------------------------------------------------
/**
* @class SkyCloudParticle
* @brief A class for particles that make up a cloud.
*
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
*/
class SkyCloudParticle
{
public:
inline SkyCloudParticle();
inline SkyCloudParticle(const Vec3f& pos,
float rRadius,
const Vec4f& baseColor,
float rTransparency = 0);
inline ~SkyCloudParticle();
//! Returns the radius of the particle.
float GetRadius() const { return _rRadius; }
//! Returns the transparency of the particle.
float GetTransparency() const { return _rTransparency; }
//! Returns the position of the particle.
const Vec3f& GetPosition() const { return _vecPosition; }
//! Returns the base color of the particle. This is often used for ambient color.
const Vec4f& GetBaseColor() const { return _vecBaseColor; }
//! Returns the number of light contributions to this particle's color.
unsigned int GetNumLitColors() const { return _vecLitColors.size(); }
//! Returns the light contribution to the color of this particle from light @a index.
inline const Vec4f& GetLitColor(unsigned int index) const;
//! Returns the square distance from the sort position used for the operator< in sorts / splits.
float GetSquareSortDistance() const { return _rSquareSortDistance; }
//! Sets the radius of the particle.
void SetRadius(float rad) { _rRadius = rad; }
//! Returns the transparency of the particle.
void SetTransparency(float trans) { _rTransparency = trans; }
//! Sets the position of the particle.
void SetPosition(const Vec3f& pos) { _vecPosition = pos; }
//! Sets the base color of the particle. This is often used for ambient color.
void SetBaseColor(const Vec4f& col) { _vecBaseColor = col; }
//! Sets the light contribution to the color of this particle from light @a index.
void AddLitColor(const Vec4f& col) { _vecLitColors.push_back(col); }
//! Clears the list of light contributions.
void ClearLitColors() { _vecLitColors.clear(); }
//! Sets the square distance from the sort position used for the operator< in sorts.
void SetSquareSortDistance(float rSquareDistance) { _rSquareSortDistance = rSquareDistance; }
//! This operator is used to sort particle arrays from nearest to farthes.
bool operator<(const SkyCloudParticle& p) const
{
return (_rSquareSortDistance < p._rSquareSortDistance);
}
//! This operator is used to sort particle arrays from farthest to nearest.
bool operator>(const SkyCloudParticle& p) const
{
return (_rSquareSortDistance > p._rSquareSortDistance);
}
protected:
float _rRadius;
float _rTransparency;
Vec3f _vecPosition;
Vec4f _vecBaseColor;
std::vector<Vec4f> _vecLitColors;
Vec3f _vecEye;
// for sorting particles during shading
float _rSquareSortDistance;
};
//------------------------------------------------------------------------------
// Function : SkyCloudParticle::SkyCloudParticle
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyCloudParticle::SkyCloudParticle()
* @brief Default constructor.
*/
inline SkyCloudParticle::SkyCloudParticle()
: _rRadius(0),
_rTransparency(0),
_vecPosition(0, 0, 0),
_vecBaseColor(0, 0, 0, 1),
_vecEye(0, 0, 0),
_rSquareSortDistance(0)
{
_vecLitColors.clear();
}
//------------------------------------------------------------------------------
// Function : SkyCloudParticle::SkyCloudParticle
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyCloudParticle::SkyCloudParticle(const Vec3f& pos, float rRadius, const Vec4f& baseColor, float rTransparency)
* @brief Constructor.
*/
inline SkyCloudParticle::SkyCloudParticle(const Vec3f& pos,
float rRadius,
const Vec4f& baseColor,
float rTransparency /* = 0 */)
: _rRadius(rRadius),
_rTransparency(rTransparency),
_vecPosition(pos),
_vecBaseColor(baseColor),
_vecEye(0, 0, 0),
_rSquareSortDistance(0)
{
_vecLitColors.clear();
}
//------------------------------------------------------------------------------
// Function : SkyCloudParticle::~SkyCloudParticle
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyCloudParticle::~SkyCloudParticle()
* @brief Destructor.
*/
inline SkyCloudParticle::~SkyCloudParticle()
{
_vecLitColors.clear();
}
//------------------------------------------------------------------------------
// Function : Vec4f& SkyCloudParticle::GetLitColor
// Description :
//------------------------------------------------------------------------------
/**
* @fn Vec4f& SkyCloudParticle::GetLitColor(unsigned int index) const
* @brief Returns the lit color specified by index.
*
* If the index is out of range, returns a zero vector.
*/
inline const Vec4f& SkyCloudParticle::GetLitColor(unsigned int index) const
{
if (index <= _vecLitColors.size())
return _vecLitColors[index];
else
return Vec4f::ZERO;
}
#endif //__SKYCLOUDPARTICLE_HPP__

View File

@@ -1,324 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyContext.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyContext.cpp
*
* Graphics Context Interface. Initializes GL extensions, etc.
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
// #include GLUT_H
#if defined (__APPLE__)
# include <OpenGL/OpenGL.h>
#endif
#if !defined (WIN32) && !defined(__APPLE__)
#include <GL/glx.h>
#endif
//#include "extgl.h"
#include "SkyContext.hpp"
#include "SkyUtil.hpp"
#include "SkyMaterial.hpp"
#include "SkyTextureState.hpp"
//------------------------------------------------------------------------------
// Function : SkyContext::SkyContext
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyContext::SkyContext()
* @brief Constructor.
*
*/
SkyContext::SkyContext()
{
// _iWidth = glutGet(GLUT_WINDOW_WIDTH);
// _iHeight = glutGet(GLUT_WINDOW_HEIGHT);
_iWidth = 640;
_iHeight = 480;
// materials and structure classes
AddCurrentGLContext();
// Initialize all the extensions and load the functions - JW (file is extgl.c)
#ifdef WIN32
glInitialize();
InitializeExtension("GL_ARB_multitexture");
#endif
}
//------------------------------------------------------------------------------
// Function : SkyContext::~SkyContext
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyContext::~SkyContext()
* @brief Destructor.
*/
SkyContext::~SkyContext()
{
// delete map of materials
for (ContextMaterialIterator cmi = _currentMaterials.begin(); cmi != _currentMaterials.end(); ++cmi)
{
SAFE_DELETE(cmi->second);
}
_currentMaterials.clear();
}
//------------------------------------------------------------------------------
// Function : SkyContext::ProcessReshapeEvent
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
* @brief Handles window resize events, and notifies all context listeners of the event.
*/
SKYRESULT SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
{
_iWidth = iWidth;
_iHeight = iHeight;
return _SendMessage(SKYCONTEXT_MESSAGE_RESHAPE);
}
//------------------------------------------------------------------------------
// Function : SkyContext::InitializeExtensions
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyContext::InitializeExtensions(const char *pExtensionNames)
* @brief Initializes GL extension specified by @a pExtensionNames.
*/
SKYRESULT SkyContext::InitializeExtension(const char *pExtensionName)
{ /***
if (!QueryExtension(pExtensionName)) // see query search function defined in extgl.c
{
SkyTrace(
"ERROR: SkyContext::InitializeExtenstions: The following extensions are unsupported: %s\n",
pExtensionName);
return SKYRESULT_FAIL;
} **/
//set this false to catch all the extensions until we come up with a linux version
return SKYRESULT_FAIL;
}
//------------------------------------------------------------------------------
// Function : SkyContext::GetCurrentMaterial
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyContext::GetCurrentMaterial()
* @brief Returns the current cached material state that is active in this OpenGL context.
*
* @todo <WRITE EXTENDED SkyContext::GetCurrentMaterial FUNCTION DOCUMENTATION>
*/
SkyMaterial* SkyContext::GetCurrentMaterial()
{
#ifdef WIN32
ContextMaterialIterator cmi = _currentMaterials.find(wglGetCurrentContext());
#elif defined(__APPLE__)
ContextMaterialIterator cmi = _currentMaterials.find(CGLGetCurrentContext());
#else
ContextMaterialIterator cmi = _currentMaterials.find(glXGetCurrentContext());
#endif
if (_currentMaterials.end() != cmi)
return cmi->second;
else
{
SkyTrace("SkyContext::GetCurrentMaterial(): Invalid context.");
return NULL;
}
}
//------------------------------------------------------------------------------
// Function : SkyContext::GetCurrentTextureState
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyContext::GetCurrentTextureState()
* @brief Returns the current cached texture state that is active in this OpenGL context.
*
* @todo <WRITE EXTENDED SkyContext::GetCurrentTextureState FUNCTION DOCUMENTATION>
*/
SkyTextureState* SkyContext::GetCurrentTextureState()
{
#ifdef WIN32
ContextTextureStateIterator ctsi = _currentTextureState.find(wglGetCurrentContext());
#elif defined(__APPLE__)
ContextTextureStateIterator ctsi = _currentTextureState.find(CGLGetCurrentContext());
#else
ContextTextureStateIterator ctsi = _currentTextureState.find(glXGetCurrentContext());
#endif
if (_currentTextureState.end() != ctsi)
return ctsi->second;
else
{
SkyTrace("SkyContext::GetCurrentTextureState(): Invalid context.");
return NULL;
}
}
//------------------------------------------------------------------------------
// Function : SkyContext::AddCurrentGLContext
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyContext::AddCurrentGLContext()
* @brief @todo <WRITE BRIEF SkyContext::AddCurrentGLContext DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyContext::AddCurrentGLContext FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyContext::AddCurrentGLContext()
{
SkyMaterial *pCurrentMaterial = new SkyMaterial;
#ifdef WIN32
_currentMaterials.insert(std::make_pair(wglGetCurrentContext(), pCurrentMaterial));
#elif defined (__APPLE__)
_currentMaterials.insert(std::make_pair(CGLGetCurrentContext(), pCurrentMaterial));
#else
_currentMaterials.insert(std::make_pair(glXGetCurrentContext(), pCurrentMaterial));
#endif
SkyTextureState *pCurrentTS = new SkyTextureState;
#ifdef WIN32
_currentTextureState.insert(std::make_pair(wglGetCurrentContext() , pCurrentTS));
#elif defined (__APPLE__)
_currentTextureState.insert(std::make_pair(CGLGetCurrentContext() , pCurrentTS));
#else
_currentTextureState.insert(std::make_pair(glXGetCurrentContext() , pCurrentTS));
#endif
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyContext::Register
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyContext::Register(Listener* pListener, int priority)
* @brief Register with the messaging system to handle notification of mode changes
*/
SKYRESULT SkyContext::Register(Listener* pListener, int priority)
{
std::list<ListenerPair>::iterator iter =
std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
if (iter == _listeners.end())
{
// insert the listener, sorted by priority
for (iter=_listeners.begin(); iter != _listeners.end(); ++iter)
{
if (priority <= iter->first)
{
_listeners.insert(iter, ListenerPair(priority, pListener));
break;
}
}
if (iter == _listeners.end())
{
_listeners.push_back(ListenerPair(priority, pListener));
}
// Send a message to the pListener if we are already active so it
// can intialize itself
//FAIL_RETURN(pListener->GraphicsReshapeEvent());
}
else
{
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is already registered");
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyContext::UnRegister
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyContext::UnRegister(Listener *pListener)
* @brief UnRegister with the messaging system.
*/
SKYRESULT SkyContext::UnRegister(Listener *pListener)
{
std::list<ListenerPair>::iterator iter =
std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
if (iter == _listeners.end())
{
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is not registered");
}
else
{
_listeners.erase(iter);
}
return SKYRESULT_OK;
}
/**
* @fn SkyContext::_SendMessage(SkyMessageType msg)
* @brief Messaging system to handle notification of mode changes
*/
SKYRESULT SkyContext::_SendMessage(SkyMessageType msg)
{
if (_listeners.size() == 0) return SKYRESULT_OK;
bool failure = false;
SKYRESULT res, failureCode = SKYRESULT_OK;
std::list<ListenerPair>::iterator iter;
SKYRESULT (Listener::*fnPtr)() = NULL;
// Make a pointer to the appropriate method
switch (msg)
{
case SKYCONTEXT_MESSAGE_RESHAPE: fnPtr = &Listener::GraphicsReshapeEvent; break;
}
// Notify all listeners of the messag. catch failures, but still call everyone else.
// !!! WRH HORRIBLE HACK must cache the current "end" because these functions could register new listeners
std::list<ListenerPair>::iterator endIter = _listeners.end();
endIter--;
iter = _listeners.begin();
do
{
if ( SKYFAILED( res = (iter->second->*fnPtr)() ) )
{
failureCode = res;
SkyTrace("SkyContext: SendMessage failed");
}
if (iter == endIter) break;
iter++;
} while (true);
FAIL_RETURN(failureCode);
return SKYRESULT_OK;
}

View File

@@ -1,139 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyContext.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyContext.hpp
*
* Graphics Context Interface. Initializes GL extensions, etc.
*/
#ifndef __SKYCONTEXT_HPP__
#define __SKYCONTEXT_HPP__
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
// warning for truncation of template name for browse info
// #pragma warning( disable : 4786)
#include "SkySingleton.hpp"
#include <simgear/compiler.h>
#include <list>
#include <map>
#include <algorithm>
#ifdef WIN32
# include "extgl.h"
#else
typedef void *HANDLE;
typedef HANDLE *PHANDLE;
#define DECLARE_HANDLE(n) typedef HANDLE n
DECLARE_HANDLE(HGLRC);
#endif
class SkyContext;
class SkyMaterial;
class SkyTextureState;
//! Graphics Context Singleton declaration.
/*! The Context must be created by calling GraphicsContext::Instantiate(). */
typedef SkySingleton<SkyContext> GraphicsContext;
//------------------------------------------------------------------------------
/**
* @class SkyContext
* @brief A manager / proxy for the state of OpenGL contexts.
*
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
*/
class SkyContext
{
public: // datatypes
//------------------------------------------------------------------------------
/**
* @class Listener
* @brief Inherit this class and overide its methods to be notified of context events.
*/
class Listener
{
public:
//! Handle a change in the dimensions of the graphics window.
virtual SKYRESULT GraphicsReshapeEvent() { return SKYRESULT_OK; }
};
/**
* @enum SkyMessageType messages that the context can generate for it's listeners.
*/
enum SkyMessageType
{
SKYCONTEXT_MESSAGE_RESHAPE,
SKYCONTEXT_MESSAGE_COUNT
};
public: // methods
SKYRESULT ProcessReshapeEvent(int iWidth, int iHeight);
SKYRESULT InitializeExtension(const char *pExtensionName);
//! Returns the current dimensions of the window.
void GetWindowSize(int &iWidth, int &iHeight) { iWidth = _iWidth; iHeight = _iHeight; }
SkyMaterial* GetCurrentMaterial();
SkyTextureState* GetCurrentTextureState();
SKYRESULT AddCurrentGLContext();
//------------------------------------------------------------------------------
// Register with the messaging system to handle notification of mode changes
//------------------------------------------------------------------------------
SKYRESULT Register(Listener *pListener, int priority = 0);
SKYRESULT UnRegister(Listener *pLlistener);
protected: // methods
SkyContext();
~SkyContext();
protected: // data
int _iWidth;
int _iHeight;
typedef std::map<HGLRC, SkyMaterial*> ContextMaterialMap;
typedef ContextMaterialMap::iterator ContextMaterialIterator;
typedef std::map<HGLRC, SkyTextureState*> ContextTextureStateMap;
typedef ContextTextureStateMap::iterator ContextTextureStateIterator;
ContextMaterialMap _currentMaterials;
ContextTextureStateMap _currentTextureState;
//------------------------------------------------------------------------------
// Messaging system to handle notification of mode changes
//------------------------------------------------------------------------------
typedef std::pair<int, Listener*> ListenerPair;
class _ListenerPred
{
public:
_ListenerPred(const Listener* l) { _l = l; }
bool operator()(const ListenerPair& pair) { return pair.second == _l; }
protected:
const Listener *_l;
};
SKYRESULT _SendMessage(SkyMessageType msg);
std::list<ListenerPair> _listeners;
};
#endif //__SKYCONTEXT_HPP__

View File

@@ -1,65 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyControlled.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyControlled.hpp
*
* Interface definition for controlled objects.
*/
#ifndef __SKYCONTROLLED_HPP__
#define __SKYCONTROLLED_HPP__
//#include "BHXController.hpp"
template<typename ControlStateType> class SkyController;
//------------------------------------------------------------------------------
/**
* @class SkyControlled
* @brief A base class defining an interface for controlled objects.
*
* This class abstracts the control of objects into a simple interface that a
* class may inherit that allows it to be controlled by SkyController objects.
* A class simply inherits from SkyControlled, which forces the class to implement
* the method UpdateStateFromControls(). This method usually uses the SkyController
* object passed to SetController() to query the input state via
* SkyController::GetControlState().
*
* @see SkyController
*/
template<typename ControlStateType>
class SkyControlled
{
public:
//! Constructor.
SkyControlled() { _pController = NULL; }
//! Destructor
virtual ~SkyControlled() { _pController = NULL; }
//! Sets the controller which will control this controlled object.
void SetController(SkyController<ControlStateType> *pController) { _pController = pController; }
//! Updates the state of the controlled object based on the controls (received from the controller).
virtual SKYRESULT UpdateStateFromControls(SKYTIME timeStep) = 0;
protected:
SkyController<ControlStateType> *_pController;
ControlStateType _controlState;
};
#endif //__SKYCONTROLLED_HPP__

View File

@@ -1,56 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyController.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyController.hpp
*
* Abstract base class for game object controllers.
*/
#ifndef __SKYCONTROLLER_HPP__
#define __SKYCONTROLLER_HPP__
#include "SkyUtil.hpp"
//------------------------------------------------------------------------------
/**
* @class SkyController
* @brief A class that defines an interface for translating general control input into game object control.
*
* This class abstracts game object control from specific control input, such
* as via user interface devices or via artificial intelligence. Subclasses of
* this class implement the method GetControlState() so that objects controlled
* by an instance of a SkyController can query the control state that determines
* their actions. The object need not know whether it is controlled by a human
* or the computer since either controller provides it the same interface.
*
* @see SkyControlled
*/
template <typename ControlStateType>
class SkyController
{
public:
//! Constructor.
SkyController() {}
//! Destructor.
virtual ~SkyController() {}
//! Fills out the control state structure passed in with the current state of controls.
virtual SKYRESULT GetControlState(ControlStateType &controlState) = 0;
};
#endif //__SKYCONTROLLER_HPP__

View File

@@ -1,278 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyDynamicTextureManager.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyDynamicTextureManager.cpp
*
* Implementation of a repository for check out and check in of dynamic textures.
*/
#pragma warning( disable : 4786 )
#include "SkyDynamicTextureManager.hpp"
#include "SkyTexture.hpp"
#include "SkyContext.hpp"
#pragma warning( disable : 4786 )
//! Set this to 1 to print lots of dynamic texture usage messages.
#define SKYDYNTEXTURE_VERBOSE 0
//! The maximum number of textures of each resolution to allow in the checked in pool.
#define SKYDYNTEXTURE_TEXCACHE_LIMIT 32
//------------------------------------------------------------------------------
// Function : SkyDynamicTextureManager::SkyDynamicTextureManager
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyDynamicTextureManager::SkyDynamicTextureManager()
* @brief Constructor.
*/
SkyDynamicTextureManager::SkyDynamicTextureManager()
#ifdef SKYDYNTEXTURE_VERBOSE
: _iNumTextureBytesUsed(0),
_iNumTextureBytesCheckedIn(0),
_iNumTextureBytesCheckedOut(0)
#endif
{
for (int i = 0; i < 11; ++i)
for (int j = 0; j < 11; ++j)
_iAvailableSizeCounts[i][j] = 0;
}
//------------------------------------------------------------------------------
// Function : SkyDynamicTextureManager::~SkyDynamicTextureManager
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyDynamicTextureManager::~SkyDynamicTextureManager()
* @brief Destructor.
*/
SkyDynamicTextureManager::~SkyDynamicTextureManager()
{
for ( TextureSet::iterator subset = _availableTexturePool.begin();
subset != _availableTexturePool.end();
++subset )
{ // iterate over texture subsets.
for ( TextureSubset::iterator texture = (*subset).second->begin();
texture != (*subset).second->end();
++texture )
{
texture->second->Destroy();
delete texture->second;
}
subset->second->clear();
}
_availableTexturePool.clear();
for ( TextureSubset::iterator texture = _checkedOutTexturePool.begin();
texture != _checkedOutTexturePool.end();
++texture )
{
texture->second->Destroy();
delete texture->second;
}
_checkedOutTexturePool.clear();
}
//------------------------------------------------------------------------------
// Function : SkyDynamicTextureManager::CheckOutTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyDynamicTextureManager::CheckOutTexture(unsigned int iWidth, unsigned int iHeight)
* @brief Returns a texture from the available pool, creating a new one if necessary.
*
* Thi texture returned by this method is checked out: it will be maintained in a
* checked out pool until it is checked in with CheckInTexture(). The texture is owned
* by the SkyDynamicTextureManager -- it should not be deleted by another object. Checked out
* textures can be modified (copied, or rendered to, etc.), but should not be reallocated
* or resized. All checked out textures will be deleted when the SkyDynamicTextureManager
* is destroyed, so this manager should be destroyed only after rendering ceases.
*/
SkyTexture* SkyDynamicTextureManager::CheckOutTexture(unsigned int iWidth,
unsigned int iHeight)
{
int iWidthLog, iHeightLog;
iWidthLog = SkyGetLogBaseTwo(iWidth);
iHeightLog = SkyGetLogBaseTwo(iHeight);
// first see if a texture of this resolution is available:
// find the subset of textures with width = iWidth, if it exists.
TextureSet::iterator subset = _availableTexturePool.find(iWidth);
if (subset != _availableTexturePool.end())
{ // found the iWidth subset
// now find a texture with height = iHeight:
TextureSubset::iterator texture = (*subset).second->find(iHeight);
if (texture != (*subset).second->end())
{ // found one!
// extract the texture
SkyTexture *pTexture = (*texture).second;
(*texture).second = NULL;
// first remove it from this set.
(*subset).second->erase(texture);
// now add it to the checked out texture set.
_checkedOutTexturePool.insert(TextureSubset::value_type(pTexture->GetID(), pTexture));
// update checked out/in amount.
#if SKYDYNTEXTURE_VERBOSE
_iNumTextureBytesCheckedIn -= iWidth * iHeight * 4;
_iNumTextureBytesCheckedOut += iWidth * iHeight * 4;
printf("CHECKOUT: %d x %d\n", iWidth, iHeight);
#endif
_iAvailableSizeCounts[iWidthLog][iHeightLog]--;
// we're now free to give this texture to the user
return pTexture;
}
else
{ // we didn't find an iWidth x iHeight texture, although the iWidth subset exists
// create a new texture of the appropriate dimensions and return it.
SkyTexture *pNewTexture = CreateDynamicTexture(iWidth, iHeight);
_checkedOutTexturePool.insert(TextureSubset::value_type(pNewTexture->GetID(),
pNewTexture));
#if SKYDYNTEXTURE_VERBOSE
_iNumTextureBytesCheckedOut += iWidth * iHeight * 4;
#endif
return pNewTexture;
}
}
else
{ // we don't yet have a subset for iWidth textures. Create one.
TextureSubset *pSubset = new TextureSubset;
_availableTexturePool.insert(TextureSet::value_type(iWidth, pSubset));
// now create a new texture of the appropriate dimensions and return it.
SkyTexture *pNewTexture = CreateDynamicTexture(iWidth, iHeight);
_checkedOutTexturePool.insert(TextureSubset::value_type(pNewTexture->GetID(), pNewTexture));
#if SKYDYNTEXTURE_VERBOSE
_iNumTextureBytesCheckedOut += iWidth * iHeight * 4;
#endif
return pNewTexture;
}
}
//------------------------------------------------------------------------------
// Function : SkyDynamicTextureManager::CheckInTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyDynamicTextureManager::CheckInTexture(SkyTexture *pTexture)
* @brief Returns a checked-out texture to the available pool.
*
* This method removes the checked out texture from the checked out pool if it is
* checked out, and then checks it in to the available pool.
*/
void SkyDynamicTextureManager::CheckInTexture(SkyTexture *pTexture)
{
// first see if the texture is in the checked out pool.
TextureSubset::iterator coTexture = _checkedOutTexturePool.find(pTexture->GetID());
if (coTexture != _checkedOutTexturePool.end())
{ // if it is there, remove it.
_checkedOutTexturePool.erase(coTexture);
_iNumTextureBytesCheckedOut -= pTexture->GetWidth() * pTexture->GetHeight() * 4;
}
// Don't cache too many unused textures.
int iWidthLog, iHeightLog;
iWidthLog = SkyGetLogBaseTwo(pTexture->GetWidth());
iHeightLog = SkyGetLogBaseTwo(pTexture->GetHeight());
if (_iAvailableSizeCounts[iWidthLog][iHeightLog] >= SKYDYNTEXTURE_TEXCACHE_LIMIT)
{
#if SKYDYNTEXTURE_VERBOSE
_iNumTextureBytesUsed -= pTexture->GetWidth() * pTexture->GetHeight() * 4;
printf("%dx%d texture DESTROYED.\n\t Total memory used: %d bytes.\n",
pTexture->GetWidth(), pTexture->GetHeight(), _iNumTextureBytesUsed);
#endif
pTexture->Destroy();
SAFE_DELETE(pTexture);
return;
}
// now check the texture into the available pool.
// find the width subset:
TextureSet::iterator subset = _availableTexturePool.find(pTexture->GetWidth());
if (subset != _availableTexturePool.end())
{ // the subset exists. Add the texture to it
(*subset).second->insert(TextureSubset::value_type(pTexture->GetHeight(), pTexture));
_iNumTextureBytesCheckedIn += pTexture->GetWidth() * pTexture->GetHeight() * 4;
_iAvailableSizeCounts[iWidthLog][iHeightLog]++;
}
else
{ // subset not found. Create it.
TextureSubset *pSubset = new TextureSubset;
// insert the texture.
pSubset->insert(TextureSubset::value_type(pTexture->GetHeight(), pTexture));
// insert the subset into the available pool
_availableTexturePool.insert(TextureSet::value_type(pTexture->GetWidth(), pSubset));
#if SKYDYNTEXTURE_VERBOSE
_iNumTextureBytesCheckedIn += pTexture->GetWidth() * pTexture->GetHeight() * 4;
_iAvailableSizeCounts[iWidthLog][iHeightLog]++;
#endif
}
pTexture = NULL;
}
//------------------------------------------------------------------------------
// Function : SkyDynamicTextureManager::CreateDynamicTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyDynamicTextureManager::CreateDynamicTexture(unsigned int iWidth, unsigned int iHeight)
* @brief Allocate a new dynamic texture object of the given resolution.
*
* This method is used by CheckOutTexture() when it can't find an available texture of
* the requested resolution. It can also be called externally, but will result in an
* unmanaged texture unless the new texture is subsequently checked in using CheckInTexture().
*/
SkyTexture* SkyDynamicTextureManager::CreateDynamicTexture(unsigned int iWidth, unsigned int iHeight)
{
unsigned int iID;
glGenTextures(1, &iID);
SkyTexture *pNewTexture = new SkyTexture(iWidth, iHeight, iID);
glBindTexture(GL_TEXTURE_2D, pNewTexture->GetID());
// set default filtering.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// create an empty buffer
unsigned char *pData = new unsigned char[iWidth * iHeight * 4];
// allocate the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, iWidth, iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pData );
delete [] pData;
// update the used texture bytes...
_iNumTextureBytesUsed += iWidth * iHeight * 4;
#if SKYDYNTEXTURE_VERBOSE
printf("New %dx%d texture created.\n\t Total memory used: %d bytes\n", iWidth, iHeight, _iNumTextureBytesUsed);
printf("\tTotal memory checked in: %d\n", _iNumTextureBytesCheckedIn);
printf("\tTotal memory checked out: %d\n", _iNumTextureBytesCheckedOut);
#endif
return pNewTexture;
}

View File

@@ -1,92 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyDynamicTextureManager.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyDynamicTextureManager.hpp
*
* Interface definition of a repository for check out and check in of dynamic textures.
*/
#ifndef __SKYDYNAMICTEXTUREMANAGER_HPP__
#define __SKYDYNAMICTEXTUREMANAGER_HPP__
// warning for truncation of template name for browse info
#pragma warning( disable : 4786)
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <map>
#include <simgear/compiler.h>
#include SG_GL_H
#include "SkyUtil.hpp"
#include "SkySingleton.hpp"
using namespace std;
class SkyTexture;
class SkyDynamicTextureManager;
//! Dynamic Texture Manager Singleton declaration.
/*! The DynamicTextureManager must be created by calling DynamicTextureManager::Instantiate(). */
typedef SkySingleton<SkyDynamicTextureManager> DynamicTextureManager;
//------------------------------------------------------------------------------
/**
* @class SkyDynamicTextureManager
* @brief A repository that allows check-out and check-in from a pool of dynamic textures.
*
* When an object needs a dynamic texture, it checks it out using CheckOutTexture(), passing
* the resolution of the texture it needs. When the object is done with the texture, it
* calls CheckInTexture(). New dynamic textures can be allocated by calling CreateDynamicTexture,
* but these textures will be unmanaged.
*/
class SkyDynamicTextureManager
{
public:
SkyTexture* CheckOutTexture(unsigned int iWidth, unsigned int iHeight);
void CheckInTexture(SkyTexture* pTexture);
SkyTexture* CreateDynamicTexture(unsigned int iWidth, unsigned int iHeight);
protected: // methods
SkyDynamicTextureManager(); // these are protected because it is a singleton.
~SkyDynamicTextureManager();
protected: // datatypes
typedef multimap<unsigned int, SkyTexture*> TextureSubset;
typedef multimap<unsigned int, TextureSubset*> TextureSet;
protected: // data
TextureSet _availableTexturePool;
TextureSubset _checkedOutTexturePool;
unsigned int _iAvailableSizeCounts[11][11];
unsigned int _iNumTextureBytesUsed;
unsigned int _iNumTextureBytesCheckedOut;
unsigned int _iNumTextureBytesCheckedIn;
};
#endif //__SKYDYNAMICTEXTUREMANAGER_HPP__

View File

@@ -1,240 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyLight.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyLight.cpp
*
* Implementation of a class that maintains the state and operation of a light.
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include SG_GLU_H
#include "glut_shapes.h"
#ifdef WIN32
# ifdef _MSC_VER
# pragma warning( disable : 4786)
# endif
# include "extgl.h"
#endif
#include "SkyLight.hpp"
#include "SkyMaterial.hpp"
#include "mat44.hpp"
SkyMaterial* SkyLight::s_pMaterial = NULL;
//------------------------------------------------------------------------------
// Function : SkyLight::SkyLight
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyLight::SkyLight(SkyLightType eType)
* @brief @todo <WRITE BRIEF SkyLight::SkyLight DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyLight::SkyLight FUNCTION DOCUMENTATION>
*/
SkyLight::SkyLight(SkyLightType eType)
: _bEnabled(true),
_bDirty(true),
_iLastGLID(-1),
_eType(eType),
_vecPosition(0, 0, 1, 1),
_vecDirection(0, 0, -1, 0),
_vecDiffuse(1, 1, 1, 1),
_vecAmbient(0, 0, 0, 0),
_vecSpecular(1, 1, 1, 1),
_vecAttenuation(1, 0, 0),
_rSpotExponent(0),
_rSpotCutoff(180)
{
if (!s_pMaterial)
{
s_pMaterial = new SkyMaterial;
s_pMaterial->SetColorMaterialMode(GL_DIFFUSE);
s_pMaterial->EnableColorMaterial(true);
s_pMaterial->EnableLighting(false);
}
}
//------------------------------------------------------------------------------
// Function : SkyLight::~SkyLight
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyLight::~SkyLight()
* @brief @todo <WRITE BRIEF SkyLight::~SkyLight DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyLight::~SkyLight FUNCTION DOCUMENTATION>
*/
SkyLight::~SkyLight()
{
}
//------------------------------------------------------------------------------
// Function : SkyLight::Display
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyLight::Display() const
* @brief Displays a wireframe representation of the light.
*
* This is useful for debugging.
*/
void SkyLight::Display() const
{
s_pMaterial->Activate();
//if (_bEnabled)
//glColor3fv(&(_vecDiffuse.x));
//else
glColor3f(0, 0, 0);
switch(_eType)
{
case SKY_LIGHT_POINT:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
{
glTranslatef(_vecPosition.x, _vecPosition.y, _vecPosition.z);
glutWireSphere(4, 8, 8);
}
glPopMatrix();
break;
case SKY_LIGHT_DIRECTIONAL:
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
{
Mat44f mat;
Vec3f vecPos(_vecPosition.x, _vecPosition.y, _vecPosition.z);
Vec3f vecDir(_vecDirection.x, _vecDirection.y, _vecDirection.z);
Vec3f vecUp(0, 1, 0);
if (fabs(vecDir * vecUp) - 1 < 1e-6) // check that the view and up directions are not parallel.
vecUp.Set(1, 0, 0);
mat.invLookAt(vecPos, vecPos + 10 * vecDir, vecUp);
glPushMatrix();
{
glTranslatef(-50 * vecDir.x, -50 * vecDir.y, -50 * vecDir.z);
glMultMatrixf(mat);
glutWireCone(10, 10, 4, 1);
}
glPopMatrix();
glMultMatrixf(mat);
GLUquadric *pQuadric = gluNewQuadric();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
gluCylinder(pQuadric, 4, 4, 50, 4, 4);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
glPopMatrix();
}
break;
case SKY_LIGHT_SPOT:
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
{
Mat44f mat;
Vec3f vecUp = Vec3f(0, 1, 0);
Vec3f vecPos(_vecPosition.x, _vecPosition.y, _vecPosition.z);
Vec3f vecDir(_vecDirection.x, _vecDirection.y, _vecDirection.z);
if (_vecDirection == vecUp)
vecUp.Set(1, 0, 0);
mat.invLookAt(vecPos + 50 * vecDir, vecPos + 51 * vecDir, vecUp);
glMultMatrixf(mat);
float rAlpha= acos(pow(10.0, (-12.0 / _rSpotExponent)));
//glutWireCone(50 * tan(SKYDEGREESTORADS * rAlpha), 50, 16, 8);
glutWireCone(50 * tan(SKYDEGREESTORADS * _rSpotCutoff), 50, 16, 8);
}
glPopMatrix();
}
break;
default:
break;
}
}
//------------------------------------------------------------------------------
// Function : SkyLight::Activate
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyLight::Activate(int iLightID)
* @brief @todo <WRITE BRIEF SkyLight::Activate DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyLight::Activate FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyLight::Activate(int iLightID)
{
glPushMatrix();
// set the position every frame
if (SKY_LIGHT_DIRECTIONAL != _eType)
glLightfv(GL_LIGHT0 + iLightID, GL_POSITION, &(_vecPosition.x));
else
glLightfv(GL_LIGHT0 + iLightID, GL_POSITION, &(_vecDirection.x));
if (SKY_LIGHT_SPOT == _eType)
glLightfv(GL_LIGHT0 + iLightID, GL_SPOT_DIRECTION, &(_vecDirection.x));
// set other light properties only when they change.
if (_bDirty || iLightID != _iLastGLID)
{
glLightfv(GL_LIGHT0 + iLightID, GL_DIFFUSE, &(_vecDiffuse.x));
glLightfv(GL_LIGHT0 + iLightID, GL_AMBIENT, &(_vecAmbient.x));
glLightfv(GL_LIGHT0 + iLightID, GL_SPECULAR, &(_vecSpecular.x));
glLightf(GL_LIGHT0 + iLightID, GL_CONSTANT_ATTENUATION, _vecAttenuation.x);
glLightf(GL_LIGHT0 + iLightID, GL_LINEAR_ATTENUATION, _vecAttenuation.y);
glLightf(GL_LIGHT0 + iLightID, GL_QUADRATIC_ATTENUATION, _vecAttenuation.z);
if (SKY_LIGHT_SPOT == _eType)
{
glLightf(GL_LIGHT0 + iLightID, GL_SPOT_CUTOFF, _rSpotCutoff);
glLightf(GL_LIGHT0 + iLightID, GL_SPOT_EXPONENT, _rSpotExponent);
}
else
{
glLightf(GL_LIGHT0 + iLightID, GL_SPOT_CUTOFF, 180);
glLightf(GL_LIGHT0 + iLightID, GL_SPOT_EXPONENT, 0);
}
if (_bEnabled)
glEnable(GL_LIGHT0 + iLightID);
else
{
glDisable(GL_LIGHT0 + iLightID);
}
_iLastGLID = iLightID;
_bDirty = false;
}
glPopMatrix();
return SKYRESULT_OK;
}

View File

@@ -1,97 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyLight.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyLight.hpp
*
* Definition of a class that maintains the state and operation of a light.
*/
#ifndef __SKYLIGHT_HPP__
#define __SKYLIGHT_HPP__
#include "vec3f.hpp"
#include "vec4f.hpp"
#include "SkyUtil.hpp"
class SkyMaterial;
class SkyLight
{
public: // types
enum SkyLightType
{
SKY_LIGHT_POINT,
SKY_LIGHT_DIRECTIONAL,
SKY_LIGHT_SPOT,
SKY_LIGHT_NUM_TYPES
};
public: // methods
SkyLight(SkyLightType eType);
virtual ~SkyLight();
// for visualization of light positions / directions.
void Display() const;
bool GetEnabled() const { return _bEnabled; }
SkyLightType GetType() const { return _eType; }
const float* GetPosition() const { return _vecPosition; }
const float* GetDirection() const { return _vecDirection; }
const float* GetDiffuse() const { return _vecDiffuse; }
const float* GetAmbient() const { return _vecAmbient; }
const float* GetSpecular() const { return _vecSpecular; }
const float* GetAttenuation() const { return _vecAttenuation; }
float GetSpotExponent() const { return _rSpotExponent; }
float GetSpotCutoff() const { return _rSpotCutoff; }
void Enable(bool bEnable) { _bEnabled = bEnable; _bDirty = true; }
void SetType(const SkyLightType& t) { _eType = t; _bDirty = true; }
void SetPosition(const float pos[3])
{ _vecPosition.Set(pos[0], pos[1], pos[2], (_eType != SKY_LIGHT_DIRECTIONAL)); _bDirty = true; }
void SetDirection(const float dir[3]) { _vecDirection.Set(dir[0], dir[1], dir[2], 0); _bDirty = true; }
void SetDiffuse(const float color[4]) { _vecDiffuse.Set(color); _bDirty = true; }
void SetAmbient(const float color[4]) { _vecAmbient.Set(color); _bDirty = true; }
void SetSpecular(const float color[4]){ _vecSpecular.Set(color); _bDirty = true; }
void SetAttenuation(float rConstant, float rLinear, float rQuadratic)
{ _vecAttenuation.Set(rConstant, rLinear, rQuadratic); _bDirty = true; }
void SetSpotExponent(float rExp) { _rSpotExponent = rExp; _bDirty = true; }
void SetSpotCutoff(float rCutoff) { _rSpotCutoff = rCutoff; _bDirty = true; }
SKYRESULT Activate(int iLightID);
protected: // data
bool _bEnabled;
bool _bDirty;
int _iLastGLID;
SkyLightType _eType;
Vec4f _vecPosition;
Vec4f _vecDirection;
Vec4f _vecDiffuse;
Vec4f _vecAmbient;
Vec4f _vecSpecular;
Vec3f _vecAttenuation; // constant, linear, and quadratic attenuation factors.
float _rSpotExponent;
float _rSpotCutoff;
static SkyMaterial *s_pMaterial; // used for rendering the lights during debugging
};
#endif //__SKYLIGHT_HPP__

View File

@@ -1,445 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyMaterial.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyMaterial.cpp
*
* Implementation of class SkyMaterial, a meterial property object.
*/
#include "SkyMaterial.hpp"
#include "SkyContext.hpp"
//------------------------------------------------------------------------------
// Function : SkyMaterial::SkyMaterial
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::SkyMaterial()
* @brief Constructor.
*/
SkyMaterial::SkyMaterial()
: _iMaterialID(-1),
_vecDiffuse(Vec4f::ZERO),
_vecSpecular(Vec4f::ZERO),
_vecAmbient(Vec4f::ZERO),
_vecEmissive(Vec4f::ZERO),
_rSpecularPower(0),
_bLighting(true),
_eColorMaterialFace(GL_FRONT_AND_BACK),
_eColorMaterialMode(GL_AMBIENT_AND_DIFFUSE),
_bColorMaterial(false),
_vecFogColor(Vec4f::ZERO),
_eFogMode(GL_EXP),
_bFog(false),
_eDepthFunc(GL_LESS),
_bDepthMask(true),
_bDepthTest(true),
_eAlphaFunc(GL_ALWAYS),
_rAlphaRef(0),
_bAlphaTest(false),
_eBlendSrcFactor(GL_ONE),
_eBlendDstFactor(GL_ZERO),
_bBlending(false),
_bFaceCulling(false),
_eFaceCullingMode(GL_BACK),
_eTextureEnvMode(GL_MODULATE)
{
_rFogParams[SKY_FOG_DENSITY] = 1;
_rFogParams[SKY_FOG_START] = 0;
_rFogParams[SKY_FOG_END] = 1;
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::~SkyMaterial
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::~SkyMaterial()
* @brief Destructor.
*/
SkyMaterial::~SkyMaterial()
{
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::SetFogParameter
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::SetFogParameter(GLenum eParameter, float rValue)
*/
SKYRESULT SkyMaterial::SetFogParameter(GLenum eParameter, float rValue)
{
switch (eParameter)
{
case GL_FOG_DENSITY:
_rFogParams[SKY_FOG_DENSITY] = rValue;
break;
case GL_FOG_START:
_rFogParams[SKY_FOG_START] = rValue;
break;
case GL_FOG_END:
_rFogParams[SKY_FOG_END] = rValue;
break;
default:
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyMaterial::SetFogParameter(): Invalid parameter.");
break;
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::GetFogParameter
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::GetFogParameter(GLenum eParameter) const
*/
float SkyMaterial::GetFogParameter(GLenum eParameter) const
{
switch (eParameter)
{
case GL_FOG_DENSITY:
return _rFogParams[SKY_FOG_DENSITY];
break;
case GL_FOG_START:
return _rFogParams[SKY_FOG_START];
break;
case GL_FOG_END:
return _rFogParams[SKY_FOG_END];
break;
default:
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyMaterial::GetFogParameter(): Invalid parameter.");
break;
}
return -1;
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::Activate
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::Activate()
* @brief @todo <WRITE BRIEF SkyMaterial::SetMaterialPropertiesForDisplay DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyMaterial::SetMaterialPropertiesForDisplay FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyMaterial::Activate()
{
// Update the cached current material, and only pass values that have changed to the GL.
SkyMaterial *pCurrentMaterial = GraphicsContext::InstancePtr()->GetCurrentMaterial();
assert(NULL != pCurrentMaterial);
// basic material properties
if (pCurrentMaterial->GetDiffuse() != GetDiffuse())
{
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &(GetDiffuse().x));
pCurrentMaterial->SetDiffuse(GetDiffuse());
}
if (pCurrentMaterial->GetSpecular() != GetSpecular())
{
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(GetSpecular().x));
pCurrentMaterial->SetSpecular(GetSpecular());
}
if (pCurrentMaterial->GetAmbient() != GetAmbient())
{
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &(GetAmbient().x));
pCurrentMaterial->SetAmbient(GetAmbient());
}
if (pCurrentMaterial->GetEmissive() != GetEmissive())
{
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &(GetEmissive().x));
pCurrentMaterial->SetEmissive(GetEmissive());
}
if (pCurrentMaterial->GetSpecularPower() != GetSpecularPower())
{
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, GetSpecularPower());
pCurrentMaterial->SetSpecularPower(GetSpecularPower());
}
// lighting
if (pCurrentMaterial->IsLightingEnabled() != IsLightingEnabled())
{
if (IsLightingEnabled())
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
pCurrentMaterial->EnableLighting(IsLightingEnabled());
}
// color material (which material property tracks color calls)
if (pCurrentMaterial->GetColorMaterialFace() != GetColorMaterialFace() ||
pCurrentMaterial->GetColorMaterialMode() != GetColorMaterialMode())
{
glColorMaterial(GetColorMaterialFace(), GetColorMaterialMode());
pCurrentMaterial->SetColorMaterialFace(GetColorMaterialFace());
pCurrentMaterial->SetColorMaterialMode(GetColorMaterialMode());
}
if (pCurrentMaterial->IsColorMaterialEnabled() != IsColorMaterialEnabled())
{
if (IsColorMaterialEnabled())
glEnable(GL_COLOR_MATERIAL);
else
glDisable(GL_COLOR_MATERIAL);
pCurrentMaterial->EnableColorMaterial(IsColorMaterialEnabled());
}
// fog
if (pCurrentMaterial->GetFogMode() != GetFogMode())
{
glFogf(GL_FOG_MODE, GetFogMode());
pCurrentMaterial->SetFogMode(GetFogMode());
}
if (pCurrentMaterial->GetFogColor() != GetFogColor())
{
glFogfv(GL_FOG_COLOR, GetFogColor());
pCurrentMaterial->SetFogColor(GetFogColor());
}
if (pCurrentMaterial->GetFogParameter(GL_FOG_DENSITY) != GetFogParameter(GL_FOG_DENSITY))
{
glFogf(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
pCurrentMaterial->SetFogParameter(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
}
if (pCurrentMaterial->GetFogParameter(GL_FOG_START) != GetFogParameter(GL_FOG_START))
{
glFogf(GL_FOG_START, GetFogParameter(GL_FOG_START));
pCurrentMaterial->SetFogParameter(GL_FOG_START, GetFogParameter(GL_FOG_START));
}
if (pCurrentMaterial->GetFogParameter(GL_FOG_END) != GetFogParameter(GL_FOG_END))
{
glFogf(GL_FOG_END, GetFogParameter(GL_FOG_END));
pCurrentMaterial->SetFogParameter(GL_FOG_END, GetFogParameter(GL_FOG_END));
}
if (pCurrentMaterial->IsFogEnabled() != IsFogEnabled())
{
if (IsFogEnabled())
glEnable(GL_FOG);
else
glDisable(GL_FOG);
pCurrentMaterial->EnableFog(IsFogEnabled());
}
// depth test
if (pCurrentMaterial->GetDepthFunc() != GetDepthFunc())
{
glDepthFunc(GetDepthFunc());
pCurrentMaterial->SetDepthFunc(GetDepthFunc());
}
if (pCurrentMaterial->GetDepthMask() != GetDepthMask())
{
glDepthMask(GetDepthMask());
pCurrentMaterial->SetDepthMask(GetDepthMask());
}
if (pCurrentMaterial->IsDepthTestEnabled() != IsDepthTestEnabled())
{
if (IsDepthTestEnabled())
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
pCurrentMaterial->EnableDepthTest(IsDepthTestEnabled());
}
// alpha test
if (pCurrentMaterial->GetAlphaFunc() != GetAlphaFunc() ||
pCurrentMaterial->GetAlphaRef() != GetAlphaRef())
{
glAlphaFunc(GetAlphaFunc(), GetAlphaRef());
pCurrentMaterial->SetAlphaFunc(GetAlphaFunc());
pCurrentMaterial->SetAlphaRef(GetAlphaRef());
}
if (pCurrentMaterial->IsAlphaTestEnabled() != IsAlphaTestEnabled())
{
if (IsAlphaTestEnabled())
glEnable(GL_ALPHA_TEST);
else
glDisable(GL_ALPHA_TEST);
pCurrentMaterial->EnableAlphaTest(IsAlphaTestEnabled());
}
// blending
if (pCurrentMaterial->GetBlendingSourceFactor() != GetBlendingSourceFactor() ||
pCurrentMaterial->GetBlendingDestFactor() != GetBlendingDestFactor())
{
glBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
pCurrentMaterial->SetBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
}
if (pCurrentMaterial->IsBlendingEnabled() != IsBlendingEnabled())
{
if (IsBlendingEnabled())
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
pCurrentMaterial->EnableBlending(IsBlendingEnabled());
}
if (pCurrentMaterial->GetFaceCullingMode() != GetFaceCullingMode())
{
glCullFace(GetFaceCullingMode());
pCurrentMaterial->SetFaceCullingMode(GetFaceCullingMode());
}
if (pCurrentMaterial->IsFaceCullingEnabled() != IsFaceCullingEnabled())
{
if (IsFaceCullingEnabled())
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
pCurrentMaterial->EnableFaceCulling(IsFaceCullingEnabled());
}
// texturing
FAIL_RETURN(_textureState.Activate());
if (pCurrentMaterial->GetTextureApplicationMode() != GetTextureApplicationMode())
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GetTextureApplicationMode());
pCurrentMaterial->SetTextureApplicationMode(GetTextureApplicationMode());
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::Force
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::Force()
* @brief @todo <WRITE BRIEF SkyMaterial::SetMaterialPropertiesForDisplay DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyMaterial::SetMaterialPropertiesForDisplay FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyMaterial::Force()
{
// Update the cached current material, and only pass values that have changed to the GL.
SkyMaterial *pCurrentMaterial = GraphicsContext::InstancePtr()->GetCurrentMaterial();
assert(NULL != pCurrentMaterial);
// basic material properties
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &(GetDiffuse().x));
pCurrentMaterial->SetDiffuse(GetDiffuse());
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(GetSpecular().x));
pCurrentMaterial->SetSpecular(GetSpecular());
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &(GetAmbient().x));
pCurrentMaterial->SetAmbient(GetAmbient());
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &(GetEmissive().x));
pCurrentMaterial->SetEmissive(GetEmissive());
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, GetSpecularPower());
pCurrentMaterial->SetSpecularPower(GetSpecularPower());
// lighting
if (IsLightingEnabled())
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
pCurrentMaterial->EnableLighting(IsLightingEnabled());
// color material (which material property tracks color calls)
glColorMaterial(GetColorMaterialFace(), GetColorMaterialMode());
pCurrentMaterial->SetColorMaterialFace(GetColorMaterialFace());
pCurrentMaterial->SetColorMaterialMode(GetColorMaterialMode());
if (IsColorMaterialEnabled())
glEnable(GL_COLOR_MATERIAL);
else
glDisable(GL_COLOR_MATERIAL);
pCurrentMaterial->EnableColorMaterial(IsColorMaterialEnabled());
// fog
glFogf(GL_FOG_MODE, GetFogMode());
pCurrentMaterial->SetFogMode(GetFogMode());
glFogfv(GL_FOG_COLOR, GetFogColor());
pCurrentMaterial->SetFogColor(GetFogColor());
glFogf(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
pCurrentMaterial->SetFogParameter(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
glFogf(GL_FOG_START, GetFogParameter(GL_FOG_START));
pCurrentMaterial->SetFogParameter(GL_FOG_START, GetFogParameter(GL_FOG_START));
glFogf(GL_FOG_END, GetFogParameter(GL_FOG_END));
pCurrentMaterial->SetFogParameter(GL_FOG_END, GetFogParameter(GL_FOG_END));
if (IsFogEnabled())
glEnable(GL_FOG);
else
glDisable(GL_FOG);
pCurrentMaterial->EnableFog(IsFogEnabled());
// depth test
glDepthFunc(GetDepthFunc());
pCurrentMaterial->SetDepthFunc(GetDepthFunc());
glDepthMask(GetDepthMask());
pCurrentMaterial->SetDepthMask(GetDepthMask());
if (IsDepthTestEnabled())
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
pCurrentMaterial->EnableDepthTest(IsDepthTestEnabled());
// alpha test
glAlphaFunc(GetAlphaFunc(), GetAlphaRef());
pCurrentMaterial->SetAlphaFunc(GetAlphaFunc());
pCurrentMaterial->SetAlphaRef(GetAlphaRef());
if (IsAlphaTestEnabled())
glEnable(GL_ALPHA_TEST);
else
glDisable(GL_ALPHA_TEST);
// blending
glBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
pCurrentMaterial->SetBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
if (IsBlendingEnabled())
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
pCurrentMaterial->EnableBlending(IsBlendingEnabled());
glCullFace(GetFaceCullingMode());
pCurrentMaterial->SetFaceCullingMode(GetFaceCullingMode());
if (IsFaceCullingEnabled())
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
pCurrentMaterial->EnableFaceCulling(IsFaceCullingEnabled());
// texturing
FAIL_RETURN(_textureState.Force());
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GetTextureApplicationMode());
pCurrentMaterial->SetTextureApplicationMode(GetTextureApplicationMode());
return SKYRESULT_OK;
}

View File

@@ -1,280 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyMaterial.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyMaterial.hpp
*
* Interface definition for class SkyMaterial, a meterial property object.
*/
#ifndef __SKYMATERIAL_HPP__
#define __SKYMATERIAL_HPP__
// #pragma warning( disable : 4786)
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include SG_GL_H
#include "vec4f.hpp"
#include "SkyUtil.hpp"
#include "SkyTextureManager.hpp"
#include "SkyTextureState.hpp"
// forward
class SkyRenderable;
//------------------------------------------------------------------------------
/**
* @class SkyMaterial
* @brief A class for organizing and caching material state.
*
* This class handles setting and querying material state. By calling the Activate()
* method, the material's state can be made current in OpenGL. The material will not
* set states that are currently active in the current OpenGL context.
*/
class SkyMaterial
{
public:
SkyMaterial();
~SkyMaterial();
SKYRESULT Activate();
SKYRESULT Force();
// Getters for basic material properties
//! Returns the material identifier.
int GetMaterialID() const { return _iMaterialID; }
//! Returns the material diffuse color.
const Vec4f& GetDiffuse() const { return _vecDiffuse; }
//! Returns the material specular color.
const Vec4f& GetSpecular() const { return _vecSpecular; }
//! Returns the material ambient color.
const Vec4f& GetAmbient() const { return _vecAmbient; }
//! Returns the material emissive color.
const Vec4f& GetEmissive() const { return _vecEmissive; }
//! Returns the material specular power (shininess).
const float GetSpecularPower() const { return _rSpecularPower; }
// lighting
//! Returns true if lighting is enabled for this material.
bool IsLightingEnabled() const { return _bLighting; }
// color material (which material property tracks color calls)
//! Returns the face for which color material tracking is enabled.
GLenum GetColorMaterialFace() const { return _eColorMaterialFace; }
//! Returns the color material tracking mode.
GLenum GetColorMaterialMode() const { return _eColorMaterialMode; }
//! Returns true if color material tracking is enabled.
bool IsColorMaterialEnabled() const { return _bColorMaterial; }
//! Returns the fog density or start / end distance.
float GetFogParameter(GLenum eParameter) const;
//! Returns the fog mode (exponential, linear, etc.)
GLenum GetFogMode() const { return _eFogMode; }
//! Returns the fog color.
const Vec4f& GetFogColor() const { return _vecFogColor; }
//! Returns true if fog is enabled for this material.
bool IsFogEnabled() const { return _bFog; }
// texturing
//! Returns the active texture target for texture unit @a iTextureUnit.
GLenum GetActiveTarget(unsigned int iTextureUnit) const
{ return _textureState.GetActiveTarget(iTextureUnit); }
//! Returns the bound texture ID for texture unit @a iTextureUnit.
unsigned int GetTextureID(unsigned int iTextureUnit) const
{ return _textureState.GetTextureID(iTextureUnit); }
//! Returns true if texturing is enabled for texture unit @a iTextureUnit.
bool IsTextureEnabled(unsigned int iTextureUnit) const
{ return _textureState.IsTextureEnabled(iTextureUnit); }
//! Returns the value of the texture parameter @a eParameter for texture unit @a iTextureUnit.
GLenum GetTextureParameter(unsigned int iTextureUnit, GLenum eParameter) const
{ return _textureState.GetTextureParameter(iTextureUnit, eParameter); }
//! Returns the texture application mode of the texture environment.
GLenum GetTextureApplicationMode() const { return _eTextureEnvMode; }
//! Returns a reference to the texture state object owned by this materal.
SkyTextureState& GetTextureState() { return _textureState; }
// depth test
//! Returns true if depth testing is enabled for this material.
bool IsDepthTestEnabled() const { return _bDepthTest; }
//! Returns the depth test function for this material.
GLenum GetDepthFunc() const { return _eDepthFunc; }
//! Returns true if depth writes are enabled for this material, false if not.
bool GetDepthMask() const { return _bDepthMask; }
// alpha test
//! Returns true if alpha testing is enabled for this material.
bool IsAlphaTestEnabled() const { return _bAlphaTest; }
//! Returns the alpha test function for this material.
GLenum GetAlphaFunc() const { return _eAlphaFunc; }
//! Returns the reference value for alpha comparison.
float GetAlphaRef() const { return _rAlphaRef; }
// blending
//! Returns true if blending is enabled for this material.
bool IsBlendingEnabled() const { return _bBlending; }
//! Returns the source blending factor for this material.
GLenum GetBlendingSourceFactor() const { return _eBlendSrcFactor; }
//! Returns the destination blending factor for this material.
GLenum GetBlendingDestFactor() const { return _eBlendDstFactor; }
//! Returns true if face culling enabled for this material.
bool IsFaceCullingEnabled() const { return _bFaceCulling; }
//! Returns which faces are culled -- front-facing or back-facing.
GLenum GetFaceCullingMode() const { return _eFaceCullingMode; }
// Setters for basic material properties
//! Sets the material identifier.
void SetMaterialID(int ID) { _iMaterialID = ID; }
//! Sets the diffuse material color.
void SetDiffuse( const Vec4f& d) { _vecDiffuse = d; }
//! Sets the specular material color.
void SetSpecular(const Vec4f& d) { _vecSpecular = d; }
//! Sets the ambient material color.
void SetAmbient( const Vec4f& d) { _vecAmbient = d; }
//! Sets the emissive material color.
void SetEmissive(const Vec4f& d) { _vecEmissive = d; }
//! Sets the material specular power (shininess).
void SetSpecularPower(float power) { _rSpecularPower = power; }
// lighting
//! Enables / Disables lighting for this material.
void EnableLighting(bool bEnable) { _bLighting = bEnable; }
// color material (which material property tracks color calls)
//! Sets which faces (front or back) track color calls.
void SetColorMaterialFace(GLenum eFace) { _eColorMaterialFace = eFace; }
//! Sets which material property tracks color calls.
void SetColorMaterialMode(GLenum eMode) { _eColorMaterialMode = eMode; }
//! Enables / Disables material color tracking for this material.
void EnableColorMaterial(bool bEnable) { _bColorMaterial = bEnable; }
//! Sets the fog density or start / end distance.
SKYRESULT SetFogParameter(GLenum eParameter, float rValue);
//! Sets the fog mode (exponential, linear, etc.)
void SetFogMode(GLenum eMode) { _eFogMode = eMode; }
//! Sets the fog color.
void SetFogColor(const Vec4f& color) { _vecFogColor = color; }
//! Enables / Disables fog for this material.
void EnableFog(bool bEnable) { _bFog = bEnable; }
// texturing
//! Sets the bound texture and texture target for texture unit @a iTextureUnit.
SKYRESULT SetTexture(unsigned int iTextureUnit, GLenum eTarget, SkyTexture& texture)
{ return _textureState.SetTexture(iTextureUnit, eTarget, texture); }
//! Sets the bound texture and texture target for texture unit @a iTextureUnit.
SKYRESULT SetTexture(unsigned int iTextureUnit, GLenum eTarget, unsigned int iTextureID)
{ return _textureState.SetTexture(iTextureUnit, eTarget, iTextureID); }
//! Enables / Disables texture unit @a iTextureUnit for this material.
SKYRESULT EnableTexture(unsigned int iTextureUnit, bool bEnable)
{ return _textureState.EnableTexture(iTextureUnit, bEnable); }
//! Sets the value of the texture parameter @a eParameter for texture unit @a iTextureUnit.
SKYRESULT SetTextureParameter(unsigned int iTextureUnit, GLenum eParameter, GLenum eMode)
{ return _textureState.SetTextureParameter(iTextureUnit, eParameter, eMode); }
//! Sets the texture application mode of the texture environment.
void SetTextureApplicationMode(GLenum eMode){ _eTextureEnvMode = eMode;}
// depth test
//! Enables / Disables depth test for this material.
void EnableDepthTest(bool bEnable) { _bDepthTest = bEnable; }
//! Sets the depth test function (greater, less than, equal, etc.).
void SetDepthFunc(GLenum eDepthFunc) { _eDepthFunc = eDepthFunc;}
//! If @a bDepthMask is true, then depth writes are enabled, otherwise they are not.
void SetDepthMask(bool bDepthMask) { _bDepthMask = bDepthMask;}
// alpha test
//! Enables / Disables alpha test for this material.
void EnableAlphaTest(bool bEnable) { _bAlphaTest = bEnable; }
//! Sets the alpha test function (greater, less than, equal, etc.).
void SetAlphaFunc(GLenum eAlphaFunc) { _eAlphaFunc = eAlphaFunc;}
//! Sets the reference value against which fragment alpha values are compared.
void SetAlphaRef(float rAlphaRef) { _rAlphaRef = rAlphaRef; }
// blending
//! Enables / Disables blending for this material.
void EnableBlending(bool bEnable) { _bBlending = bEnable; }
//! Sets the source and destination blending factors for this material.
void SetBlendFunc(GLenum eSrcFactor, GLenum eDstFactor)
{ _eBlendSrcFactor = eSrcFactor; _eBlendDstFactor = eDstFactor; }
//! Enables / Disables face culling for this material.
void EnableFaceCulling(bool bEnable) { _bFaceCulling = bEnable; }
//! Sets which faces will be culled -- front facing or back facing.
void SetFaceCullingMode(GLenum eMode) { _eFaceCullingMode = eMode; }
protected:
int _iMaterialID;
Vec4f _vecDiffuse;
Vec4f _vecSpecular;
Vec4f _vecAmbient;
Vec4f _vecEmissive;
float _rSpecularPower;
bool _bLighting;
GLenum _eColorMaterialFace;
GLenum _eColorMaterialMode;
bool _bColorMaterial;
enum SkyFogParams
{
SKY_FOG_DENSITY,
SKY_FOG_START,
SKY_FOG_END,
SKY_FOG_NUM_PARAMS
};
Vec4f _vecFogColor;
GLenum _eFogMode;
float _rFogParams[SKY_FOG_NUM_PARAMS];
bool _bFog;
GLenum _eDepthFunc;
bool _bDepthMask;
bool _bDepthTest;
GLenum _eAlphaFunc;
float _rAlphaRef;
bool _bAlphaTest;
GLenum _eBlendSrcFactor;
GLenum _eBlendDstFactor;
bool _bBlending;
bool _bFaceCulling;
GLenum _eFaceCullingMode;
SkyTextureState _textureState;
GLenum _eTextureEnvMode;
};
#endif //__SKYMATERIAL_HPP__

View File

@@ -1,334 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyMinMaxBox.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyMinMaxBox.cpp
*
* Implementation of a bounding box class. Modified from Wes Hunt's BoundingBox.
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include SG_GL_H
#include "SkyMinMaxBox.hpp"
#include "camutils.hpp"
#include <float.h>
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::SkyMinMaxBox
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::SkyMinMaxBox()
* @brief Constructor
*/
SkyMinMaxBox::SkyMinMaxBox()
{
Clear();
}
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::Clear
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::Clear()
* @brief Reset the min and max to floating point extremes.
*
*/
void SkyMinMaxBox::Clear()
{
_min.x = FLT_MAX;
_min.y = FLT_MAX;
_min.z = FLT_MAX;
_max.x = -FLT_MAX;
_max.y = -FLT_MAX;
_max.z = -FLT_MAX;
}
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::PointInBBox
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
* @brief Queries pt to see if it is inside the SkyMinMaxBox.
*
*/
bool SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
{
if( (pt.x >= _min.x) && ( pt.x <= _max.x ) )
{
if( (pt.y >= _min.y) && ( pt.y <= _max.y ) )
{
if( (pt.z >= _min.z) && ( pt.z <= _max.z ) )
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::AddPoint
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::AddPoint( float x , float y , float z )
* @brief Adds a point and adjusts bounds if necessary.
*/
void SkyMinMaxBox::AddPoint( float x , float y , float z )
{
if( x > _max.x )
_max.x = x;
if( x < _min.x )
_min.x = x;
if( y > _max.y )
_max.y = y;
if( y < _min.y )
_min.y = y;
if( z > _max.z )
_max.z = z;
if( z < _min.z )
_min.z = z;
// update the center and radius
_UpdateSphere();
}
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::AddPoint
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::AddPoint( const Vec3f &pt )
* @brief Adds a point and adjusts bounds if necessary.
*/
void SkyMinMaxBox::AddPoint( const Vec3f &pt )
{
if( pt.x > _max.x )
_max.x = pt.x;
if( pt.x < _min.x )
_min.x = pt.x;
if( pt.y > _max.y )
_max.y = pt.y;
if( pt.y < _min.y )
_min.y = pt.y;
if( pt.z > _max.z )
_max.z = pt.z;
if( pt.z < _min.z )
_min.z = pt.z;
// update the center and radius
_UpdateSphere();
}
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::ViewFrustumCull
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
* @brief Returns true if bounding volume culled against cam.
*
* This function must transform the object space min and max then adjust the new
* min and max box by expanding it. Each of the 8 points must be tested. This
* is faster then doing an xform of all the geometry points and finding a tight
* fitting min max box, however this will be enlarged.
*/
bool SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
{
SkyMinMaxBox xBV; // Xformed Bounding Volume
Vec3f xMin = mat * _min; // Xformed _min
Vec3f xMax = mat * _max; // Xformed _max
Vec3f offset = _max - _min; // Offset for sides of MinMaxBox
Vec3f tmp;
xBV.Clear(); // Clear the values first
// First find the new minimum x,y,z
// Find min + x
tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
tmp *= offset.x;
tmp += xMin;
xBV.AddPoint(tmp);
// Find min + y
tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
tmp *= offset.y;
tmp += xMin;
xBV.AddPoint(tmp);
// Find min + z
tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
tmp *= offset.z;
tmp += xMin;
xBV.AddPoint(tmp);
// Second find the new maximum x,y,z
// Find max - x
tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
tmp *= -offset.x;
tmp += xMax;
xBV.AddPoint(tmp);
// Find max - y
tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
tmp *= -offset.y;
tmp += xMax;
xBV.AddPoint(tmp);
// Find max - z
tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
tmp *= -offset.z;
tmp += xMax;
xBV.AddPoint(tmp);
// Use the camera utility function that already exists for minmax boxes
return VFC(&cam, xBV.GetMin(), xBV.GetMax());
}
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::Transform
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::Transform(const Mat44f& mat)
* @brief @todo <WRITE BRIEF SkyMinMaxBox::Transform DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyMinMaxBox::Transform FUNCTION DOCUMENTATION>
*/
void SkyMinMaxBox::Transform(const Mat44f& mat)
{
Vec3f verts[8];
_CalcVerts(verts);
Clear();
for (int i = 0; i < 8; ++i)
{
AddPoint(mat * verts[i]);
}
}
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::_UpdateSphere
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::_UpdateSphere()
* @brief Updates the bounding sphere based on min and max.
*/
void SkyMinMaxBox::_UpdateSphere()
{
_vecCenter = _min;
_vecCenter += _max;
_vecCenter *= 0.5f;
Vec3f rad = _max;
rad -= _vecCenter;
_rRadius = rad.Length();
}
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::Display
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::Display() const
* @brief @todo <WRITE BRIEF SkyMinMaxBox::Display DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyMinMaxBox::Display FUNCTION DOCUMENTATION>
*/
void SkyMinMaxBox::Display() const
{
Vec3f V[8];
_CalcVerts(V);
glPushAttrib(GL_LINE_BIT);
glLineWidth(1.0);
glBegin(GL_LINE_LOOP); // TOP FACE
glVertex3fv(V[4]); glVertex3fv(V[5]); glVertex3fv(V[1]); glVertex3fv(V[0]);
glEnd();
glBegin(GL_LINE_LOOP); // BOTTOM FACE
glVertex3fv(V[3]); glVertex3fv(V[2]); glVertex3fv(V[6]); glVertex3fv(V[7]);
glEnd();
glBegin(GL_LINE_LOOP); // LEFT FACE
glVertex3fv(V[1]); glVertex3fv(V[5]); glVertex3fv(V[6]); glVertex3fv(V[2]);
glEnd();
glBegin(GL_LINE_LOOP); // RIGHT FACE
glVertex3fv(V[0]); glVertex3fv(V[3]); glVertex3fv(V[7]); glVertex3fv(V[4]);
glEnd();
glBegin(GL_LINE_LOOP); // NEAR FACE
glVertex3fv(V[1]); glVertex3fv(V[2]); glVertex3fv(V[3]); glVertex3fv(V[0]);
glEnd();
glBegin(GL_LINE_LOOP); // FAR FACE
glVertex3fv(V[4]); glVertex3fv(V[7]); glVertex3fv(V[6]); glVertex3fv(V[5]);
glEnd();
glPopAttrib();
}
//-----------------------------------------------------------------------------
// Calculates the eight corner vertices of the MinMaxBox.
// V must be prealloced.
// 5---4
// / /|
// 1---0 | VERTS : 0=RTN,1=LTN,2=LBN,3=RBN,4=RTF,5=LTF,6=LBF,7=RBF
// | | 7 (L,R, B,T, N,F) = (Left,Right, Bottom,Top, Near,Far)
// | |/
// 2---3
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Function : SkyMinMaxBox::_CalcVerts
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
* @brief @todo <WRITE BRIEF SkyMinMaxBox::_CalcVerts DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyMinMaxBox::_CalcVerts FUNCTION DOCUMENTATION>
*/
void SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
{
pVerts[0].Set(_max); pVerts[4].Set(_max.x, _max.y, _min.z);
pVerts[1].Set(_min.x, _max.y, _max.z); pVerts[5].Set(_min.x, _max.y, _min.z);
pVerts[2].Set(_min.x, _min.y, _max.z); pVerts[6].Set(_min);
pVerts[3].Set(_max.x, _min.y, _max.z); pVerts[7].Set(_max.x, _min.y, _min.z);
}

View File

@@ -1,85 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyMinMaxBox.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyMinMaxBox.hpp
*
* Interface definition for a min-max bounding box class for bounding volume hierarchies.
*/
#ifndef __SKYMINMAXBOX_HPP__
#define __SKYMINMAXBOX_HPP__
#include "SkyBoundingVolume.hpp"
//------------------------------------------------------------------------------
/**
* @class SkyMinMaxBox
* @brief An AABB class that can be used in bounding volume hierarchies.
*
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
*/
class SkyMinMaxBox : public SkyBoundingVolume
{
public:
SkyMinMaxBox();
//! Destructor
virtual ~SkyMinMaxBox() {}
void AddPoint( const Vec3f &pt );
void AddPoint( float x , float y , float z );
//! Expand this box to contain @a box.
void Union(const SkyMinMaxBox& box) { AddPoint(box.GetMin()); AddPoint(box.GetMax()); }
//! Returns the minimum corner of the bounding box.
const Vec3f &GetMin() const { return _min; }
//! Returns the maximum corner of the bounding box.
const Vec3f &GetMax() const { return _max; }
//! Sets the minimum corner of the bounding box.
void SetMin(const Vec3f &min) { _min = min; _UpdateSphere(); }
//! Sets the maximum corner of the bounding box.
void SetMax(const Vec3f &max) { _max = max; _UpdateSphere(); }
//! Returns the X width of the bounding box.
float GetWidthInX() const { return _max.x - _min.x;}
//! Returns the Y width of the bounding box.
float GetWidthInY() const { return _max.y - _min.y;}
//! Returns the Z width of the bounding box.
float GetWidthInZ() const { return _max.z - _min.z;}
bool PointInBBox( const Vec3f &pt ) const;
bool ViewFrustumCull( const Camera &cam, const Mat44f &mat );
void Transform(const Mat44f& mat);
// Reset the bounding box
void Clear();
void Display() const;
protected:
void _UpdateSphere();
void _CalcVerts(Vec3f pVerts[8]) const;
private:
Vec3f _min; // Original object space BV
Vec3f _max;
};
#endif //__SKYMINMAXBOX_HPP__

View File

@@ -1,116 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyRenderable.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
//------------------------------------------------------------------------------
// File : SkyRenderable.hpp
//------------------------------------------------------------------------------
// Sky : Copyright 2002 Mark J. Harris and Andrew Zaferakis
//------------------------------------------------------------------------------
/**
* @file SkyRenderable.hpp
*
* Abstract base class definition for SkyRenderable, a renderable object class.
*/
#ifndef __SKYRENDERABLE_HPP__
#define __SKYRENDERABLE_HPP__
#pragma warning( disable : 4786)
#include <string>
#include "SkyUtil.hpp"
// forward to reduce unnecessary dependencies
class SkyMinMaxBox;
class SkyRenderableInstance;
class Camera;
//------------------------------------------------------------------------------
/**
* @class SkyRenderable
* @brief An base class for renderable objects.
*
* Each SkyRenderable object should know how to Display itself, however some
* objects may not have a bounding volume that is useful (skybox, etc.)
*/
class SkyRenderable
{
public:
//! Constructor
SkyRenderable() {}
//! Destructor
virtual ~SkyRenderable() { }
//------------------------------------------------------------------------------
// Function : SetName
// Description :
//------------------------------------------------------------------------------
/**
* @fn SetName(const std::string &name)
* @brief Set a name for this renderable.
*/
void SetName(const std::string &name) { _name = name; }
//------------------------------------------------------------------------------
// Function : GetName
// Description :
//------------------------------------------------------------------------------
/**
* @fn GetName() const
* @brief Get the name of this renderable.
*/
const std::string& GetName() const { return _name; }
//------------------------------------------------------------------------------
// Function : Update
// Description :
//------------------------------------------------------------------------------
/**
* @fn Update(const Camera &cam, SkyRenderableInstance *pInstance)
* @brief Update the state of the renderable.
*
* This method is optional, as some renderables will need periodic updates
* (i.e. for animation) and others will not.
*/
virtual SKYRESULT Update(const Camera &cam, SkyRenderableInstance *pInstance = NULL)
{ return SKYRESULT_OK; }
//------------------------------------------------------------------------------
// Function : Display
// Description :
//------------------------------------------------------------------------------
/**
* @fn Display(const Camera &cam, SkyRenderableInstance *pInstance)
* @brief Display the object.
*/
virtual SKYRESULT Display(const Camera &cam, SkyRenderableInstance *pInstance = NULL) = 0;
//------------------------------------------------------------------------------
// Function : CopyBoundingVolume
// Description :
//------------------------------------------------------------------------------
/**
* @fn CopyBoundingVolume() const
* @brief Create a copy of the object's bounding volume, useful for collision, VFC, etc.
*/
virtual SkyMinMaxBox* CopyBoundingVolume() const = 0;// { return 0; }
protected:
std::string _name; // the name of this renderable.
};
#endif //__SKYRENDERABLE_HPP__

View File

@@ -1,202 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyRenderableInstance.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyRenderableInstance.hpp
*
* Interface definition for SkyRenderableInstance, an instance of a renderable object.
*/
#ifndef __SKYRENDERABLEINSTANCE_HPP__
#define __SKYRENDERABLEINSTANCE_HPP__
#include <vector>
#include "mat33.hpp"
#include "mat44.hpp"
#include "SkyUtil.hpp"
// forward to reduce unnecessary dependencies
class Camera;
class SkyMinMaxBox;
// forward so we can make the following typedefs easily visible in the header.
// rather than buried under the class definition.
class SkyRenderableInstance;
//! A dynamic array of SkyRenderableInstance pointers.
typedef std::vector<SkyRenderableInstance*> InstanceArray;
//! An instance array iterator.
typedef InstanceArray::iterator InstanceIterator;
//------------------------------------------------------------------------------
/**
* @class SkyRenderableInstance
* @brief An instance of a SkyRenderable object.
*
* An instance contains a pointer to a SkyRenderable object. The
* instance contains attributes such as position, orientation,
* scale, etc. that vary between instances.
*/
class SkyRenderableInstance
{
public:
//! Constructor.
SkyRenderableInstance()
: _bCulled(false), _bAlive(true), _vecPosition(0, 0, 0), _rScale(1), _rSquareSortDistance(0)
{
_matRotation.Identity(); _matInvRotation.Identity();
}
//! Constructor.
SkyRenderableInstance(const Vec3f &position,
const Mat33f &rotation,
const float scale)
: _bCulled(false), _bAlive(true), _vecPosition(position),
_matRotation(rotation), _rScale(scale), _rSquareSortDistance(0)
{
_matInvRotation = _matRotation;
_matInvRotation.Transpose();
}
//! Destructor
virtual ~SkyRenderableInstance() {}
// Setters / Getters
//! Set the world space position of the instance.
virtual void SetPosition(const Vec3f &position) { _vecPosition = position; }
//! Set the world space rotation of the instance.
virtual void SetRotation(const Mat33f &rotation) { _matRotation = rotation;
_matInvRotation = rotation;
_matInvRotation.Transpose(); }
//! Set the world space scale of the instance.
virtual void SetScale( const float &scale) { _rScale = scale; }
//! Returns the world space position of the instance.
virtual const Vec3f& GetPosition() const { return _vecPosition; }
//! Returns the world space rotation matrix of the instance.
virtual const Mat33f& GetRotation() const { return _matRotation; }
//! Returns the inverse of the world space rotation matrix of the instance.
virtual const Mat33f& GetInverseRotation() const { return _matInvRotation; }
//! Returns the world space scale of the instance.
virtual float GetScale() const { return _rScale; }
//! Update the instance based on the given camera, @a cam.
virtual SKYRESULT Update(const Camera &cam) { return SKYRESULT_OK; }
//! Render the instance.
virtual SKYRESULT Display() { return SKYRESULT_OK; }
//! Returns the transform matrix from model space to world space.
inline virtual void GetModelToWorldTransform(Mat44f &mat) const;
//! Returns the transform matrix from world space to model space.
inline virtual void GetWorldToModelTransform(Mat44f &mat) const;
//! Returns the object-space bounding volume for this instance, or NULL if none is available.
virtual SkyMinMaxBox* GetBoundingVolume() const { return NULL; }
//! Returns true if and only if the bounding volume of this instance lies entirely outside @a cam.
virtual bool ViewFrustumCull(const Camera &cam) { return false; }
//! Returns true if the instance was culled.
virtual bool IsCulled() { return _bCulled; }
//! Sets the culled state of the instance.
virtual void SetCulled(bool bCulled) { _bCulled = bCulled; }
//! Returns true if the instance is currently active.
virtual bool IsAlive() { return _bAlive; }
//! Activates or deactivates the instance.
virtual void SetIsAlive(bool bAlive) { _bAlive = bAlive; }
//! Sets the distance of this object from the sort position. Used to sort instances.
virtual void SetSquareSortDistance(float rSqrDist) { _rSquareSortDistance = rSqrDist; }
//! Returns the distance of this object from the sort position. (Set with SetSquareSortDistance())
virtual float GetSquareSortDistace() const { return _rSquareSortDistance; }
//! This operator is used to sort instance arrays.
bool operator<(const SkyRenderableInstance& instance) const
{
return (_rSquareSortDistance > instance._rSquareSortDistance);
}
protected:
bool _bCulled; // Culled flag
bool _bAlive; // Alive object flag
Vec3f _vecPosition; // Position
Mat33f _matRotation; // Rotation
Mat33f _matInvRotation; // inverse rotation
float _rScale; // Scale
// for sorting particles during shading
float _rSquareSortDistance;
};
//------------------------------------------------------------------------------
// Function : SkyRenderableInstance::GetModelToWorldTransform
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstance::GetModelToWorldTransform(Mat44f &mat) const
* @brief Returns the 4x4 transformation matrix from world to model space.
*/
inline void SkyRenderableInstance::GetModelToWorldTransform(Mat44f &mat) const
{
mat[0] = _matRotation.M[0]; mat[4] = _matRotation.M[3];
mat[8] = _matRotation.M[6]; mat[12] = 0;
mat[1] = _matRotation.M[1]; mat[5] = _matRotation.M[4];
mat[9] = _matRotation.M[7]; mat[13] = 0;
mat[2] = _matRotation.M[2]; mat[6] = _matRotation.M[5];
mat[10] = _matRotation.M[8]; mat[14] = 0;
mat[3] = 0; mat[7] = 0; mat[11] = 0; mat[15] = 0;
// Scale the matrix (we don't want to scale translation or mat[15] which is 1)
if (_rScale != 1)
mat *= _rScale;
// Set the translation and w coordinate after the potential scaling
mat[12] = _vecPosition.x; mat[13] = _vecPosition.y; mat[14] = _vecPosition.z;
mat[15] = 1;
}
//------------------------------------------------------------------------------
// Function : Mat44f& SkyRenderableInstance::GetWorldToModelTransform
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstance::GetWorldToModelTransform(Mat44f &mat) const
* @brief Returns the 4x4 transformation matrix from world to model space.
*/
inline void SkyRenderableInstance::GetWorldToModelTransform(Mat44f &mat) const
{
mat[0] = _matRotation.M[0]; mat[4] = _matRotation.M[1];
mat[8] = _matRotation.M[2]; mat[12] = 0;
mat[1] = _matRotation.M[3]; mat[5] = _matRotation.M[4];
mat[9] = _matRotation.M[5]; mat[13] = 0;
mat[2] = _matRotation.M[6]; mat[6] = _matRotation.M[7];
mat[10] = _matRotation.M[8]; mat[14] = 0;
mat[3] = 0; mat[7] = 0; mat[11] = 0; mat[15] = 0;
// Scale the matrix (we don't want to scale translation or mat[15] which is 1)
if (_rScale != 1)
mat *= (1 / _rScale);
// Set the translation and w coordinate after the potential scaling
mat[12] = -_vecPosition.x; mat[13] = -_vecPosition.y; mat[14] = -_vecPosition.z;
mat[15] = 1;
}
#endif //__SKYRENDERABLEINSTANCE_HPP__

View File

@@ -1,721 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyRenderableInstanceCloud.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyRenderableInstanceCloud.cpp
*
* Implementation of class SkyRenderableInstanceCloud.
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include SG_GLU_H
#include "SkyUtil.hpp"
#include "SkyCloud.hpp"
#include "SkyMaterial.hpp"
#include "SkyBoundingVolume.hpp"
#include "SkyRenderableInstanceCloud.hpp"
#include "SkyDynamicTextureManager.hpp"
//! Set this to 1 to see verbose messages about impostor updates.
#define SKYCLOUD_VERBOSE 0
//! Set this to control the number of frames a cloud has to be culled before its textures are released.
#define SKYCLOUD_CULL_RELEASE_COUNT 100
//------------------------------------------------------------------------------
// Static declarations.
//------------------------------------------------------------------------------
unsigned int SkyRenderableInstanceCloud::s_iCount = 0;
float SkyRenderableInstanceCloud::s_rErrorToleranceAngle = SKYDEGREESTORADS * 0.125f;
SkyMaterial* SkyRenderableInstanceCloud::s_pMaterial = NULL;
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::SkyRenderableInstanceCloud
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::SkyRenderableInstanceCloud(SkyCloud *pCloud, bool bUseOffScreenBuffer)
* @brief Constructor.
*/
SkyRenderableInstanceCloud::SkyRenderableInstanceCloud(SkyCloud *pCloud,
bool bUseOffScreenBuffer /* = true */)
: SkyRenderableInstance(),
_iCloudID(-1),
_pCloud(pCloud),
_pWorldSpaceBV(NULL),
_rRadius(0),
_bScreenImpostor(false),
_bImageExists(false),
_bEnabled(true),
_bUseOffScreenBuffer(bUseOffScreenBuffer),
_bSplit(false),
_vecSplit(0, 0, 0),
_vecNearPoint(0, 0, 0),
_vecFarPoint(0, 0, 0),
_iLogResolution(0),
_pBackTexture(NULL),
_pFrontTexture(NULL),
_iCulledCount(0)
{
_Initialize();
// cout << "Cloud Instance created" << endl;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::SkyRenderableInstanceCloud
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::SkyRenderableInstanceCloud(SkyCloud *pCloud, const Vec3f &position, const Mat33f &rotation, const float scale, bool bUseOffScreenBuffer)
* @brief Constructor.
*/
SkyRenderableInstanceCloud::SkyRenderableInstanceCloud(SkyCloud *pCloud,
const Vec3f &position,
const Mat33f &rotation,
const float scale,
bool bUseOffScreenBuffer /* = true */)
: SkyRenderableInstance(position, rotation, scale),
_iCloudID(-1),
_pCloud(pCloud),
_pWorldSpaceBV(NULL),
_rRadius(0),
_bScreenImpostor(false),
_bImageExists(false),
_bEnabled(true),
_bUseOffScreenBuffer(false),
_bSplit(false),
_vecSplit(0, 0, 0),
_vecNearPoint(0, 0, 0),
_vecFarPoint(0, 0, 0),
_iLogResolution(0),
_pBackTexture(NULL),
_pFrontTexture(NULL)
{
_Initialize();
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::~SkyRenderableInstanceCloud
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::~SkyRenderableInstanceCloud()
* @brief Destructor
*/
SkyRenderableInstanceCloud::~SkyRenderableInstanceCloud()
{
_pCloud = NULL;
SAFE_DELETE(_pWorldSpaceBV);
s_iCount--;
// delete the offscreen buffer when no one else is using it.
if (0 == s_iCount)
{
//JW?? SAFE_DELETE(s_pRenderBuffer);
SAFE_DELETE(s_pMaterial);
}
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::SetPosition
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::SetPosition(const Vec3f &position)
* @brief Set the world space position of the instance.
*
* @todo <WRITE EXTENDED SkyRenderableInstanceCloud::SetPosition FUNCTION DOCUMENTATION>
*/
void SkyRenderableInstanceCloud::SetPosition(const Vec3f &position)
{
if (_pCloud)
{
_pCloud->Translate(position - _vecPosition);
}
_vecPosition = position;
_UpdateWorldSpaceBounds();
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::SetRotation
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::SetRotation(const Mat33f &rotation)
* @brief Set the world space rotation of the instance.
*
* @todo <WRITE EXTENDED SkyRenderableInstanceCloud::SetRotation FUNCTION DOCUMENTATION>
*/
void SkyRenderableInstanceCloud::SetRotation(const Mat33f &rotation)
{
if (_pCloud)
{
_pCloud->Translate(-_vecPosition);
_pCloud->Rotate(_matInvRotation * rotation);
_pCloud->Translate(_vecPosition);
}
_matRotation = rotation;
_matInvRotation = rotation;
_matInvRotation.Transpose();
_UpdateWorldSpaceBounds();
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::SetScale
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::SetScale(const float &scale)
* @brief Set the world space scale of the instance.
*/
void SkyRenderableInstanceCloud::SetScale(const float &scale)
{
if (_pCloud)
{
_pCloud->Translate(-_vecPosition);
_pCloud->Scale(scale);
_pCloud->Translate(_vecPosition);
}
_rScale = scale;
_UpdateWorldSpaceBounds();
}
//------------------------------------------------------------------------------
// Function : DrawQuad
// Description :
//------------------------------------------------------------------------------
/**
* DrawQuad(Vec3f pos, Vec3f x, Vec3f y, Vec4f color)
* @brief Simply draws an OpenGL quad at @a pos.
*
* The quad's size and orientation are determined by the (non-unit) vectors @a x
* and @a y. Its color is given by @a color.
*/
inline void DrawQuad(Vec3f pos, Vec3f x, Vec3f y, Vec4f color)
{
glColor4fv(&(color.x));
Vec3f left = pos; left -= y;
Vec3f right = left; right += x;
left -= x;
glTexCoord2f(0, 0); glVertex3fv(&(left.x));
glTexCoord2f(1, 0); glVertex3fv(&(right.x));
left += y; left += y;
right += y; right += y;
glTexCoord2f(1, 1); glVertex3fv(&(right.x));
glTexCoord2f(0, 1); glVertex3fv(&(left.x));
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::Display
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::Display(bool bDisplayFrontOfSplit)
* @brief Display the instance of the cloud using the impostor image.
*/
SKYRESULT SkyRenderableInstanceCloud::Display(bool bDisplayFrontOfSplit /* = false */)
{
if (!_bImageExists || !_bEnabled)
{
//FAIL_RETURN(DisplayWithoutImpostor(*(GLVU::GetCurrent()->GetCurrentCam())));
FAIL_RETURN(DisplayWithoutImpostor(Camera()));
}
else
{//cout << "Using impostor image\n";
if (!_pBackTexture || (bDisplayFrontOfSplit && !_pFrontTexture)) {
// cout << "texture id failure" << endl;
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyRenderableInstanceCloud::Display(): missing texture!");
}
s_pMaterial->SetTexture(0, GL_TEXTURE_2D, bDisplayFrontOfSplit ? *_pFrontTexture : *_pBackTexture);
if (_bScreenImpostor)
{
s_pMaterial->EnableDepthTest(false);
}
else if (_bSplit)
{
if (!bDisplayFrontOfSplit)
{
s_pMaterial->EnableDepthTest(true);
s_pMaterial->SetDepthMask(false);
}
else
s_pMaterial->EnableDepthTest(false);
}
else
{
s_pMaterial->EnableDepthTest(true);
s_pMaterial->SetDepthMask(true);
}
s_pMaterial->Activate();
// s_pMaterial->Force();
Vec3f x, y, z;
if (!_bScreenImpostor)
{//cout << "Outside the cloud\n";
z = _vecPosition;
z -= _impostorCam.Orig;
z.Normalize();
x = (z ^ _impostorCam.Y);
x.Normalize();
x *= _rRadius;
y = (x ^ z);
y.Normalize();
y *= _rRadius;
glBegin(GL_QUADS);
DrawQuad(_vecPosition, x, y, Vec4f(1, 1, 1, 1));
glEnd();
}
else
{ //cout << "Drawing a polygon - must be inside a cloud\n";
x = _impostorCam.X;
x *= 0.5f * (_impostorCam.wR - _impostorCam.wL);
y = _impostorCam.Y;
y *= 0.5f * (_impostorCam.wT - _impostorCam.wB);
z = -_impostorCam.Z;
z *= _impostorCam.Near;
// draw a polygon with this texture...
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(-1, 1, -1, 1);
glColor4f(1, 1, 1, 1);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(-1, -1);
glTexCoord2f(1, 0); glVertex2f(1, -1);
glTexCoord2f(1, 1); glVertex2f(1, 1);
glTexCoord2f(0, 1); glVertex2f(-1, 1);
glEnd();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::DisplayWithoutImpostor
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::DisplayWithoutImpostor(const Camera &cam)
* @brief Displays the cloud directly -- without an impotor.
*
* This is used both when the impostor is disabled and to create the impostor image
* when it needs to be updated.
*/
SKYRESULT SkyRenderableInstanceCloud::DisplayWithoutImpostor(const Camera &cam)
{
// Get and set the world space transformation
/*Mat44f mat;
GetModelToWorldTransform(mat);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(mat.M);*/
FAIL_RETURN_MSG(_pCloud->Display(cam, this), "SkyRenderableInstanceCloud:Display(): Cloud's display failed.");
//glMatrixMode(GL_MODELVIEW);
//glPopMatrix();
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::ViewFrustumCull
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::ViewFrustumCull(const Camera &cam)
* @brief View frustum cull the object given its world position
*/
bool SkyRenderableInstanceCloud::ViewFrustumCull(const Camera &cam)
{
Mat44f xform;
//GetModelToWorldTransform(xform);
xform.Identity();
_bCulled = (_pWorldSpaceBV == NULL) ? false : _pWorldSpaceBV->ViewFrustumCull(cam, xform);
return _bCulled;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::ReleaseImpostorTextures
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::ReleaseImpostorTextures()
* @brief Causes the instance to release its impostor textures for use by other impostors.
*
* This method is called when the cloud is view frustum culled.
*/
void SkyRenderableInstanceCloud::ReleaseImpostorTextures()
{
_iCulledCount++;
if (_iCulledCount > SKYCLOUD_CULL_RELEASE_COUNT)
{
_iCulledCount = 0;
if (_pBackTexture)
{
DynamicTextureManager::InstancePtr()->CheckInTexture(_pBackTexture);
_pBackTexture = NULL;
}
if (_pFrontTexture)
{
DynamicTextureManager::InstancePtr()->CheckInTexture(_pFrontTexture);
_pFrontTexture = NULL;
}
_bImageExists = false;
}
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::Update
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::Update(const Camera &cam)
* @brief Updates the impostor image to be valid for the current viewpoint.
*
* If the image is already valid, exits early.
*
* @see SetErrorToleranceAngle, IsValid
*/
SKYRESULT SkyRenderableInstanceCloud::Update(const Camera &cam)
{
if (!_bEnabled || IsImpostorValid(cam))
return SKYRESULT_OK;
// since we are going to update it anyway, let's make sure we don't try to use it if something
// goes wrong. This will be set to true on the successful completion of this Update() method.
_bImageExists = false;
//cout << "updating impostor\n";
Mat44f M;
_impostorCam = cam;
float rDistance = (_vecPosition - cam.Orig).Length();
float rRadius = _pWorldSpaceBV->GetRadius();
float rCamRadius = sqrt(cam.wR*cam.wR + cam.Near*cam.Near);
float rWidth = cam.wR - cam.wL;
float rHeight = cam.wT - cam.wB;
float rMaxdim = (rWidth > rHeight) ? rWidth : rHeight;
if (rRadius * cam.Near / rDistance < 0.5 * rMaxdim && (rDistance - rRadius > rCamRadius))
{ // outside cloud
_impostorCam.TightlyFitToSphere(cam.Orig, cam.Y, _vecPosition, rRadius);
_rRadius = 0.5f * (_impostorCam.wR - _impostorCam.wL) * rDistance / _impostorCam.Near;
_rRadius *= GetScale();
_bScreenImpostor = false;
// store points used in later error estimation
_vecNearPoint = -_impostorCam.Z;
_vecNearPoint *= _impostorCam.Near;
_vecNearPoint += _impostorCam.Orig;
_vecFarPoint = -_impostorCam.Z;
_vecFarPoint *= _impostorCam.Far;
_vecFarPoint += _impostorCam.Orig;
}
else // inside cloud
{
_impostorCam.Far = _impostorCam.Near + 3 * rRadius;
_bScreenImpostor = true;
}
// resolution based on screensize, distance, and object size.
// Cam radius is used to heuristically reduce resolution for clouds very close to the camera.
_iLogResolution = _GetRequiredLogResolution(rDistance, rRadius, rCamRadius);
int iRes = 1 << _iLogResolution;
int iOldVP[4];
glGetIntegerv(GL_VIEWPORT, iOldVP);
_impostorCam.GetProjectionMatrix(M);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrixf(M);
_impostorCam.GetModelviewMatrix(M);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf(M);
glViewport(0, 0, iRes, iRes);
s_pMaterial->SetDepthMask(true); // so that the depth buffer gets cleared!
s_pMaterial->Activate();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (!_bSplit)
{
FAIL_RETURN(DisplayWithoutImpostor(_impostorCam));
if (_pBackTexture && _pBackTexture->GetWidth() != iRes)
{
DynamicTextureManager::InstancePtr()->CheckInTexture(_pBackTexture);
_pBackTexture = NULL;
}
if (!_pBackTexture)
{
_pBackTexture = DynamicTextureManager::InstancePtr()->CheckOutTexture(iRes, iRes);
}
s_pMaterial->SetTexture(0, GL_TEXTURE_2D, *_pBackTexture); // shared material for clouds.
s_pMaterial->Activate();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, iRes, iRes);
}
else
{
FAIL_RETURN_MSG(_pCloud->DisplaySplit(cam, _vecSplit, true, this),
"SkyRenderableInstanceCloud:Display(): Cloud's display failed.");
if (_pBackTexture && _pBackTexture->GetWidth() != iRes)
{
DynamicTextureManager::InstancePtr()->CheckInTexture(_pBackTexture);
_pBackTexture = NULL;
}
if (_pFrontTexture && _pFrontTexture->GetWidth() != iRes)
{
DynamicTextureManager::InstancePtr()->CheckInTexture(_pFrontTexture);
_pFrontTexture = NULL;
}
if (!_pBackTexture)
{
_pBackTexture = DynamicTextureManager::InstancePtr()->CheckOutTexture(iRes, iRes);
}
s_pMaterial->SetTexture(0, GL_TEXTURE_2D, *_pBackTexture); // shared material for clouds.
FAIL_RETURN(s_pMaterial->Activate());
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, iRes, iRes);
// now clear and draw the front.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
FAIL_RETURN_MSG(_pCloud->DisplaySplit(cam, _vecSplit, false, this),
"SkyRenderableInstanceCloud:Display(): Cloud's display failed.");
if (!_pFrontTexture)
{
_pFrontTexture = DynamicTextureManager::InstancePtr()->CheckOutTexture(iRes, iRes);
}
s_pMaterial->GetTextureState().SetTexture(0, GL_TEXTURE_2D, *_pFrontTexture);
FAIL_RETURN(s_pMaterial->GetTextureState().Activate());
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, iRes, iRes);
}
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//GLVU::CheckForGLError("Cloud Impostor Update");
glViewport(iOldVP[0], iOldVP[1], iOldVP[2], iOldVP[3]);
_bImageExists = true;
// the textures should now exist.
assert(_pBackTexture);
assert(!_bSplit || (_bSplit && _pFrontTexture));
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::IsImpostorValid
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::IsImpostorValid(const Camera& cam)
* @brief Returns true if the impostor image is valid for the given camera.
*
* Will return false if this is a screen impostor, or if there is error in either
* the translation of the camera from the capture point or the impostor image resolution.
*
* @see SetErrorToleranceAngle
*/
bool SkyRenderableInstanceCloud::IsImpostorValid(const Camera& cam)
{
// first make sure there is a current image.
if (!_bImageExists)
return false;
// screen impostors should always be updated
if (_bScreenImpostor)
{
_vecFarPoint = Vec3f::ZERO;
_vecNearPoint = Vec3f::ZERO;
#if SKYCLOUD_VERBOSE
SkyTrace("Screen Impostor Update");
#endif
return false;
}
// impostors are valid from the viewpoint from which they were captured
if (cam.Orig == _impostorCam.Orig)
return true;
if (_bSplit)
{
#if SKYCLOUD_VERBOSE
SkyTrace("Split Impostor Update");
#endif
return false;
}
Vec3f vecX = _vecNearPoint - cam.Orig;
Vec3f vecY = _vecFarPoint - cam.Orig;
float rXLength = vecX.Length();
float rYLength = vecY.Length();
if (rXLength > rYLength)
{
#if SKYCLOUD_VERBOSE
SkyTrace("Backwards Impostor Update");
#endif
return false;
}
vecX /= rXLength;
vecY /= rYLength;
float rCosAlpha = vecX * vecY; // dot product of normalized vectors = cosine
if (fabs(rCosAlpha) < 1.0)
{
float rAlpha = acos(rCosAlpha);
if (rAlpha >= s_rErrorToleranceAngle)
{
#if SKYCLOUD_VERBOSE
SkyTrace("Angle Error Update %f", SKYRADSTODEGREES * rAlpha);
#endif
return false;
}
}
float rDistance = (_vecPosition - cam.Orig).Length();
float rCamRadius = sqrt(cam.wR*cam.wR + cam.Near*cam.Near);
int iRes = _GetRequiredLogResolution(rDistance, _pWorldSpaceBV->GetRadius(), rCamRadius);
if (iRes > _iLogResolution)
{
#if SKYCLOUD_VERBOSE
SkyTrace("Resolution Error Update: Required: %d Actual: %d", iRes, _iLogResolution);
#endif
return false;
}
return true;
}
//------------------------------------------------------------------------------
// Function : SetErrorToleranceAngle
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::SetErrorToleranceAngle(float rDegrees)
* @brief Set the global error tolerance angle for all impostors.
*/
void SkyRenderableInstanceCloud::SetErrorToleranceAngle(float rDegrees)
{
s_rErrorToleranceAngle = SKYDEGREESTORADS * rDegrees;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::_Initialize
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::_Initialize()
* @brief Initializer used by the constructors.
*/
void SkyRenderableInstanceCloud::_Initialize()
{
_UpdateWorldSpaceBounds();
// if (!s_pRenderBuffer && _bUseOffScreenBuffer)
// {
//JW?? s_pRenderBuffer = new SkyOffScreenBuffer(GLUT_SINGLE | GLUT_DEPTH | GLUT_STENCIL);
//JW?? s_pRenderBuffer->Initialize(true);
//JW?? s_pRenderBuffer->MakeCurrent();
// set some GL state:
// glClearColor(0, 0, 0, 0);
//JW?? GLVU::GetCurrent()->MakeCurrent();
// }
if (!s_pMaterial)
{
s_pMaterial = new SkyMaterial;
s_pMaterial->EnableBlending(true);
s_pMaterial->SetBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
s_pMaterial->SetAlphaFunc(GL_GREATER);
s_pMaterial->EnableDepthTest(false);
s_pMaterial->SetDepthMask(true);
s_pMaterial->EnableAlphaTest(true);
s_pMaterial->EnableLighting(false);
s_pMaterial->SetTextureParameter(0, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
s_pMaterial->SetTextureParameter(0, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
s_pMaterial->SetTextureParameter(0, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
s_pMaterial->EnableTexture(0, true);
}
s_iCount++;
}

View File

@@ -1,273 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyRenderableInstanceCloud.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyRenderableInstanceCloud.hpp
*
* Interface for class SkyRenderableInstanceCloud, an instance of a SkyCloud object.
*/
#ifndef __SKYRENDERABLEINSTANCECLOUD_HPP__
#define __SKYRENDERABLEINSTANCECLOUD_HPP__
class SkyCloud;
class SkyTexture;
//class SkyOffScreenBuffer;
#include <vector>
#include "camera.hpp"
#include "SkyContext.hpp"
#include "SkyRenderableInstance.hpp"
#include "SkyRenderableInstanceGeneric.hpp"
#include "SkyCloud.hpp"
//------------------------------------------------------------------------------
/**
* @class SkyRenderableInstanceCloud
* @brief An instance of a cloud. Renders using an impostor.
*
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
*/
class SkyRenderableInstanceCloud : public SkyRenderableInstance
{
public:
SkyRenderableInstanceCloud( SkyCloud *pCloud, bool bUseOffScreenBuffer = false);
SkyRenderableInstanceCloud( SkyCloud *pCloud,
const Vec3f &position,
const Mat33f &rotation,
const float scale,
bool bUseOffScreenBuffer = false);
virtual ~SkyRenderableInstanceCloud();
// Setters / Getters
//! Sets the identifier for this cloud (used by SkySceneManager.)
void SetID(int id) { _iCloudID = id; }
virtual void SetPosition(const Vec3f &position);
virtual void SetRotation(const Mat33f &rotation);
virtual void SetScale(const float &scale);
//! Returns SkySceneManager's id for this cloud.
int GetID() const { return _iCloudID; }
//! Returns a pointer to the renderable that this instance represents.
virtual SkyCloud* GetCloud() const { return _pCloud; }
//! Returns the world space bounding box of the cloud instance.
const SkyMinMaxBox& GetWorldSpaceBounds() { return *_pWorldSpaceBV; }
//! Make this into a split impostor. Will be rendered as two halves, around the split point.
void SetSplit(bool bSplit) { _bSplit = bSplit; }
//! Set the distance at which the cloud will be split (from the camera position).
void SetSplitPoint(const Vec3f& vecSplit) { _vecSplit = vecSplit; }
//! Returns true if this is a split impostor (cloud contains objects)
bool IsSplit() const { return _bSplit; }
//! Returns true if the camera is inside this clouds bounding volume.
bool IsScreenImpostor() const { return _bScreenImpostor; }
virtual SKYRESULT Update(const Camera& cam);
virtual SKYRESULT Display(bool bDisplayFrontOfSplit = false);
SKYRESULT DisplayWithoutImpostor(const Camera& cam);
virtual bool ViewFrustumCull( const Camera &cam );
void ReleaseImpostorTextures();
virtual SkyMinMaxBox* GetBoundingVolume() const { return _pWorldSpaceBV; }
//----------------------------------------------------------------------------
// Determine if the current impostor image is valid for the given viewpoint
//----------------------------------------------------------------------------
bool IsImpostorValid(const Camera &cam);
//------------------------------------------------------------------------------
// Function : Enable
// Description :
//------------------------------------------------------------------------------
/**
* @fn Enable(bool bEnable)
* @brief Enable / Disable the use of impostor images (if disabled, displays geometry).
*/
void Enable(bool bEnable) { _bEnabled = bEnable; }
static void SetErrorToleranceAngle(float rDegrees);
protected: // methods
void _Initialize();
inline int _GetRequiredLogResolution(float rObjectDistance, float rObjectRadius, float rCamRadius);
inline void _UpdateWorldSpaceBounds();
protected: // data
int _iCloudID; // used by the scene manager to identify clouds.
SkyCloud *_pCloud; // Pointer to the cloud object
SkyMinMaxBox *_pWorldSpaceBV; // Pointer to bounding volume in object space
float _rRadius; // Radius of the impostor.
bool _bScreenImpostor; // Is this a screen space or world space impostor?
bool _bImageExists; // The impostor image exists and is ready to use.
bool _bEnabled; // if disabled, draw geometry -- otherwise, draw impostor.
bool _bUseOffScreenBuffer; // if enabled, uses off-screen rendering to create impostor images.
bool _bSplit; // true if the cloud contains other object instances.
Vec3f _vecSplit; // the point about which this cloud is split.
Vec3f _vecNearPoint; // Nearest point on bounding sphere to viewpoint.
Vec3f _vecFarPoint; // Farthest point on bounding sphere from viewpoint.
Camera _impostorCam; // camera used to generate this impostor
unsigned int _iLogResolution; // Log base 2 of current impostor image resolution.
SkyTexture *_pBackTexture; // Back texture for split clouds or main texture for unsplit.
SkyTexture *_pFrontTexture; // Front texture for split clouds.
unsigned int _iCulledCount; // used to determine when to release textures
static unsigned int s_iCount; // keep track of number of impostors using the render buffer.
//JW?? static SkyOffScreenBuffer* s_pRenderBuffer;
static float s_rErrorToleranceAngle;
static SkyMaterial *s_pMaterial; // shared material for cloud impostors.
};
//------------------------------------------------------------------------------
/**
* @class SkyContainerCloud
* @brief A class used to organize the rendering order of cloud impostors and the objects in the clouds
*
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
*/
class SkyContainerCloud : public SkyRenderableInstance
{
public: // methods
//! Constructor.
SkyContainerCloud(SkyRenderableInstanceCloud *cloud) : SkyRenderableInstance(), pCloud(cloud) {}
//! Destructor.
~SkyContainerCloud()
{ pCloud = NULL; containedOpaqueInstances.clear(); containedTransparentInstances.clear(); }
virtual SKYRESULT Display()
{
// display the back half of the split impostor.
FAIL_RETURN_MSG(pCloud->Display(false),
"SkySceneManager::Display(): cloud instance display failed.");
if (pCloud->IsSplit())
{
// display contained instances -- first opaque, then transparent.
InstanceIterator ii;
for (ii = containedOpaqueInstances.begin(); ii != containedOpaqueInstances.end(); ++ii)
FAIL_RETURN((*ii)->Display());
for (ii = containedTransparentInstances.begin(); ii != containedTransparentInstances.end(); ++ii)
FAIL_RETURN((*ii)->Display());
// now display the front half of the split impostor.
FAIL_RETURN_MSG(pCloud->Display(true),
"SkySceneManager::Display(): cloud instance display failed.");
}
return SKYRESULT_OK;
}
virtual const Vec3f& GetPosition() const { return pCloud->GetPosition(); }
public: //data -- here the data are public because the interface is minimal.
SkyRenderableInstanceCloud *pCloud;
InstanceArray containedOpaqueInstances;
InstanceArray containedTransparentInstances;
// This operator is used to sort ContainerCloud arrays.
bool operator<(const SkyContainerCloud& container) const
{
return (*((SkyRenderableInstance*)pCloud) < *((SkyRenderableInstance*)container.pCloud));
}
};
//------------------------------------------------------------------------------
// Function : _GetRequiredLogResolution
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::_GetRequiredLogResolution(float rObjectDistance, float rObjectRadius, float rCamRadius)
* @brief Returns the integer logarithm base two of the expected impostor resolution.
*
* Impostor resolution is based on object size, distance, and the FOV of the camera (stored as the
* radius of a sphere centered at the camera position and passing through the corners of the
* projection plane.
*/
inline int SkyRenderableInstanceCloud::_GetRequiredLogResolution(float rObjectDistance,
float rObjectRadius,
float rCamRadius)
{
int iScreenWidth, iScreenHeight;
GraphicsContext::InstancePtr()->GetWindowSize(iScreenWidth, iScreenHeight);
//cout << "SkyRes: w=" << iScreenWidth << "h=" << iScreenHeight << endl; char ff; cin >> ff;
int iScreenResolution = (iScreenWidth > iScreenHeight) ? iScreenWidth : iScreenHeight;
int iLogMinScreenResolution = (iScreenWidth > iScreenHeight) ? iScreenHeight : iScreenWidth;
iLogMinScreenResolution = SkyGetLogBaseTwo(iLogMinScreenResolution) - 1;
int iRes = 2 * iScreenResolution * _pWorldSpaceBV->GetRadius() / rObjectDistance;
int iLogResolution;
if (rObjectDistance - (0.5f * rObjectRadius) < rCamRadius)
{
iLogResolution = SkyGetLogBaseTwo(iScreenResolution / 8);
}
else if (rObjectDistance - rObjectRadius < rCamRadius)
{
iLogResolution = SkyGetLogBaseTwo(iScreenResolution / 4);
}
else if (iRes > iScreenResolution)
{
iLogResolution = SkyGetLogBaseTwo(iScreenResolution / 2);
}
else
{
iLogResolution = SkyGetLogBaseTwo(iRes);
}
// if not rendering to an off screen buffer, make sure the resolution fits in the window!
if (!_bUseOffScreenBuffer && (iLogMinScreenResolution < iLogResolution))
iLogResolution = iLogMinScreenResolution;
return iLogResolution;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceCloud::_UpdateWorldSpaceBounds
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceCloud::_UpdateWorldSpaceBounds()
* @brief Updates the world space bounding box of the cloud.
*/
inline void SkyRenderableInstanceCloud::_UpdateWorldSpaceBounds()
{
SAFE_DELETE(_pWorldSpaceBV);
_pWorldSpaceBV = _pCloud->CopyBoundingVolume();
_vecPosition = _pCloud->CopyBoundingVolume()->GetCenter();
}
#endif //__SKYRENDERABLEINSTANCECLOUD_HPP__

View File

@@ -1,76 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyRenderableInstanceGeneric.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyRenderableInstanceGeneric.hpp
*
* Interface for a basic implementation of SkyRenderableInstance
*/
#ifndef __SKYRENDERABLEINSTANCEGENERIC_HPP__
#define __SKYRENDERABLEINSTANCEGENERIC_HPP__
#include "SkyRenderableInstance.hpp"
// forward to reduce unnecessary dependencies
class SkyRenderable;
class SkyMinMaxBox;
//------------------------------------------------------------------------------
/**
* @class SkyRenderableInstanceGeneric
* @brief A generic renderable instance
*
* The SkyRenderableInstanceGeneric is a basic implementation of the base class.
* For view frustum culling, the function ViewFrustumCull should be called once
* per frame, at which point a flag is set if the object is culled or not. It
* is possible that the object is then queried multiple times if it is culled or
* not by various other objects before being displayed, that is why the flag is
* stored.
*/
class SkyRenderableInstanceGeneric : public SkyRenderableInstance
{
public:
SkyRenderableInstanceGeneric(SkyRenderable *pObject);
SkyRenderableInstanceGeneric(SkyRenderable *pObject,
const Vec3f &position,
const Mat33f &rotation,
const float scale);
virtual ~SkyRenderableInstanceGeneric();
// Setters / Getters
virtual void SetRenderable(SkyRenderable *pRenderable );
//! Returns a pointer to the renderable that this instance represents.
virtual SkyRenderable* GetRenderable() const { return _pObj; }
virtual SKYRESULT Display();
// Test / Set / Get
virtual bool ViewFrustumCull( const Camera &cam );
virtual SkyMinMaxBox* GetBoundingVolume() const { return _pBV; }
protected:
protected:
SkyRenderable *_pObj; // Pointer to the renderable object
SkyMinMaxBox *_pBV; // Pointer to bounding volume
};
#endif //__SKYRENDERABLEINSTANCEGENERIC_HPP__

View File

@@ -1,189 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyRenderableInstanceGroup.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyRenderableInstanceGroup.cpp
*
* Implementation of class SkyRenderableInstanceGroup, an instance that groups
* other instances.
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include SG_GL_H
#include "SkyRenderableInstanceGroup.hpp"
#include "SkySceneManager.hpp"
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceGroup::SkyRenderableInstanceGroup
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceGroup::SkyRenderableInstanceGroup()
* @brief Constructor.
*/
SkyRenderableInstanceGroup::SkyRenderableInstanceGroup()
: SkyRenderableInstance(),
_pObjectSpaceBV(NULL)
{
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceGroup::~SkyRenderableInstanceGroup
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceGroup::~SkyRenderableInstanceGroup()
* @brief Destructor.
*/
SkyRenderableInstanceGroup::~SkyRenderableInstanceGroup()
{
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceGroup::Update
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceGroup::Update(const Camera &cam)
* @brief Processes any per frame updates the instance requires.
*
* This method simply calls the SkyRenderableInstance::Update() method of each of
* its sub-instances.
*/
SKYRESULT SkyRenderableInstanceGroup::Update(const Camera &cam)
{
InstanceIterator ii;
for (ii = _opaqueSubInstances.begin(); ii != _opaqueSubInstances.end(); ++ii)
{
FAIL_RETURN((*ii)->Update(cam));
}
for (ii = _transparentSubInstances.begin(); ii != _transparentSubInstances.end(); ++ii)
{
FAIL_RETURN((*ii)->Update(cam));
}
SkySceneManager::SortInstances(_transparentSubInstances, cam.Orig);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceGroup::Display
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceGroup::Display()
* @brief Displays all sub-instances of this instance.
*
* The object-to-world transform of this instance group will be applied to all sub-instances before
* their own object-to-world transforms are applied.
*/
SKYRESULT SkyRenderableInstanceGroup::Display()
{
// Get and set the world space transformation
Mat44f mat;
GetModelToWorldTransform(mat);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(mat.M);
InstanceIterator ii;
/***
for (ii = _opaqueSubInstances.begin(); ii != _opaqueSubInstances.end(); ++ii)
{
FAIL_RETURN((*ii)->Display());
}
for (ii = _transparentSubInstances.begin(); ii != _transparentSubInstances.end(); ++ii)
{
FAIL_RETURN((*ii)->Display());
}
***/
_pObjectSpaceBV->Display();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceGroup::ViewFrustumCull
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceGroup::ViewFrustumCull(const Camera& cam)
* @brief @todo <WRITE BRIEF SkyRenderableInstanceGroup::ViewFrustumCull DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyRenderableInstanceGroup::ViewFrustumCull FUNCTION DOCUMENTATION>
*/
bool SkyRenderableInstanceGroup::ViewFrustumCull(const Camera& cam)
{
Mat44f xform;
GetModelToWorldTransform(xform);
_bCulled = (_pObjectSpaceBV == NULL) ? false : _pObjectSpaceBV->ViewFrustumCull(cam, xform);
return _bCulled;
}
//------------------------------------------------------------------------------
// Function : SkyRenderableInstanceGroup::AddSubInstance
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyRenderableInstanceGroup::AddSubInstance(SkyRenderableInstance *pInstance, bool bTransparent)
* @brief Adds a sub-instance to the group.
*/
void SkyRenderableInstanceGroup::AddSubInstance(SkyRenderableInstance *pInstance, bool bTransparent)
{
if (!bTransparent)
_opaqueSubInstances.push_back(pInstance);
else
_transparentSubInstances.push_back(pInstance);
// update the bounds...
Mat44f xform;
pInstance->GetModelToWorldTransform(xform);
SkyMinMaxBox *pBV = pInstance->GetBoundingVolume();
if (pBV)
{
Vec3f min = pInstance->GetBoundingVolume()->GetMin();
Vec3f max = pInstance->GetBoundingVolume()->GetMax();
if (!_pObjectSpaceBV)
_pObjectSpaceBV = new SkyMinMaxBox;
_pObjectSpaceBV->AddPoint(xform * min);
_pObjectSpaceBV->AddPoint(xform * max);
}
}

View File

@@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyRenderableInstanceGroup.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyRenderableInstanceGroup.hpp
*
* Interface definition for class SkyRenderableInstanceGroup, an instance that groups
* other instances.
*/
#ifndef __SKYRENDERABLEINSTANCEGROUP_HPP__
#define __SKYRENDERABLEINSTANCEGROUP_HPP__
#include "SkyRenderableInstance.hpp"
#include "SkyMinMaxBox.hpp"
//------------------------------------------------------------------------------
/**
* @class SkyRenderableInstanceGroup
* @brief A renderable instance that groups other instances.
*
* This class provides a very basic way to implement static hierarchies of objects.
* It is not meant to be a full scene graph --
*/
class SkyRenderableInstanceGroup : public SkyRenderableInstance
{
public:
SkyRenderableInstanceGroup();
virtual ~SkyRenderableInstanceGroup();
//! Update all sub-instances.
virtual SKYRESULT Update(const Camera &cam);
//! Render all sub-instances.
virtual SKYRESULT Display();
//! Returns true if and only if the bounding volume of this instance lies entirely outside @a cam.
virtual bool ViewFrustumCull(const Camera &cam);
//! Adds an instance to the group that this instance represents.
void AddSubInstance(SkyRenderableInstance *pInstance, bool bTransparent);
protected:
InstanceArray _opaqueSubInstances;
InstanceArray _transparentSubInstances;
SkyMinMaxBox *_pObjectSpaceBV; // Pointer to bounding volume in object space
};
#endif //__SKYRENDERABLEINSTANCEGROUP_HPP__

View File

@@ -1,278 +0,0 @@
//------------------------------------------------------------------------------
// File : SkySceneLoader.cpp
//------------------------------------------------------------------------------
// Adapted from SkyWorks for FlightGear by J. Wojnaroski -- castle@mminternet.com
// Copywrite July 2002
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/**
* @file SkySceneLoader.cpp
*
* Implementation of class SkySceneLoader.
*/
#include <plib/ssg.h>
#include <plib/sg.h>
#include <simgear/misc/sg_path.hxx>
#include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx>
#include <simgear/math/vector.hxx>
#include "SkySceneLoader.hpp"
#include "SkySceneManager.hpp"
#include "SkyTextureManager.hpp"
#include "SkySceneManager.hpp"
#include "SkyDynamicTextureManager.hpp"
#include "SkyContext.hpp"
#include "SkyLight.hpp"
#include "camera.hpp"
ssgLight _sky_ssgLights [ 8 ] ;
sgdVec3 cam_pos;
static sgdVec3 delta;
Point3D origin;
Camera *pCam = new Camera();
// Need to add a light here until we figure out how to use the sun position and color
SkyLight::SkyLightType eType = SkyLight::SKY_LIGHT_DIRECTIONAL;
SkyLight *pLight = 0;
// hack
sgMat4 my_copy_of_ssgOpenGLAxisSwapMatrix =
{
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
//------------------------------------------------------------------------------
// Function : SkySceneLoader::SkySceneLoader
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneLoader::SkySceneLoader()
* @brief Constructor.
*/
SkySceneLoader::SkySceneLoader()
{
}
//------------------------------------------------------------------------------
// Function : SkySceneLoader::~SkySceneLoader
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneLoader::~SkySceneLoader()
* @brief Destructor.
*/
SkySceneLoader::~SkySceneLoader()
{
SceneManager::Destroy();
DynamicTextureManager::Destroy();
TextureManager::Destroy();
GraphicsContext::Destroy();
}
//------------------------------------------------------------------------------
// Function : SkySceneLoader::Load
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneLoader::Load(std::string filename)
* @brief Loads a SkyWorks scene.
*
* This is a temporary fix, as it loads only limited scenes
* It can however, load any number of Cloud
+
*/
//bool SkySceneLoader::Load(std::string filepath)
bool SkySceneLoader::Load( unsigned char *data, unsigned int size, double latitude, double longitude )
{
if( !pLight)
pLight = new SkyLight(eType);
// Need to create the managers
cout << "GraphicsContext::Instantiate();" << endl;
GraphicsContext::Instantiate();
cout << " TextureManager::Instantiate();" << endl;
TextureManager::Instantiate();
cout << " DynamicTextureManager::Instantiate();" << endl;
DynamicTextureManager::Instantiate();
cout << " SceneManager::Instantiate();" << endl;
SceneManager::Instantiate();
float rScale = 40.0;
FAIL_RETURN(SceneManager::InstancePtr()->LoadClouds(data, size, rScale, latitude, longitude));
Vec3f dir(0, 0, 1);
pLight->SetPosition(Vec3f(0, 0, 17000));
pLight->SetDirection(dir);
pLight->SetAmbient(Vec4f( 0.0f, 0.0f, 0.0f, 0.0f));
pLight->SetDiffuse(Vec4f(1.0f, 1.0f, 1.0f, 0.0f));
//pLight->SetDiffuse(Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
//pLight->SetSpecular(Vec4f(1.0f, 1.0f, 1.0f, 0.0f));
// No attenuation
pLight->SetAttenuation(1.0f, 0.0f, 0.0f);
SceneManager::InstancePtr()->AddLight(pLight);
SceneManager::InstancePtr()->ShadeClouds();
return true;
}
//------------------------------------------------------------------------------
// Function : SkySceneLoader::Load
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneLoader::Load(std::string filename)
* @brief Loads a SkyWorks scene.
*
* This is a temporary fix, as it loads only limited scenes
* It can however, load any number of Cloud
+
*/
//bool SkySceneLoader::Load(std::string filepath)
bool SkySceneLoader::Load( SGPath filename, double latitude, double longitude )
{
SkyArchive archive;
SGPath base = filename.dir();
if (SKYFAILED(archive.Load(filename.c_str()))) {
cout << "Archive file not found\n" << filename.c_str();
return false;
}
char *pFilename;
// Need to create the managers
cout << "GraphicsContext::Instantiate();" << endl;
GraphicsContext::Instantiate();
cout << " TextureManager::Instantiate();" << endl;
TextureManager::Instantiate();
cout << " DynamicTextureManager::Instantiate();" << endl;
DynamicTextureManager::Instantiate();
cout << " SceneManager::Instantiate();" << endl;
SceneManager::Instantiate();
unsigned int iNumFiles;
if (!SKYFAILED(archive.GetInfo("CloudFile", STRING_TYPE, &iNumFiles)))
{
iNumFiles = ulEndianLittle32(iNumFiles);
for (unsigned int i = 0; i < iNumFiles; ++i)
{
FAIL_RETURN(archive.FindString("CloudFile", &pFilename, i));
// this is where we have to append the $fg_root string to the filename
base.append( pFilename );
const char *FilePath = base.c_str();
//float rScale = 1.0;
//FAIL_RETURN(archive.FindFloat32("CloudScale", &rScale, i));
float rScale = 40.0;
SkyArchive cloudArchive;
cout << "Calling cloudArchive.Load(FilePath)" << endl;
FAIL_RETURN(cloudArchive.Load(FilePath));
cout << "Calling SceneManager::InstancePtr()->LoadClouds" << endl;
FAIL_RETURN(SceneManager::InstancePtr()->LoadClouds(cloudArchive, rScale, latitude, longitude));
}
}
cout << "After Load Clouds" << endl;
Vec3f dir(0, 0, 1);
if( !pLight)
pLight = new SkyLight(eType);
pLight->SetPosition(Vec3f(0, 0, 17000));
pLight->SetDirection(dir);
pLight->SetAmbient(Vec4f( 0.0f, 0.0f, 0.0f, 0.0f));
pLight->SetDiffuse(Vec4f(1.0f, 1.0f, 1.0f, 0.0f));
//pLight->SetDiffuse(Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
//pLight->SetSpecular(Vec4f(1.0f, 1.0f, 1.0f, 0.0f));
// No attenuation
pLight->SetAttenuation(1.0f, 0.0f, 0.0f);
cout << "Before SceneManager::InstancePtr()->AddLight(pLight)" << endl;
SceneManager::InstancePtr()->AddLight(pLight);
cout << "Before SceneManager::InstancePtr()->ShadeClouds()" << endl;
SceneManager::InstancePtr()->ShadeClouds();
cout << "After SceneManager::InstancePtr()->ShadeClouds()" << endl;
return true;
}
void SkySceneLoader::Set_Cloud_Orig( Point3D *posit )
{
// set origin for cloud coordinates to initial tile center
origin = *posit;
sgdSetVec3( delta, origin[0], origin[1], origin[2]);
//printf("Cloud marker %f %f %f\n", origin[0], origin[1], origin[2] );
}
void SkySceneLoader::Update( double *view_pos )
{
double wind_x, wind_y, wind_z;
wind_x = 0.0; wind_z = 0.0;
// just a dumb test to see what happens if we can move the clouds en masse via the camera
delta[0] += wind_x; delta[2] += wind_z;
sgdSubVec3( cam_pos, view_pos, delta );
//cout << "ORIGIN: " << delta[0] << " " << delta[1] << " " << delta[2] << endl;
//cout << "CAM : " << cam_pos[0] << " " << cam_pos[1] << " " << cam_pos[2] << endl;
SceneManager::InstancePtr()->Update(*pCam);
// need some scheme to reshade selected clouds a few at a time to save frame rate cycles
// SceneManager::InstancePtr()->ShadeClouds();
}
void SkySceneLoader::Resize( double w, double h )
{
pCam->Perspective( (float) h, (float) (w / h), 0.5, 120000.0 );
}
void SkySceneLoader::Draw( sgMat4 mat )
{
sgMat4 cameraMatrix;
// sgCopyMat4(cameraMatrix,mat);
// or just
ssgGetModelviewMatrix(cameraMatrix);
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity () ;
glLoadMatrixf( (float *) cameraMatrix );
pCam->SetModelviewMatrix( (float *) cameraMatrix );
SceneManager::InstancePtr()->Display(*pCam);
//pLight->Display(); // draw the light position to debug with sun position
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity () ;
}

View File

@@ -1,64 +0,0 @@
//------------------------------------------------------------------------------
// File : SkySceneLoader.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkySceneLoader.hpp
*
* Definition of a simple class for loading scenes into SkyWorks.
*/
#ifndef __SKYSCENELOADER_HPP__
#define __SKYSCENELOADER_HPP__
#ifdef HAVE_CONFIG
# include <config.h>
#endif
#include <simgear/compiler.h>
#include <simgear/misc/sg_path.hxx>
#include <simgear/math/point3d.hxx>
#include "SkyUtil.hpp"
//------------------------------------------------------------------------------
/**
* @class SkySceneLoader
* @brief A simple scene loader for SkyWorks scenes.
*
* Loads a scene using the Load() method, which is passed the filename of a
* file containing a SkyArchive describing the scene.
*/
class SkySceneLoader
{
public:
SkySceneLoader();
~SkySceneLoader();
bool Load( unsigned char *data, unsigned int size, double latitude, double longitude );
bool Load( SGPath fileroot, double latitude, double longitude );
void Set_Cloud_Orig( Point3D *posit );
void Update( double *view_pos );
void Resize( double w, double h);
void Draw( sgMat4 mat );
};
#endif //__SKYSCENELOADER_HPP__

View File

@@ -1,946 +0,0 @@
//------------------------------------------------------------------------------
// File : SkySceneManager.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkySceneManager.cpp
*
* Implementation of the singleton class SkySceneManager, which manages objects,
* instances, scene update, visibility, culling, and rendering.
*/
// warning for truncation of template name for browse info
#pragma warning( disable : 4786)
#include "SkySceneManager.hpp"
#include "SkyMaterial.hpp"
#include "SkyLight.hpp"
#include "SkyCloud.hpp"
#include "SkyRenderable.hpp"
#include "SkyRenderableInstance.hpp"
#include "SkyRenderableInstanceCloud.hpp"
#include "camutils.hpp"
#include <algorithm>
//------------------------------------------------------------------------------
// Function : SkySceneManager::SkySceneManager
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::SkySceneManager()
* @brief Constructor
*/
SkySceneManager::SkySceneManager()
: /*_pSkyBox(NULL),
_pTerrain(NULL),*/
_bDrawLights(false),
_bDrawTree(false),
_bReshadeClouds(true)
{
_wireframeMaterial.SetColorMaterialMode(GL_DIFFUSE);
_wireframeMaterial.EnableColorMaterial(true);
_wireframeMaterial.EnableLighting(false);
// add the default material with ID -1
// this should avoid errors caused by models without materials exported from MAX
// (because flexporter gives them the ID -1).
SkyMaterial *pDefaultMaterial = new SkyMaterial;
pDefaultMaterial->SetMaterialID(-1);
AddMaterial(pDefaultMaterial);
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::~SkySceneManager
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::~SkySceneManager()
* @brief Destructor.
*
* This destructor deletes all renderables, instances (renderable instances, cloud instances,
* and otherwise), materials, and lights that were added to the scene using the Add*() functions.
* In other words, the scene manager owns all entities added to the scene. This eases cleanup
* and shutdown.
*/
SkySceneManager::~SkySceneManager()
{
ObjectIterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi)
SAFE_DELETE(*oi);
_objects.clear();
CloudIterator ci;
for (ci = _clouds.begin(); ci != _clouds.end(); ++ci)
SAFE_DELETE(*ci);
_clouds.clear();
InstanceIterator ii;
for (ii = _instances.begin(); ii != _instances.end(); ++ii)
SAFE_DELETE(*ii);
_instances.clear();
CloudInstanceIterator cii;
for (cii = _cloudInstances.begin(); cii != _cloudInstances.end(); ++cii)
SAFE_DELETE(*cii);
_cloudInstances.clear();
ContainerSetIterator cni;
for (cni = _containerClouds.begin(); cni != _containerClouds.end(); ++cni)
SAFE_DELETE(cni->second);
_containerClouds.clear();
MaterialIterator mi;
for (mi = _materials.begin(); mi != _materials.end(); ++mi)
SAFE_DELETE(mi->second);
_materials.clear();
LightIterator li;
for (li = _lights.begin(); li!= _lights.end(); ++li)
SAFE_DELETE(li->second);
_lights.clear();
//SAFE_DELETE(_pSkyBox);
//SAFE_DELETE(_pTerrain);
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::AddObject
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::AddObject(SkyRenderable *pObject)
* @brief Add a new SkyRenderable object to the manager.
*/
SKYRESULT SkySceneManager::AddObject(SkyRenderable *pObject)
{
// Check for null object
if (NULL == pObject)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL,
"SkySceneManager::AddObject(): Attempting to add NULL Renderable Object.");
}
_objects.push_back(pObject);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::AddInstance
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::AddInstance(SkyRenderableInstance *pInstance, bool bTransparent)
* @brief Add a new SkyRenderableInstance to the manager.
*/
SKYRESULT SkySceneManager::AddInstance(SkyRenderableInstance *pInstance, bool bTransparent /* = false */)
{
// Check for null instance
if (NULL == pInstance)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL,
"SkySceneManager::AddObject(): Attempting to add NULL Renderable Instance.");
}
if (!bTransparent)
_instances.push_back(pInstance);
else
_transparentInstances.push_back(pInstance);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::AddCloud
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::AddCloud(SkyCloud *pCloud)
* @brief Add a new cloud object to the manager.
*
* @todo <WRITE EXTENDED SkySceneManager::AddCloud FUNCTION DOCUMENTATION>
*/
SKYRESULT SkySceneManager::AddCloud(SkyCloud *pCloud)
{
if (NULL == pCloud)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL,
"SkySceneManager::AddObject(): Attempting to add NULL SkyCloud Object.");
}
_clouds.push_back(pCloud);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::AddCloudInstance
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::AddCloudInstance(SkyRenderableInstanceCloud *pInstance)
* @brief Add a new instance of a cloud to the manager.
*
* @todo Note that since cloud instances share shading information, if two instances
* of a cloud have different orientations, one of the instances will have incorrect
* lighting for the scene. For this reason, I recommend that the number of clouds and
* cloud instances is equal.
*/
SKYRESULT SkySceneManager::AddCloudInstance(SkyRenderableInstanceCloud *pInstance)
{
// Check for null instance
if (NULL == pInstance)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL,
"SkySceneManager::AddObject(): Attempting to add NULL SkyCloud Instance.");
}
pInstance->SetID(_cloudInstances.size());
_cloudInstances.push_back(pInstance);
SkyContainerCloud *pContainer = new SkyContainerCloud(pInstance);
_containerClouds.insert(std::make_pair(pInstance->GetID(), pContainer));
RebuildCloudBVTree();
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::AddMaterial
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::AddMaterial(SkyMaterial *pMaterial)
* @brief Adds a material to the scene.
*
* Materials are kept in a map with their ID as key. A material can be retrieved
* from the scene manager by passing its ID to GetMaterial.
*
* @see GetMaterial, SkyMaterial
*/
SKYRESULT SkySceneManager::AddMaterial(SkyMaterial *pMaterial)
{
// Check for null instance
if (NULL == pMaterial)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL,
"SkySceneMananger::AddMaterial(): Attempting to add NULL Material to Scene Manager");
}
_materials.insert(std::make_pair(pMaterial->GetMaterialID(), pMaterial));
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::GetMaterial
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::GetMaterial(int iMaterialID)
* @brief Returns the material with ID @a iMaterialID.
*
* If the material is not found, returns NULL.
*
* @see AddMaterial, SkyMaterial
*/
SkyMaterial* SkySceneManager::GetMaterial(int iMaterialID)
{
MaterialIterator mi = _materials.find(iMaterialID);
if (_materials.end() == mi)
{
SkyTrace("SkySceneManager::GetMaterial: Error: invalid material ID");
return NULL;
}
else
return mi->second;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::ActivateMaterial
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::ActivateMaterial(int iMaterialID)
* @brief Makes the specified material active, setting the appropriate rendering state.
*
* @todo <WRITE EXTENDED SkySceneManager::ActivateMaterial FUNCTION DOCUMENTATION>
*/
SKYRESULT SkySceneManager::ActivateMaterial(int iMaterialID)
{
// cout << "Activating material\n"; char mm; cin >> mm;
MaterialIterator mi = _materials.find(iMaterialID);
if (_materials.end() == mi)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL,
"SkySceneManager::ActivateMaterial: Error: invalid material ID.");
}
else
{
FAIL_RETURN_MSG(mi->second->Activate(),
"SkySceneManager::ActivateMaterial: Error: failed to activate.");
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::AddLight
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::AddLight(SkyLight *pLight)
* @brief @todo <WRITE BRIEF SkySceneManager::AddLight DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::AddLight FUNCTION DOCUMENTATION>
*/
SKYRESULT SkySceneManager::AddLight(SkyLight *pLight)
{
// Check for null instance
if (NULL == pLight)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL,
"SkySceneMananger::AddLight(): Attempting to add NULL Light to Scene Manager");
}
_lights.insert(std::make_pair(_lights.size(), pLight));
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::GetLight
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::GetLight(int iLightID)
* @brief @todo <WRITE BRIEF SkySceneManager::GetLight DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::GetLight FUNCTION DOCUMENTATION>
*/
SkyLight* SkySceneManager::GetLight(int iLightID)
{
LightIterator li = _lights.find(iLightID);
if (_lights.end() == li)
{
SkyTrace("SkySceneManager::GetLight: Error: Invalid light ID");
return NULL;
}
else
return li->second;
}
//------------------------------------------------------------------------------
// Function : Alive
// Description :
//------------------------------------------------------------------------------
/**
* @fn Alive(SkyRenderableInstance* pInstance)
* @brief A predicate to determine if an object is dead or not.
*/
bool Alive(SkyRenderableInstance* pInstance)
{
return (pInstance->IsAlive());
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::Update
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::Update(const Camera &cam)
* @brief Iterate through all SkyRenderableInstances and update them.
*/
SKYRESULT SkySceneManager::Update(const Camera &cam)
{
_ResolveVisibility(cam);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::Display
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::Display(const Camera &cam)
* @brief Iterate through all SkyRenderableInstances and display them.
*/
SKYRESULT SkySceneManager::Display( const Camera &cam )
{
// _clearMaterial.Force();
_clearMaterial.Activate();
//glClear(GL_DEPTH_BUFFER_BIT);
// set lights (only lights that have changed will be passed to GL).
for (LightIterator li = _lights.begin(); li != _lights.end(); ++li)
{
li->second->Activate(li->first);
//if (_bDrawLights)
//li->second->Display();
}
//if (_bDrawTree)// force the issue and draw
//_VisualizeCloudBVTree(cam, _cloudBVTree.GetRoot());
/*
glLineWidth(2.0);
glBegin(GL_LINES);
// red is Cartesian y-axis
glColor3ub( 255, 0, 0 );
glVertex3f( 0.0,0.0,0.0 );
glVertex3f( 0.0, -104000.0, 0.0);
// yellow is Cartesian z-axis
glColor3ub( 255, 255, 0 );
glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 0.0, 0.0, 104000.0);
// blue is Cartesian x-axis
glColor3ub( 0, 0, 255 );
glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( -104000.0, 0.0, 0.0);
glEnd();
*/
// draw all container clouds and "free" objects not in clouds.
//int i = 0;
for (InstanceIterator iter = _visibleInstances.begin(); iter != _visibleInstances.end(); ++iter)
{
FAIL_RETURN_MSG((*iter)->Display(),
"SkySceneManager::Display(): instance display failed.");
//i++;
}
//cout << "There are " << i << " visible clouds\n";
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::RebuildCloudBVTree
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::RebuildCloudBVTree()
* @brief Builds an AABB tree of the cloud bounding volumes.
*/
SKYRESULT SkySceneManager::RebuildCloudBVTree()
{
CloudInstanceIterator cii;
SkyMinMaxBox bbox;
_cloudBVTree.BeginTree();
for (cii = _cloudInstances.begin(); cii != _cloudInstances.end(); ++cii)
{
bbox = (*cii)->GetWorldSpaceBounds();
_cloudBVTree.AddObject(*cii, bbox);
}
_cloudBVTree.EndTree();
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::ShadeClouds
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::ShadeClouds()
* @brief @todo <WRITE BRIEF SkySceneManager::ShadeClouds DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::ShadeClouds FUNCTION DOCUMENTATION>
*/
SKYRESULT SkySceneManager::ShadeClouds()
{
// cout << "SkySceneManager::ShadeClouds()\n";
int i=0;
for (CloudInstanceIterator cii = _cloudInstances.begin(); cii != _cloudInstances.end(); ++cii)
{
for (LightIterator li = _lights.begin(); li != _lights.end(); ++li)
{
if (SkyLight::SKY_LIGHT_DIRECTIONAL == li->second->GetType())
{
(*cii)->GetCloud()->Illuminate(li->second, *cii, li == _lights.begin());
// printf("Shading Cloud %d of %d with light %d \n", i++, _cloudInstances.size(), *li );
}
}
}
_bReshadeClouds = false;
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::LoadClouds
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::LoadClouds(SkyArchive& cloudArchive, float rScale)
* @brief @todo <WRITE BRIEF SkySceneManager::LoadClouds DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::LoadClouds FUNCTION DOCUMENTATION>
*/
SKYRESULT SkySceneManager::LoadClouds(unsigned char *data, unsigned int size, float rScale, double latitude, double longitude)
{
SkyCloud *pCloud = new SkyCloud();
pCloud->Load(data, size, rScale, latitude, longitude);
SkyRenderableInstanceCloud *pInstance = new SkyRenderableInstanceCloud(pCloud, false);
AddCloud(pCloud);
AddCloudInstance(pInstance);
RebuildCloudBVTree();
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::LoadClouds
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::LoadClouds(SkyArchive& cloudArchive, float rScale)
* @brief @todo <WRITE BRIEF SkySceneManager::LoadClouds DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::LoadClouds FUNCTION DOCUMENTATION>
*/
SKYRESULT SkySceneManager::LoadClouds(SkyArchive& cloudArchive, float rScale, double latitude, double longitude)
{
unsigned int iNumClouds = 0;
cloudArchive.FindUInt32("CldNumClouds", &iNumClouds);
iNumClouds = ulEndianLittle32(iNumClouds);
SkyArchive subArchive;
//iNumClouds = 5; //set this value to reduce cloud field for debugging
for (int i = 0; i < iNumClouds; ++i)
{printf("Loading # %d of %d clouds\n", i+1, iNumClouds);
cloudArchive.FindArchive("Cloud", &subArchive, i);
SkyCloud *pCloud = new SkyCloud();
pCloud->Load(subArchive, rScale, latitude, longitude);
SkyRenderableInstanceCloud *pInstance = new SkyRenderableInstanceCloud(pCloud, false);
AddCloud(pCloud);
AddCloudInstance(pInstance);
}
RebuildCloudBVTree();
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::_SortClouds
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::_SortClouds(CloudInstanceArray& clouds, const Vec3f& vecSortPoint)
* @brief @todo <WRITE BRIEF SkySceneManager::_SortClouds DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::_SortClouds FUNCTION DOCUMENTATION>
*/
void SkySceneManager::_SortClouds(CloudInstanceArray& clouds, const Vec3f& vecSortPoint)
{
static InstanceComparator comparator;
for (CloudInstanceIterator cii = clouds.begin(); cii != clouds.end(); ++cii)
{
Vec3f vecPos = (*cii)->GetPosition();
vecPos -= vecSortPoint;
(*cii)->SetSquareSortDistance(vecPos.LengthSqr());
}
std::sort(clouds.begin(), clouds.end(), comparator);
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::_SortInstances
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::SortInstances(InstanceArray& instances, const Vec3f& vecSortPoint)
* @brief @todo <WRITE BRIEF SkySceneManager::_SortInstances DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::_SortInstances FUNCTION DOCUMENTATION>
*/
void SkySceneManager::SortInstances(InstanceArray& instances, const Vec3f& vecSortPoint)
{
static InstanceComparator comparator;
for (InstanceIterator ii = instances.begin(); ii != instances.end(); ++ii)
{
Vec3f vecPos = (*ii)->GetPosition();
vecPos -= vecSortPoint;
(*ii)->SetSquareSortDistance(vecPos.LengthSqr());
}
std::sort(instances.begin(), instances.end(), comparator);
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::_ViewFrustumCullClouds
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::_ViewFrustumCullClouds(const Camera& cam, const CloudBVTree::Node *pNode)
* @brief @todo <WRITE BRIEF SkySceneManager::_ViewFrustumCullClouds DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::_ViewFrustumCullClouds FUNCTION DOCUMENTATION>
*/
void SkySceneManager::_ViewFrustumCullClouds(const Camera& cam, const CloudBVTree::Node *pNode)
{
if (!pNode)
return;
int i;
int iResult = CamMinMaxBoxOverlap(&cam, pNode->GetNodeBV().GetMin(), pNode->GetNodeBV().GetMax());
//iResult = COMPLETEIN; // just a hack to force the issue
if (COMPLETEIN == iResult)
{
// trivially add all instances
for (i = 0; i < pNode->GetNumObjs(); ++i)
{
SkyRenderableInstanceCloud* pInstance =
const_cast<SkyRenderableInstanceCloud*>(pNode->GetObj(i));
_visibleCloudInstances.push_back(pInstance);
}
}
else if ((PARTIAL == iResult) && pNode->IsLeaf())
{
SkyMinMaxBox bbox;
// check each instance in this node against camera
for (i = 0; i < pNode->GetNumObjs(); ++i)
{
SkyRenderableInstanceCloud* pInstance =
const_cast<SkyRenderableInstanceCloud*>(pNode->GetObj(i));
bbox = pInstance->GetWorldSpaceBounds();
iResult = CamMinMaxBoxOverlap(&cam, bbox.GetMin(), bbox.GetMax());
if (COMPLETEOUT != iResult)
_visibleCloudInstances.push_back(pInstance);
else
pInstance->ReleaseImpostorTextures();
}
}
else if (PARTIAL == iResult)
{
_ViewFrustumCullClouds(cam, pNode->GetLeftChild());
_ViewFrustumCullClouds(cam, pNode->GetRightChild());
}
else // the node is completely out. All of its child clouds should release their textures.
{
for (i = 0; i < pNode->GetNumObjs(); ++i)
{
SkyRenderableInstanceCloud* pInstance =
const_cast<SkyRenderableInstanceCloud*>(pNode->GetObj(i));
pInstance->ReleaseImpostorTextures();
}
}
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::_VisualizeCloudBVTree
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::_VisualizeCloudBVTree(const Camera& cam, const CloudBVTree::Node *pNode)
* @brief @todo <WRITE BRIEF SkySceneManager::_VisualizeCloudBVTree DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::_VisualizeCloudBVTree FUNCTION DOCUMENTATION>
*/
void SkySceneManager::_VisualizeCloudBVTree(const Camera& cam, const CloudBVTree::Node *pNode)
{
// set display state.
_wireframeMaterial.Activate();
int iResult = CamMinMaxBoxOverlap(&cam, pNode->GetNodeBV().GetMin(), pNode->GetNodeBV().GetMax());
if (COMPLETEIN == iResult)
{
// draw this node's bounding box in green.
glColor3f(0, 1, 0);
pNode->GetNodeBV().Display();
}
else if (PARTIAL == iResult)
{
SkyMinMaxBox bbox;
if (pNode->IsLeaf())
{
// draw this node's bounding box and the boxes of all of its objects that are visible.
// draw this node's bbox in orange.
glColor3f(1, 0.5, 0);
pNode->GetNodeBV().Display();
int i;
for (i = 0; i < pNode->GetNumObjs(); ++i)
{
SkyRenderableInstanceCloud* pInstance =
const_cast<SkyRenderableInstanceCloud*>(pNode->GetObj(i));
bbox = pInstance->GetWorldSpaceBounds();
iResult = CamMinMaxBoxOverlap(&cam, bbox.GetMin(), bbox.GetMax());
if (COMPLETEIN == iResult)
{
// draw the box in green
glColor3f(0, 1, 0);
bbox.Display();
}
else if (PARTIAL == iResult)
{
// draw the box in yellow
glColor3f(1, 1, 0);
bbox.Display();
}
}
}
else
{
_VisualizeCloudBVTree(cam, pNode->GetLeftChild());
_VisualizeCloudBVTree(cam, pNode->GetRightChild());
}
}
else
{
// draw the node's bbox in red.
// This should NEVER be visible from the camera from which it was culled!
glColor3f(1, 0, 0);
pNode->GetNodeBV().Display();
}
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::_ResolveVisibility
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::_ResolveVisibility(const Camera &cam)
* @brief @todo <WRITE BRIEF SkySceneManager::_ResolveRenderingOrder DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::_ResolveRenderingOrder FUNCTION DOCUMENTATION>
*/
SKYRESULT SkySceneManager::_ResolveVisibility(const Camera &cam)
{
InstanceIterator ii;
// clear the free instance array
_visibleInstances.clear();
// clear the contained instance arrays
ContainerSetIterator csi;
for (csi = _containerClouds.begin(); csi != _containerClouds.end(); ++csi)
{
csi->second->containedOpaqueInstances.clear();
csi->second->containedTransparentInstances.clear();
}
// clear the visible cloud array.
_visibleCloudInstances.clear();
// Test each instance for containment inside a cloud's bounding volume.
// If the instance is inside a cloud, it is considered a "contained" instance, and will be
// rendered with the cloud in which it is contained for correct visibility. If the instance is
// not inside any cloud, then it is a "free" instance, and will be rendered after all contained
// instances. Transparent instances of each type are rendered after opaque instances of each
// type.
// opaque instances
for (ii = _instances.begin(); ii != _instances.end(); ++ii)
{
// cout << "Opague instance\n"; char zz; cin >> zz;
(*ii)->ViewFrustumCull(cam); // First VFC then check if culled, some instances may
// manually set the culled flag, instead of using VFC
if (!(*ii)->IsCulled())
{
// first update this instance.
FAIL_RETURN_MSG((*ii)->Update(cam), "SkySceneManager::_ResolveVisibility(): instance update failed.");
if (!_TestInsertInstanceIntoClouds(cam, _cloudBVTree.GetRoot(), *ii, false))
_visibleInstances.push_back(*ii);
}
}
// transparent instances
for (ii = _transparentInstances.begin(); ii != _transparentInstances.end(); ++ii)
{
// cout << "Transparent instance\n"; char tt; cin >> tt;
(*ii)->ViewFrustumCull(cam); // First VFC then check if culled, some instances may
// manually set the culled flag, instead of using VFC
if (!(*ii)->IsCulled())
{
// first update this instance.
FAIL_RETURN_MSG((*ii)->Update(cam), "SkySceneManager::Update(): instance update failed.");
if (!_TestInsertInstanceIntoClouds(cam, _cloudBVTree.GetRoot(), *ii, true))
_visibleInstances.push_back(*ii);
}
}
// view frustum cull the clouds
_ViewFrustumCullClouds(cam, _cloudBVTree.GetRoot());
// Clouds must be rendered in sorted order.
//_SortClouds(_visibleCloudInstances, cam.Orig);
// reshade the clouds if necessary.
if (_bReshadeClouds)
{
printf("ReShading clouds\n");
FAIL_RETURN(ShadeClouds());
}
// Now process the visible clouds. First, go through the container clouds corresponding to the
// clouds, calculate their split points, and update their impostors.
for (CloudInstanceIterator cii = _visibleCloudInstances.begin();
cii != _visibleCloudInstances.end();
++cii)
{
// get the container corresponding to this cloud
ContainerSetIterator csi = _containerClouds.find((*cii)->GetID());
if (csi == _containerClouds.end())
{
SkyTrace("Error: SkySceneManager::_ResolveVisibility(): Invalid cloud instance %d.",
(*cii)->GetID());
return SKYRESULT_FAIL;
}
if (csi->second->containedOpaqueInstances.size() > 0 ||
csi->second->containedTransparentInstances.size() > 0)
{
SortInstances(csi->second->containedOpaqueInstances, cam.Orig);
SortInstances(csi->second->containedTransparentInstances, cam.Orig);
SkyRenderableInstance *pOpaque = (csi->second->containedOpaqueInstances.size() > 0) ?
csi->second->containedOpaqueInstances.back() : NULL;
SkyRenderableInstance *pTransparent = (csi->second->containedTransparentInstances.size() > 0) ?
csi->second->containedTransparentInstances.back() : NULL;
// find the closest contained instance to the camera
if (pOpaque && pTransparent)
{
if (*pOpaque < *pTransparent)
(*cii)->SetSplitPoint(pOpaque->GetPosition());
else
(*cii)->SetSplitPoint(pTransparent->GetPosition());
}
else if (pOpaque)
(*cii)->SetSplitPoint(pOpaque->GetPosition());
else if (pTransparent)
(*cii)->SetSplitPoint(pTransparent->GetPosition());
else
(*cii)->SetSplit(false);
}
else
(*cii)->SetSplit(false);
// add the container to the list of visiblie clouds to be rendered this frame.
_visibleInstances.push_back(csi->second);
// now update the impostors
FAIL_RETURN_MSG((*cii)->Update(cam),
"SkySceneManager::_ResolveVisibility(): cloud instance update failed.");
}
SortInstances(_visibleInstances, cam.Orig);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::_TestInsertInstanceIntoClouds
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::_TestInsertInstanceIntoClouds(const Camera &cam, const CloudBVTree::Node *pNode, SkyRenderableInstance *pInstanceToInsert, bool bTransparent)
* @brief @todo <WRITE BRIEF SkySceneManager::_TestInsertInstanceIntoClouds DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::_TestInsertInstanceIntoClouds FUNCTION DOCUMENTATION>
*/
bool SkySceneManager::_TestInsertInstanceIntoClouds(const Camera &cam,
const CloudBVTree::Node *pNode,
SkyRenderableInstance *pInstanceToInsert,
bool bTransparent)
{
if (_clouds.size() <= 0)
return false;
if (pNode->GetNodeBV().PointInBBox(pInstanceToInsert->GetPosition()))
{
if (pNode->IsLeaf())
{
SkyMinMaxBox bbox;
int i;
// check the instance against each cloud in this leaf node.
for (i = 0; i < pNode->GetNumObjs(); ++i)
{
SkyRenderableInstanceCloud* pCloud =
const_cast<SkyRenderableInstanceCloud*>(pNode->GetObj(i));
bbox = pCloud->GetWorldSpaceBounds();
if (bbox.PointInBBox(pInstanceToInsert->GetPosition()))
{
// get the container cloud struct for this cloud instance, and add this instance.
ContainerSetIterator csi = _containerClouds.find(pCloud->GetID());
if (csi == _containerClouds.end())
{
SkyTrace(
"Error: SkySceneManager::_TestInsertInstanceIntoClouds(): Invalid cloud instance %d.",
pCloud->GetID());
return false;
}
else // this instance is inside a cloud. Set up for split cloud rendering.
{
if (!bTransparent)
csi->second->containedOpaqueInstances.push_back(pInstanceToInsert);
else
csi->second->containedTransparentInstances.push_back(pInstanceToInsert);
csi->second->pCloud->SetSplit(true);
return true;
}
}
}
return false;
}
else
{
if (!_TestInsertInstanceIntoClouds(cam, pNode->GetLeftChild(), pInstanceToInsert, bTransparent))
return _TestInsertInstanceIntoClouds(cam, pNode->GetRightChild(), pInstanceToInsert, bTransparent);
else
return true;
}
}
else
return false;
}

View File

@@ -1,189 +0,0 @@
//------------------------------------------------------------------------------
// File : SkySceneManager.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkySceneManager.hpp
*
* The SkySceneManager class manages all of the renderable objects and
* instances. This class maintains lists of each object and instance.
* The scene manager decides what to display, it can make use of various
* techniques such as view frustum culling, material grouping, etc.
*/
#ifndef __SKYSCENEMANAGER_HPP__
#define __SKYSCENEMANAGER_HPP__
// warning for truncation of template name for browse info
#pragma warning( disable : 4786)
#include "vec3f.hpp"
#include <vector>
#include <map>
#include "SkyUtil.hpp"
#include "SkySingleton.hpp"
#include "SkyRenderableInstance.hpp"
#include "SkyMaterial.hpp"
#include "SkyAABBTree.hpp"
#include "SkyRenderableInstanceCloud.hpp"
// forward to reduce unnecessary dependencies
class Camera;
class SkyRenderable;
class SkyRenderableInstance;
class SkyMaterial;
class SkyLight;
class SkyCloud;
//class SkyHeavens;
//class SkyHeightField;
//------------------------------------------------------------------------------
/**
* @class SkySceneManager
* @brief Manages all of the renderable objects and instances.
*/
class SkySceneManager; // Forward declaration
//! A singleton of the SkySceneManager. Can only create the SceneManager with SceneManager::Instantiate();
typedef SkySingleton<SkySceneManager> SceneManager;
class SkySceneManager
{
public:
SKYRESULT AddObject( SkyRenderable *pObject);
SKYRESULT AddInstance( SkyRenderableInstance *pInstance, bool bTransparent = false);
SKYRESULT AddCloud( SkyCloud *pCloud);
SKYRESULT AddCloudInstance(SkyRenderableInstanceCloud *pInstance);
SKYRESULT AddMaterial( SkyMaterial *pMaterial);
SkyMaterial* GetMaterial( int iMaterialID);
SKYRESULT ActivateMaterial(int iMaterialID);
SKYRESULT AddLight( SkyLight *pLight);
SkyLight* GetLight( int iLightID);
//! Set the sky box for this scene.
// void SetSkyBox( SkyHeavens *pSkyBox) { _pSkyBox = pSkyBox; }
//! Set the terrain for this scene.
//void SetTerrain( SkyHeightField *pTerrain) { _pTerrain = pTerrain; }
//! Enable wireframe display of lights (for debugging).
void EnableDrawLights(bool bEnable) { _bDrawLights = bEnable; }
//! Enable wireframe display of bounding volume tree of clouds.
void EnableDrawBVTree(bool bEnable) { _bDrawTree = bEnable; }
//! Returns true if wireframe display of lights is enabled.
bool IsDrawLightsEnabled() const { return _bDrawLights; }
//! Returns true if wireframe display of the cloud bounding volume tree is enabled.
bool IsDrawBVTreeEnabled() const { return _bDrawTree; }
SKYRESULT Update( const Camera &cam);
SKYRESULT Display( const Camera &cam);
SKYRESULT RebuildCloudBVTree();
SKYRESULT ShadeClouds();
//! Force the illumination of all clouds to be recomputed in the next update.
void ForceReshadeClouds() { _bReshadeClouds = true; }
// sort instances in @a instances from back to front.
static void SortInstances(InstanceArray& instances, const Vec3f& vecSortPoint);
// load a set of clouds from an archive file.
SKYRESULT LoadClouds(unsigned char *data, unsigned int size, float rScale = 1.0f, double latitude=0.0, double longitude=0.0);
SKYRESULT LoadClouds(SkyArchive& cloudArchive, float rScale = 1.0f, double latitude=0.0, double longitude=0.0);
protected: // datatypes
// Typedef the vectors into cleaner names
typedef std::vector<SkyRenderable*> ObjectArray;
typedef std::map<int, SkyMaterial*> MaterialSet;
typedef std::map<int, SkyLight*> LightSet;
typedef std::vector<SkyRenderableInstanceCloud*> CloudInstanceArray;
typedef std::vector<SkyCloud*> CloudArray;
typedef std::map<int, SkyContainerCloud*> ContainerCloudSet;
typedef SkyAABBTree<SkyRenderableInstanceCloud*> CloudBVTree;
typedef ObjectArray::iterator ObjectIterator;
typedef CloudArray::iterator CloudIterator;
typedef CloudInstanceArray::iterator CloudInstanceIterator;
typedef MaterialSet::iterator MaterialIterator;
typedef LightSet::iterator LightIterator;
typedef ContainerCloudSet::iterator ContainerSetIterator;
class InstanceComparator
{
public:
bool operator()(SkyRenderableInstance* pA, SkyRenderableInstance *pB)
{
return ((*pA) < (*pB));
}
};
class ContainerComparator
{
public:
bool operator()(SkyContainerCloud* pA, SkyContainerCloud *pB)
{
return ((*pA) < (*pB));
}
};
protected: // methods
SkySceneManager();
~SkySceneManager();
void _SortClouds(CloudInstanceArray& clouds, const Vec3f& vecSortPoint);
void _ViewFrustumCullClouds(const Camera& cam, const CloudBVTree::Node *pNode);
void _VisualizeCloudBVTree(const Camera& cam, const CloudBVTree::Node *pNode);
SKYRESULT _ResolveVisibility(const Camera &cam);
bool _TestInsertInstanceIntoClouds(const Camera &cam,
const CloudBVTree::Node *pNode,
SkyRenderableInstance *pInstanceToInsert,
bool bTransparent);
private: // data
ObjectArray _objects;
CloudArray _clouds;
InstanceArray _instances;
InstanceArray _transparentInstances;
InstanceArray _visibleInstances; //! @TODO: change this to "_freeInstances"
CloudInstanceArray _cloudInstances;
CloudInstanceArray _visibleCloudInstances;
ContainerCloudSet _containerClouds;
MaterialSet _materials;
LightSet _lights;
SkyMaterial _wireframeMaterial; // used for rendering the wireframes for debugging
SkyMaterial _clearMaterial; // used to maintain state consistency when clearing.
CloudBVTree _cloudBVTree;
//SkyHeavens *_pSkyBox;
//SkyHeightField *_pTerrain;
bool _bDrawLights;
bool _bDrawTree;
bool _bReshadeClouds;
};
#endif //__SKYSCENEMANAGER_HPP__

View File

@@ -1,292 +0,0 @@
//------------------------------------------------------------------------------
// File : SkySingleton.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkySingleton.hpp
*
* A generic singleton template wrapper to make classes into singletons
*/
#ifndef __SKYSINGLETON_HPP__
#define __SKYSINGLETON_HPP__
#include "SkyUtil.hpp"
#include <assert.h>
#include <stdlib.h>
//------------------------------------------------------------------------------
/**
* @class SkySingleton
* @brief A singleton template class.
*
* Usage : Use this template container class to make any class into a
* singleton. I usually do this:
*
* @code
* class MyClass
* {
* public:
* // normal class stuff, but don't put ctor/dtor here.
* int GetData() { return _someData; }
* protected:
* // Make the ctor(s)/dtor protected, so this can only be
* // instantiated as a singleton. Note: singleton will still
* // work on classes that do not follow this (public ctors)
* // but violation of the singleton is possible then, since non-
* // singleton versions of the class can be instantiated.
* MyClass() : _someData(5) {}
* MyClass(int arg) : _someData(arg) {} // etc...
* // don't implement the copy constructor, because singletons
* // shouldn't be copied!
* MyClass(const MyClass& mc) {}
* ~MyClass() {}
* private:
* int _someData;
* };
*
* // now create a singleton of MyClass
* typedef SkySingleton<MyClass> MyClassSingleton;
*
* @endcode
* Later, in your program code, you can instantiate the singleton and access
* its members like so:
*
* @code
* void somefunc()
* {
* // instantiate the MyClassSingleton
* MyClassSingleton::Instantiate();
* // could also call MyClassSingleton::Instantiate(10);
* // since we have a constructor of that form in MyClass.
*
* // access the methods in MyClass:
* int data1 = MyClassSingleton::InstancePtr()->GetData();
* // or...
* int data2 = MyClassSingleton::InstanceRef().GetData();
*
* // now destroy the singleton
* MyClassSingleton::Destroy();
* }
* @endcode
*/
template <class T>
class SkySingleton : protected T
{
public:
//------------------------------------------------------------------------------
// Function : Instantiate
// Description :
//------------------------------------------------------------------------------
/**
* @fn Instantiate()
* @brief Creates the singleton instance for class T.
*
* Assures (by assertion) that the instance will only be created once.
* This works for default constructors.
*/
static void Instantiate()
{
assert(!s_pInstance);
s_pInstance = new SkySingleton();
}
//------------------------------------------------------------------------------
// Function : Destroy
// Description :
//------------------------------------------------------------------------------
/**
* @fn Destroy() { SAFE_DELETE(s_pInstance); }
* @brief Destructor, deletes the instance
*/
static void Destroy() { SAFE_DELETE(s_pInstance); }
//------------------------------------------------------------------------------
// Function : InstancePtr
// Description :
//------------------------------------------------------------------------------
/**
* @fn InstancePtr() { assert(s_pInstance); return s_pInstance; }
* @brief Returns a pointer to the instance
*/
static T* InstancePtr() { assert(s_pInstance); return s_pInstance; }
//------------------------------------------------------------------------------
// Function : InstanceRef
// Description :
//------------------------------------------------------------------------------
/**
* @fn InstanceRef() { assert(s_pInstance); return *s_pInstance; }
* @brief Returns a reference to the instance
*/
static T& InstanceRef() { assert(s_pInstance); return *s_pInstance; }
//------------------------------------------------------------------------------
// Function : static void Instantiate
// Description :
//------------------------------------------------------------------------------
/**
* @fn static void Instantiate(const A& a)
* @brief Instantiates class of type T that have constructors with an argument
*
* This might be a source of confusion. These templatized
* functions are used to instantiate classes of type T that
* have constructors with arguments. For n arguments, you
* to add a function below with n arguments. Note, these will
* only be created if they are used, since they are templates.
* I've added 4 below, for 1-4 arguments. If you get a
* compilation error, add one for the number of arguments you
* need. Also need a SkySingleton protected constructor with
* the same number of arguments.
*/
template<class A>
static void Instantiate(const A& a)
{
assert(!s_pInstance);
s_pInstance = new SkySingleton(a);
}
//------------------------------------------------------------------------------
// Function : Instantiate
// Description :
//------------------------------------------------------------------------------
/**
* @fn Instantiate(const A& a, const B& b)
* @brief Instantiates class of type T that have constructors with 2 args
*/
template<class A, class B>
static void Instantiate(const A& a, const B& b)
{
assert(!s_pInstance);
s_pInstance = new SkySingleton(a, b);
}
//------------------------------------------------------------------------------
// Function : Instantiate
// Description :
//------------------------------------------------------------------------------
/**
* @fn Instantiate(const A& a, const B& b, const C& c)
* @brief Instantiates class of type T that have constructors with 3 args
*/
template<class A, class B, class C>
static void Instantiate(const A& a, const B& b, const C& c)
{
assert(!s_pInstance);
s_pInstance = new SkySingleton(a, b, c);
}
//------------------------------------------------------------------------------
// Function : Instantiate
// Description :
//------------------------------------------------------------------------------
/**
* @fn Instantiate(const A& a, const B& b, const C& c, const D& d)
* @brief Instantiates class of type T that have constructors with 4 args
*/
template<class A, class B, class C, class D>
static void Instantiate(const A& a, const B& b, const C& c, const D& d)
{
assert(!s_pInstance);
s_pInstance = new SkySingleton(a, b, c, d);
}
protected:
// although the instance is of type SkySingleton<T>, the Instance***() funcs
// above implicitly cast it to type T.
static SkySingleton* s_pInstance;
private:
//------------------------------------------------------------------------------
// Function : SkySingleton
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySingleton()
* @brief Hidden so that the singleton can only be instantiated via public static Instantiate function.
*/
SkySingleton() : T() {}
//------------------------------------------------------------------------------
// Function : Singleton
// Description :
//------------------------------------------------------------------------------
/**
* @fn Singleton(const A& a)
* @brief Used by the templatized public Instantiate() functions.
*/
template<class A>
SkySingleton(const A& a) : T(a) {}
//------------------------------------------------------------------------------
// Function : Singleton
// Description :
//------------------------------------------------------------------------------
/**
* @fn Singleton(const A& a, const B& b)
* @brief Used by the templatized public Instantiate() functions.
*/
template<class A, class B>
SkySingleton(const A& a, const B& b) : T(a, b) {}
//------------------------------------------------------------------------------
// Function : Singleton
// Description :
//------------------------------------------------------------------------------
/**
* @fn Singleton(const A& a, const B& b, const C& c)
* @brief Used by the templatized public Instantiate() functions.
*/
template<class A, class B, class C>
SkySingleton(const A& a, const B& b, const C& c) : T(a, b, c) {}
//------------------------------------------------------------------------------
// Function : Singleton
// Description :
//------------------------------------------------------------------------------
/**
* @fn Singleton(const A& a, const B& b, const C &c, const D& d)
* @brief Used by the templatized public Instantiate() functions.
*/
template<class A, class B, class C, class D>
SkySingleton(const A& a, const B& b, const C &c, const D& d) : T(a, b, c, d) {}
//------------------------------------------------------------------------------
// Function : SkySingleton
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySingleton(const SkySingleton&)
* @brief Hidden because you can't copy a singleton!
*/
SkySingleton(const SkySingleton&) {} // hide the copy ctor: singletons can'
//------------------------------------------------------------------------------
// Function : ~SkySingleton
// Description :
//------------------------------------------------------------------------------
/**
* @fn ~SkySingleton()
* @brief Destructor, hidden, destroy via the public static Destroy() method.
*/
~SkySingleton() {} // hide the dtor:
};
// declare the static instance pointer
template<class T> SkySingleton<T>* SkySingleton<T>::s_pInstance = NULL;
#endif //__SKYSINGLETON_HPP__

View File

@@ -1,111 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyTexture.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyTexture.hpp
*
* Interface definition for class SkyTexture, a texture class.
*/
#ifndef __SKYTEXTURE_HPP__
#define __SKYTEXTURE_HPP__
// #pragma warning( disable : 4786 )
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include SG_GL_H
#define __glext_h_
#define __GLEXT_H_
#define __glext_h_
#define __GLEXT_H_
//------------------------------------------------------------------------------
/**
* @class SkyTexture
* @brief A basic texture class.
*
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
*/
class SkyTexture
{
public:
//! Default Constructor.
SkyTexture() : _iID(0), _iWidth(0), _iHeight(0) {}
//! Constructor.
SkyTexture(unsigned int iWidth, unsigned int iHeight, unsigned int iTextureID)
: _iID(iTextureID), _iWidth(iWidth), _iHeight(iHeight) {}
//! Destructor.
~SkyTexture() {}
//! Sets the texture width in texels.
void SetWidth(unsigned int iWidth) { _iWidth = iWidth; }
//! Sets the texture height in texels.
void SetHeight(unsigned int iHeight) { _iHeight = iHeight; }
//! Sets the texture ID as created by OpenGL.
void SetID(unsigned int iTextureID) { _iID = iTextureID; }
//! Returns the texture width in texels.
unsigned int GetWidth() const { return _iWidth; }
//! Returns the texture height in texels.
unsigned int GetHeight() const { return _iHeight; }
//! Returns the texture ID as created by OpenGL.
unsigned int GetID() const { return _iID; }
inline SKYRESULT Destroy();
protected:
unsigned int _iID;
unsigned int _iWidth;
unsigned int _iHeight;
};
//------------------------------------------------------------------------------
// Function : SkyTexture::Destroy
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTexture::Destroy()
* @brief Destroys the OpenGL texture object represented by this SkyTexture object.
*
* Fails if the GL texture has not been created (i.e. its ID is zero).
*/
inline SKYRESULT SkyTexture::Destroy()
{
if (0 == _iID)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL,
"SkyTexture::Destroy(): Error: attempt to destroy unallocated texture.");
}
else
{
glDeleteTextures(1, &_iID);
_iID = 0;
}
return SKYRESULT_OK;
}
#endif //__SKYTEXTURE_HPP__

View File

@@ -1,895 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyTextureManager.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyTextureManager.cpp
*
* Implementation of a manager that keeps track of texture resource locations and sharing.
*/
#pragma warning( disable : 4786)
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include SG_GLU_H
#include "SkyTextureManager.hpp"
#include "SkyContext.hpp"
//#include "glvu.hpp"
//#include "ppm.hpp"
//#include "tga.hpp"
//#include "fileutils.hpp"
bool SkyTextureManager::s_bSlice3DTextures = false;
//------------------------------------------------------------------------------
// Function : SkyTextureManager::SkyTextureManager
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::SkyTextureManager(bool bSlice3DTextures)
* @brief Constructor.
*
*/
SkyTextureManager::SkyTextureManager(bool bSlice3DTextures /* = false */)
{
s_bSlice3DTextures = bSlice3DTextures;
// this should be put somewhere more safe -- like done once in the functions that actually
// use these extensions.
/*GraphicsContext::InstancePtr()->InitializeExtensions("GL_ARB_texture_cube_map "
"GL_VERSION_1_2");*/
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::~SkyTextureManager
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::~SkyTextureManager()
* @brief destructor.
*
* @todo <WRITE EXTENDED SkyTextureManager::~SkyTextureManager FUNCTION DOCUMENTATION>
*/
SkyTextureManager::~SkyTextureManager()
{
_texturePaths.clear();
for ( TextureIterator iter = _textures.begin();
iter != _textures.end();
++iter)
{
DestroyTextureObject(iter->second);
}
_textures.clear();
for ( TextureList::iterator uncachedIter = _uncachedTextures.begin();
uncachedIter != _uncachedTextures.end();
++uncachedIter)
{
DestroyTextureObject(*uncachedIter);
}
_uncachedTextures.clear();
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::AddPath
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::AddPath(const string &path)
* @brief Adds a texture path to the list of active search paths.
*
*/
void SkyTextureManager::AddPath(const string &path)
{
_texturePaths.push_back(path);
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Get2DTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Get2DTexture(const string& filename, SkyTexture& texture, bool bMipmap)
* @brief Returns a 2D texture object from the texture set.
*
* If the texture is already loaded, it is returned. If it is not, the texture is loaded from
* file, added to the texture set, and returned.
*
* If the image cannot be loaded, returns an error. Otherwise returns success.
*/
SKYRESULT SkyTextureManager::Get2DTexture(const string& filename,
SkyTexture& texture,
bool bMipmap /* = false */)
{
TextureIterator iter = _textures.find(filename);
if (iter != _textures.end())
{ // the texture is already loaded, just return it.
texture = iter->second;
}
else
{ // the texture is being requested for the first time, load and return it
FAIL_RETURN(Clone2DTexture(filename, texture, bMipmap));
_textures.insert(make_pair(filename, texture));
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Get3DTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Get3DTexture(const string& filename, SkyTexture& texture, unsigned int iDepth, bool bMipmap, bool bLoadFromSliceFiles)
* @brief Returns a 3D texture object from the texture set.
*
* If the texture is already loaded, it is returned. If it is not, the texture is loaded from
* file, added to the texture set, and returned. If the image cannot be loaded, returns an error.
* Otherwise returns success.
*
* For 3D textures, this simply loads a 2D image file, and duplicates it across each slice. The
* parameter iDepth must be set in order to use a 2D texture image for a 3D texture.
*/
SKYRESULT SkyTextureManager::Get3DTexture(const string& filename,
SkyTexture& texture,
unsigned int iDepth,
bool bMipmap /* = false */,
bool bLoadFromSliceFiles /* = false */)
{
TextureIterator iter = _textures.find(filename);
if (iter != _textures.end())
{ // the texture is already loaded, just return it.
texture = iter->second;
}
else
{ // the texture is being requested for the first time, load and return it
FAIL_RETURN(Clone3DTexture(filename, texture, iDepth, bMipmap, bLoadFromSliceFiles));
_textures.insert(make_pair(filename, texture));
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : roundPowerOf2
// Description :
//------------------------------------------------------------------------------
static int roundPowerOf2(int n)
{
int m;
for (m = 1; m < n; m *= 2);
// m >= n
if (m - n <= n - m/2)
return m;
else
return m/2;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Clone2DTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Clone2DTexture( const string &filename, SkyTexture& texture, bool bMipmap)
* @brief Returns a 2D texture object.
*
* Ignores texture set. This always loads the file, if it exists, and creates and returns the texture.
*
* If the image cannot be loaded, returns an error. Otherwise returns success.
*/
SKYRESULT SkyTextureManager::Clone2DTexture(const string &filename,
SkyTexture& texture,
bool bMipmap /* = false */)
{
string pathFilename;
unsigned char *pImageData = NULL;
int iWidth = 0;
int iHeight = 0;
int iChannels = 0;
enum ImageType
{
IMAGE_PPM,
IMAGE_TGA
};
ImageType eType;
/****
// first get the image type from its extension.
if (filename.find(".tga") != string.npos || filename.find(".TGA") != string.npos)
eType = IMAGE_TGA;
else if (filename.find(".ppm") != string.npos || filename.find(".PPM") != string.npos)
eType = IMAGE_PPM;
else
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyTextureManager error: invalid image format");
****/
// first try the filename sent in in case it includes a path.
//if (FileUtils::FileExists(filename.c_str()))
//{
// printf("Filename is %s\n", filename.c_str() );
//eType = IMAGE_TGA;
/* switch (eType)
{
case IMAGE_PPM:
LoadPPM(filename.c_str(), pImageData, iWidth, iHeight);
iChannels = 3;
break;
case IMAGE_TGA:
LoadTGA(filename.c_str(), pImageData, iWidth, iHeight, iChannels);
break;
default:
break;
}*/
//}
if (!pImageData) // image not found in current directory. Check the paths...
{
for ( StringList::iterator iter = _texturePaths.begin();
iter != _texturePaths.end();
++iter)
{ // loop over all texture paths, looking for the filename
// get just the filename without path.
int iPos = filename.find_last_of("/");
if (iPos == filename.npos)
iPos = filename.find_last_of("/");
// tack on the paths from the texture path list.
if (iPos != filename.npos)
pathFilename = (*iter) + "/" + filename.substr(iPos+1);
else
pathFilename = (*iter) + "/" + filename;
//if (FileUtils::FileExists(pathFilename.c_str()))
//{
/* switch (eType)
{
case IMAGE_PPM:
LoadPPM(pathFilename.c_str(), pImageData, iWidth, iHeight);
break;
case IMAGE_TGA:
LoadTGA(pathFilename.c_str(), pImageData, iWidth, iHeight, iChannels);
break;
default:
break;
}*/
//if (pImageData)
//break;
//}
}
}
if (!pImageData)
{
char buffer[256];
sprintf(buffer, "SkyTextureManager::Clone2DTexture(): Could not load image. %s.\n", filename.c_str());
FAIL_RETURN_MSG(SKYRESULT_OK, buffer);
}
// make sure it is power of 2 resolution.
int iNewWidth = roundPowerOf2(iWidth);
int iNewHeight = roundPowerOf2(iHeight);
int iMaxsize;
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &iMaxsize );
if (iNewWidth > iMaxsize)
{
iNewWidth = iMaxsize;
}
if (iNewHeight> iMaxsize)
{
iNewHeight = iMaxsize;
}
GLenum eFormat = (4 == iChannels) ? GL_RGBA : GL_RGB;
if (iNewWidth != iWidth || iNewHeight != iHeight)
{
unsigned char *pScaledImageData = new unsigned char[iChannels * iNewWidth * iNewHeight];
gluScaleImage(eFormat, iWidth, iHeight, GL_UNSIGNED_BYTE, pImageData,
iNewWidth, iNewHeight, GL_UNSIGNED_BYTE, pScaledImageData);
SAFE_DELETE_ARRAY(pImageData);
pImageData = pScaledImageData;
}
_Create2DTextureObject( texture, iNewWidth, iNewHeight, eFormat, pImageData);
SAFE_DELETE_ARRAY(pImageData);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Clone3DTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Clone3DTexture( const string &filename, SkyTexture& texture, unsigned int iDepth, bool bMipmap, bool bLoadFromSliceFiles)
* @brief Returns a 3D texture object.
*
* Ignores texture set. This always loads the file, if it exists, and creates and returns the texture.
* If the image cannot be loaded, returns an error. Otherwise returns success.
*/
SKYRESULT SkyTextureManager::Clone3DTexture(const string &filename,
SkyTexture& texture,
unsigned int iDepth,
bool bMipmap /* = false */,
bool bLoadFromSliceFiles /* = false */)
{
string pathFilename;
/*QImage image;
QDir dir;
unsigned char *pBits = NULL;
if (!bLoadFromSliceFiles)
{
// first try the filename sent in in case it includes a path.
if (image.load(filename))
{
image = QGLWidget::convertToGLFormat(image);
}
else
{
image.reset();
for ( QStringList::Iterator iter = _texturePaths.begin();
iter != _texturePaths.end();
iter++)
{ // loop over all texture paths, looking for the filename
pathFilename = (*iter) + "\\" + filename;
if (image.load(pathFilename))
{
image = QGLWidget::convertToGLFormat(image);
break;
}
else
image.reset();
}
}
if (image.isNull())
{
qWarning("SkyTextureManager::GetTexture(): Could not load image "
"%s.\n", filename);
return false;
}
// make sure it is power of 2 resolutions.
int iWidth = roundPowerOf2(image.width());
int iHeight = roundPowerOf2(image.height());
int iMaxsize;
if (s_bSlice3DTextures)
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &iMaxsize );
else
glGetIntegerv( GL_MAX_3D_TEXTURE_SIZE, &iMaxsize );
if (iWidth > iMaxsize)
{
iWidth = iMaxsize;
}
if (iHeight> iMaxsize)
{
iHeight = iMaxsize;
}
if (iWidth != image.width() || iHeight != image.height())
image = image.smoothScale(iWidth, iHeight);
// first build an array of repeated 2D textures...
QImage inverted(image.mirror());
pBits = new unsigned char[image.numBytes() * iDepth];
unsigned int iSliceSize = image.numBytes();
int bInverted = false;
int iInvertedCount = 8;
for (unsigned int iSlice = 0; iSlice < iDepth; ++iSlice)
{
memcpy(&(pBits[iSlice * iSliceSize]),
(bInverted) ? inverted.bits() : image.bits(),
image.numBytes());
if (--iInvertedCount <= 0)
{
iInvertedCount = 8;
bInverted = !bInverted;
}
}
}
else /// Load from a set of files matching the file pattern
{
QFileInfo fi(filename);
fi.refresh();
QString baseFilename = fi.baseName();
int truncPos = baseFilename.find(QRegExp("[0-9]"));
if (truncPos >= 0)
baseFilename.truncate(truncPos);
dir.setFilter(QDir::Files);
dir.setNameFilter(baseFilename + "*." + fi.extension());
dir.setSorting(QDir::Name);
QStringList files = dir.entryList();
bool bFound = true;
if (files.count() < iDepth)
{
bFound = false;
for ( QStringList::Iterator iter = _texturePaths.begin();
iter != _texturePaths.end();
iter++)
{
dir.setCurrent(*iter);
files = dir.entryList();
if (files.count() >= iDepth)
{
bFound = true;
break;
}
}
}
if (!bFound)
{
qWarning("SkyTextureManager::Clone3DTexture: ERROR: could not find %d files matching "
"%s", iDepth, filename.latin1());
return false;
}
else
{
unsigned int iSlice = 0;
unsigned int iSliceSize = 0;
for ( QStringList::Iterator iter = files.begin();
iter != files.end() && iSlice < iDepth;
iter++)
{
if (image.load(*iter))
{
image = QGLWidget::convertToGLFormat(image);
// make sure it is power of 2 resolution.
int iWidth = roundPowerOf2(image.width());
int iHeight = roundPowerOf2(image.height());
int iMaxsize;
if (s_bSlice3DTextures)
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &iMaxsize );
else
glGetIntegerv( GL_MAX_3D_TEXTURE_SIZE, &iMaxsize );
if (iWidth > iMaxsize)
{
iWidth = iMaxsize;
}
if (iHeight> iMaxsize)
{
iHeight = iMaxsize;
}
if (iWidth != image.width() || iHeight != image.height())
image = image.smoothScale(iWidth, iHeight);
if (0 == iSlice)
{
pBits = new unsigned char[image.numBytes() * iDepth];
iSliceSize = image.numBytes();
}
memcpy(&(pBits[iSlice * iSliceSize]), image.bits(), image.numBytes());
++iSlice;
}
else
{
qWarning("SkyTextureManager::Clone3DTexture: ERROR: could not find %d files matching "
"%s", iDepth, filename);
return false;
}
}
}
}
_Create3DTextureObject(texture,
image.width(),
image.height(),
iDepth,
GL_RGBA,
pBits);
*/
return SKYRESULT_FAIL;
}
//!
/*! */
//------------------------------------------------------------------------------
// Function : SkyTextureManager::GetCubeMapTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::GetCubeMapTexture(const string& filename, SkyTexture& texture, bool bMipmap)
* @brief Returns a cube map texture object from the texture set
*
* If the texture is already loaded, it is returned. If it is not, the texture is loaded from file,
* added to the texture set, and returned. If any of the 6 images cannot be loaded, returns an error.
* Otherwise returns success.
*/
SKYRESULT SkyTextureManager::GetCubeMapTexture( const string& filename,
SkyTexture& texture,
bool bMipmap)
{
TextureIterator iter = _textures.find(filename);
if (iter != _textures.end())
{ // the texture is already loaded, just return it.
texture = iter->second;
}
else
{ // the texture is being requested for the first time, load and return it
if (!CloneCubeMapTexture(filename, texture, bMipmap))
return false;
_textures.insert(make_pair(filename, texture));
}
return true;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::CloneCubeMapTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::CloneCubeMapTexture(const string& filename, SkyTexture& texture, bool bMipmap)
* @brief Returns a cube map texture object.
*
* Ignores the texture set. This always loads the cube map texture, if all 6 face images exist,
* creates the texture, and returns it. If any of the 6 images cannot be loaded, returns an error.
* Otherwise returns success.
*/
SKYRESULT SkyTextureManager::CloneCubeMapTexture( const string& filename,
SkyTexture& texture,
bool bMipmap)
{
string pathFilename;
/*QImage images[6];
GLenum faces [] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB };
char* faceNames[] = {"posx", "negx", "posy", "negy", "posz", "negz" };
for ( QStringList::Iterator iter = _texturePaths.begin();
iter != _texturePaths.end();
iter++)
{ // loop over all texture paths, looking for the filename
for (int i = 0; i < 6; i++)
{
char buffer[FILENAME_MAX];
sprintf(buffer, filename.ascii(), faceNames[i]);
pathFilename = (*iter) + "\\" + buffer;
if (images[i].load(pathFilename))
{
images[i] = QGLWidget::convertToGLFormat(images[i]);
}
else
images[i].reset();
}
}
for (int i = 0; i < 6; i++)
{
if (images[i].isNull())
{
char buffer[FILENAME_MAX];
sprintf(buffer, filename.ascii(), faceNames[i]);
qWarning("SkyTextureManager::GetTexture(): Could not load image "
"%s.\n", buffer);
return false;
}
}
glGenTextures(1, &(texture.iTextureID));
texture.iWidth = images[0].width();
texture.iHeight = images[0].height();
// create and bind a cubemap texture object
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texture.iTextureID);
// enable automipmap generation if needed.
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_GENERATE_MIPMAP_SGIS, bMipmap);
if (bMipmap)
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
else
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
for (i = 0; i < 6; i++)
{
glTexImage2D(faces[i],
0,
GL_RGBA8,
images[i].width(),
images[i].height(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
images[i].bits());
}*/
return true;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::_Create2DTextureObject
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::_Create2DTextureObject(SkyTexture &texture, unsigned int iWidth, unsigned int iHeight, unsigned int iFormat, unsigned char *pData)
* @brief Creates a 2D texture.
*
* Creates an OpenGL texture object and returns its ID and dimensions in a SkyTexture structure.
*/
SKYRESULT SkyTextureManager::_Create2DTextureObject(SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iFormat,
unsigned char *pData)
{
bool bNew = false;
unsigned int iTextureID;
if (!texture.GetID())
{
glGenTextures(1, &iTextureID);
texture.SetID(iTextureID);
bNew = true;
}
texture.SetWidth(iWidth);
texture.SetHeight(iHeight);
glBindTexture(GL_TEXTURE_2D, texture.GetID());
if (bNew)
{
GLenum iInternalFormat;
switch (iFormat)
{
case GL_LUMINANCE:
iInternalFormat = GL_LUMINANCE;
break;
case GL_LUMINANCE_ALPHA:
iInternalFormat = GL_LUMINANCE_ALPHA;
break;
default:
iInternalFormat = GL_RGBA8;
break;
}
glTexImage2D( GL_TEXTURE_2D,
0,
iInternalFormat,
iWidth, iHeight,
0,
(GLenum) iFormat,
GL_UNSIGNED_BYTE,
pData);
}
else
{
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0,
iWidth, iHeight,
(GLenum) iFormat,
GL_UNSIGNED_BYTE,
pData);
}
// set default filtering.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::_Create3DTextureObject
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::_Create3DTextureObject(SkyTexture &texture, unsigned int iWidth, unsigned int iHeight, unsigned int iDepth, unsigned int iFormat, unsigned char *pData)
* @brief Creates a 3D texture
*
* Creates an OpenGL 3D texture object (or a set of 2D slices) and returns its ID and dimensions
* in a SkyTexture structure.
*/
SKYRESULT SkyTextureManager::_Create3DTextureObject(SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iDepth,
unsigned int iFormat,
unsigned char *pData)
{
/* bool bNew = false;
if (s_bSlice3DTextures) // create one 2D texture per slice!
{
if (!texture.pSliceIDs)
{
texture.pSliceIDs = new unsigned int[iDepth];
glGenTextures(iDepth, texture.pSliceIDs);
bNew = true;
}
}
else if (!texture.iTextureID)
{
glGenTextures(1, &(texture.iTextureID));
bNew = true;
}
texture.iWidth = iWidth;
texture.iHeight = iHeight;
texture.iDepth = iDepth;
texture.bSliced3D = s_bSlice3DTextures;
if (!s_bSlice3DTextures)
{
glBindTexture(GL_TEXTURE_3D, texture.iTextureID);
if (bNew)
{
unsigned int iInternalFormat;
switch (iFormat)
{
case GL_LUMINANCE:
iInternalFormat = GL_LUMINANCE;
break;
case GL_LUMINANCE_ALPHA:
iInternalFormat = GL_LUMINANCE_ALPHA;
break;
default:
iInternalFormat = GL_RGBA;
break;
}
glTexImage3D( GL_TEXTURE_3D,
0,
iInternalFormat,
iWidth, iHeight, iDepth,
0,
iFormat,
GL_UNSIGNED_BYTE,
pData);
}
else
{
glTexSubImage3D(GL_TEXTURE_3D,
0, 0, 0, 0,
iWidth, iHeight, iDepth,
iFormat,
GL_UNSIGNED_BYTE,
pData);
}
// set default filtering.
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
else
{
unsigned int iInternalFormat = 0;
unsigned int iBytesPerPixel = 0;
switch (iFormat)
{
case GL_LUMINANCE:
iInternalFormat = GL_LUMINANCE;
iBytesPerPixel = 1;
break;
case GL_LUMINANCE_ALPHA:
iInternalFormat = GL_LUMINANCE_ALPHA;
iBytesPerPixel = 2;
break;
case GL_RGBA:
default:
iInternalFormat = GL_RGBA;
iBytesPerPixel = 4;
break;
}
unsigned int iSliceSize = iWidth * iHeight * iBytesPerPixel;
// create iDepth 2D texture slices...
for (unsigned int iSlice = 0; iSlice < iDepth; ++iSlice)
{
glBindTexture(GL_TEXTURE_2D, texture.pSliceIDs[iSlice]);
if (bNew)
{
glTexImage2D( GL_TEXTURE_2D,
0,
iInternalFormat,
iWidth, iHeight,
0,
iFormat,
GL_UNSIGNED_BYTE,
(pData + iSlice * iSliceSize));
}
else
{
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0,
iWidth, iHeight,
iFormat,
GL_UNSIGNED_BYTE,
(pData + iSlice * iSliceSize));
}
// set default filtering.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
GLVU::CheckForGLError("SkyTextureManager::_Create3DTextureObject()");
return SKYRESULT_OK;*/
return SKYRESULT_FAIL;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::DestroyTextureObject
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::DestroyTextureObject(SkyTexture &texture)
* @brief destroys a SkyTexture object.
*
* Deletes the data as well as the OpenGL texture ID(s).
*/
void SkyTextureManager::DestroyTextureObject(SkyTexture &texture)
{ /*
if (texture.GetID)
glDeleteTextures(1, &(texture.iTextureID));
if (texture.bSliced3D && texture.pSliceIDs)
{
glDeleteTextures(texture.iDepth, texture.pSliceIDs);
delete [] texture.pSliceIDs;
} */
}

View File

@@ -1,208 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyTextureManager.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
/**
* @file SkyTextureManager.hpp
*
* Definition of a manager that keeps track of texture locations and sharing of texture files. |
*/
#ifndef SKYTEXTUREMANAGER_HPP
#define SKYTEXTUREMANAGER_HPP
// #pragma warning( disable : 4786)
#include "SkySingleton.hpp"
#include "SkyTexture.hpp"
#include <string>
#include <list>
#include <map>
using namespace std;
// forward declaration for singleton
class SkyTextureManager;
//! A singleton of the SkyTextureManager. Can only create the TextureManager with TextureManager::Instantiate();
typedef SkySingleton<SkyTextureManager> TextureManager;
//------------------------------------------------------------------------------
/**
* @class SkyTextureManager
* @brief A resource manager for textures.
*
* This manager allows textures to be shared. It keeps a mapping of
* filenames to texture objects, and makes it easy to use the same texture
* for multiple objects without the objects having to be aware of the
* sharing. Supports cube map textures, and 2D textures. Can also be used
* to "clone textures", which creates unmanaged texture objects from files
* that are not kept in the mapping, and thus are not shared.
*/
class SkyTextureManager
{
public: // types
typedef list<string> StringList;
public: // methods
//.-------------------------------------------------------------------------.
//| Paths to texture directories
//.-------------------------------------------------------------------------.
void AddPath(const string& path);
//! Return the list of texture paths that will be searched by Get2DTexture() and Get3DTexture().
const StringList& GetPaths() const { return _texturePaths; }
//! Clear the list of texture paths that will be searched by Get2DTexture() and Get3DTexture().
void ClearPaths() { _texturePaths.clear(); }
//.-------------------------------------------------------------------------.
//| Texture loading
//.-------------------------------------------------------------------------.
SKYRESULT Get2DTexture( const string &filename,
SkyTexture& texture,
bool bMipmap = false);
SKYRESULT Get3DTexture( const string &filename,
SkyTexture& texture,
unsigned int iDepth,
bool bMipmap = false,
bool bLoadFromSliceFiles = false);
SKYRESULT GetCubeMapTexture( const string &filename,
SkyTexture& texture,
bool bMipmap = false);
//.-------------------------------------------------------------------------.
//| Texture cloning: create a duplicate texture object: not added to set!
//.-------------------------------------------------------------------------.
SKYRESULT Clone2DTexture( const string &filename,
SkyTexture& texture,
bool bMipmap = false);
SKYRESULT Clone3DTexture( const string &filename,
SkyTexture& texture,
unsigned int iDepth,
bool bMipmap = false,
bool bLoadFromSliceFiles = false );
SKYRESULT CloneCubeMapTexture( const string &filename,
SkyTexture& texture,
bool bMipmap = false);
//.-------------------------------------------------------------------------.
//| Texture Object Creation: not added to the texture set (no filename!)
//.-------------------------------------------------------------------------.
inline SKYRESULT Create2DTextureObject(SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iFormat,
unsigned char *pData);
inline SKYRESULT Create3DTextureObject(SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iDepth,
unsigned int iFormat,
unsigned char *pData);
//.-------------------------------------------------------------------------.
//| Texture Object Destruction: use this because texture objects are structs
//| that use shallow copies!
//.-------------------------------------------------------------------------.
static void DestroyTextureObject( SkyTexture &texture);
protected:
SkyTextureManager(bool bSlice3DTextures = false);
~SkyTextureManager();
SKYRESULT _Create2DTextureObject( SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iFormat,
unsigned char *pData);
SKYRESULT _Create3DTextureObject( SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iDepth,
unsigned int iFormat,
unsigned char *pData);
private:
typedef list<SkyTexture> TextureList;
typedef map<string, SkyTexture> TextureSet;
typedef TextureSet::iterator TextureIterator;
//.-------------------------------------------------------------------------.
//| Data
//.-------------------------------------------------------------------------.
// paths searched for textures specified by filename.
StringList _texturePaths;
// cached textures
TextureSet _textures; // loaded textures
// textures created directly, not loaded from file and cached.
TextureList _uncachedTextures;
// if this is true, then 3D textures will be represented as a set of 2D slices.
static bool s_bSlice3DTextures;
};
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Create2DTextureObject
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Create2DTextureObject(SkyTexture &texture, unsigned int iWidth, unsigned int iHeight, unsigned int iFormat, unsigned char *pData)
* @brief Creates a 2D texture.
*
* Creates an OpenGL texture object and returns its ID and dimensions in a SkyTexture structure.
* This texture will be deleted by the texture manager at shutdown.
*
*/
inline SKYRESULT SkyTextureManager::Create2DTextureObject(SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iFormat,
unsigned char *pData)
{
SKYRESULT retval = _Create2DTextureObject(texture, iWidth, iHeight, iFormat, pData);
if SKYSUCCEEDED(retval)
_uncachedTextures.push_back(texture);
return retval;
}
//------------------------------------------------------------------------------
// Function : SkyTextureManager::Create3DTextureObject
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureManager::Create3DTextureObject(SkyTexture &texture, unsigned int iWidth, unsigned int iHeight, unsigned int iDepth, unsigned int iFormat, unsigned char *pData)
* @brief Creates a 3D texture.
*
* Creates an OpenGL texture object and returns its ID and dimensions in a SkyTexture structure.
* This texture will be deleted by the texture manager at shutdown, and should not be destroyed
* by the user.
*
*/
inline SKYRESULT SkyTextureManager::Create3DTextureObject(SkyTexture &texture,
unsigned int iWidth,
unsigned int iHeight,
unsigned int iDepth,
unsigned int iFormat,
unsigned char *pData)
{
SKYRESULT retval = _Create3DTextureObject(texture, iWidth, iHeight, iDepth, iFormat, pData);
if SKYSUCCEEDED(retval)
_uncachedTextures.push_back(texture);
return retval;
}
#endif //QGLVUTEXTUREMANAGER_HPP

View File

@@ -1,357 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyTextureState.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyTextureState.cpp
*
* Implementation of class SkyTextureState, which encapsulates OpenGL texture state.
*/
#include "SkyTextureState.hpp"
//#include "glvu.hpp"
#include <simgear/screen/extensions.hxx>
glActiveTextureProc glActiveTexturePtr = 0;
bool glActiveTextureIsSupported = false;
//------------------------------------------------------------------------------
// Static initializations.
//------------------------------------------------------------------------------
unsigned int SkyTextureState::s_iNumTextureUnits = 0;
//------------------------------------------------------------------------------
// Function : SkyTextureState::SkyTextureState
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::SkyTextureState()
* @brief Constructor.
*/
SkyTextureState::SkyTextureState()
{
if (0 == s_iNumTextureUnits)
{
int iNumTextureUnits = 0;
if (SGIsOpenGLExtensionSupported("GL_ARB_multitexture")) {
glActiveTextureIsSupported = true;
glActiveTexturePtr = (glActiveTextureProc)
SGLookupFunction("glActiveTextureARB");
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &iNumTextureUnits);
if (iNumTextureUnits > 0)
s_iNumTextureUnits = iNumTextureUnits;
else
s_iNumTextureUnits = 1;
} else
s_iNumTextureUnits = 1;
}
_pTextureUnitState = new TexState[s_iNumTextureUnits];
}
//------------------------------------------------------------------------------
// Function : SkyTextureState::~SkyTextureState
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::~SkyTextureState()
* @brief Destructor.
*/
SkyTextureState::~SkyTextureState()
{
SAFE_DELETE(_pTextureUnitState);
}
//------------------------------------------------------------------------------
// Function : SkyTextureState::Activate
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::Activate()
* @brief @todo <WRITE BRIEF SkyTextureState::Activate DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyTextureState::Activate FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyTextureState::Activate()
{
SkyTextureState *pCurrent = GraphicsContext::InstancePtr()->GetCurrentTextureState();
assert(NULL != pCurrent);
//GLVU::CheckForGLError("SkyTextureState::Activate(8)");
for (unsigned int i = 0; i < s_iNumTextureUnits; ++i)
{
if (glActiveTextureIsSupported && (s_iNumTextureUnits > 1))
glActiveTexturePtr(GL_TEXTURE0_ARB + i);
bool bEnabled = IsTextureEnabled(i);
if (pCurrent->IsTextureEnabled(i) != bEnabled)
{
FAIL_RETURN(pCurrent->EnableTexture(i, bEnabled));
//GLVU::CheckForGLError("SkyTextureState::Activate(7)");
if (bEnabled)
glEnable(GetActiveTarget(i));
else
glDisable(GetActiveTarget(i));
}
//GLVU::CheckForGLError("SkyTextureState::Activate(6)");
if (bEnabled)
{
GLenum eTarget = GetActiveTarget(i);
unsigned int iID = GetTextureID(i);
// if ((pCurrent->GetActiveTarget(i) != eTarget) ||
// (pCurrent->GetTextureID(i) != iID))
// {
FAIL_RETURN(pCurrent->SetTexture(i, eTarget, iID));
glBindTexture(eTarget, iID);
// }
//GLVU::CheckForGLError("SkyTextureState::Activate(5)");
GLenum paramValue = GetTextureParameter(i, GL_TEXTURE_WRAP_S);
if (pCurrent->GetTextureParameter(i, GL_TEXTURE_WRAP_S) != paramValue)
{
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_WRAP_S, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_WRAP_S, paramValue);
}
//GLVU::CheckForGLError("SkyTextureState::Activate(4)");
paramValue = GetTextureParameter(i, GL_TEXTURE_WRAP_T);
if (pCurrent->GetTextureParameter(i, GL_TEXTURE_WRAP_T) != paramValue)
{
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_WRAP_T, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_WRAP_T, paramValue);
}
//GLVU::CheckForGLError("SkyTextureState::Activate(3)");
paramValue = GetTextureParameter(i, GL_TEXTURE_WRAP_R);
if (pCurrent->GetTextureParameter(i, GL_TEXTURE_WRAP_R) != paramValue)
{
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_WRAP_R, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_WRAP_R, paramValue);
}
//GLVU::CheckForGLError("SkyTextureState::Activate(2)");
paramValue = GetTextureParameter(i, GL_TEXTURE_MIN_FILTER);
if (pCurrent->GetTextureParameter(i, GL_TEXTURE_MIN_FILTER) != paramValue)
{
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_MIN_FILTER, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, paramValue);
}
//GLVU::CheckForGLError("SkyTextureState::Activate(1)");
paramValue = GetTextureParameter(i, GL_TEXTURE_MAG_FILTER);
if (pCurrent->GetTextureParameter(i, GL_TEXTURE_MAG_FILTER) != paramValue)
{
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_MAG_FILTER, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_MAG_FILTER, paramValue);
}
//GLVU::CheckForGLError("SkyTextureState::Activate()");
}
if (glActiveTextureIsSupported && (s_iNumTextureUnits > 1))
glActiveTexturePtr(GL_TEXTURE0_ARB);
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureState::Force
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::Force()
* @brief @todo <WRITE BRIEF SkyTextureState::Activate DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyTextureState::Activate FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyTextureState::Force()
{
SkyTextureState *pCurrent = GraphicsContext::InstancePtr()->GetCurrentTextureState();
assert(NULL != pCurrent);
//GLVU::CheckForGLError("SkyTextureState::Activate(8)");
for (unsigned int i = 0; i < s_iNumTextureUnits; ++i)
{
if (glActiveTextureIsSupported && (s_iNumTextureUnits > 1))
glActiveTexturePtr(GL_TEXTURE0_ARB + i);
bool bEnabled = IsTextureEnabled(i);
FAIL_RETURN(pCurrent->EnableTexture(i, bEnabled));
//GLVU::CheckForGLError("SkyTextureState::Activate(7)");
if (bEnabled)
glEnable(GetActiveTarget(i));
else
glDisable(GetActiveTarget(i));
//GLVU::CheckForGLError("SkyTextureState::Activate(6)");
GLenum eTarget = GetActiveTarget(i);
unsigned int iID = GetTextureID(i);
FAIL_RETURN(pCurrent->SetTexture(i, eTarget, iID));
glBindTexture(eTarget, iID);
//GLVU::CheckForGLError("SkyTextureState::Activate(5)");
GLenum paramValue = GetTextureParameter(i, GL_TEXTURE_WRAP_S);
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_WRAP_S, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_WRAP_S, paramValue);
//GLVU::CheckForGLError("SkyTextureState::Activate(4)");
paramValue = GetTextureParameter(i, GL_TEXTURE_WRAP_T);
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_WRAP_T, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_WRAP_T, paramValue);
//GLVU::CheckForGLError("SkyTextureState::Activate(3)");
paramValue = GetTextureParameter(i, GL_TEXTURE_WRAP_R);
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_WRAP_R, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_WRAP_R, paramValue);
//GLVU::CheckForGLError("SkyTextureState::Activate(2)");
paramValue = GetTextureParameter(i, GL_TEXTURE_MIN_FILTER);
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_MIN_FILTER, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, paramValue);
//GLVU::CheckForGLError("SkyTextureState::Activate(1)");
paramValue = GetTextureParameter(i, GL_TEXTURE_MAG_FILTER);
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_MAG_FILTER, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, paramValue);
if(glActiveTextureIsSupported && (s_iNumTextureUnits > 1))
glActiveTexturePtr(GL_TEXTURE0_ARB);
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureState::SetTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::SetTexture(unsigned int iTextureUnit, GLenum eTarget, SkyTexture& texture)
* @brief @todo <WRITE BRIEF SkyTextureState::BindTexture DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyTextureState::BindTexture FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyTextureState::SetTexture(unsigned int iTextureUnit,
GLenum eTarget,
SkyTexture& texture)
{
if (iTextureUnit >= s_iNumTextureUnits)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyTextureState::BindTexture(): Invalid texture unit.");
}
_pTextureUnitState[iTextureUnit].eActiveTarget = eTarget;
_pTextureUnitState[iTextureUnit].iBoundTexture = texture.GetID();
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureState::SetTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::SetTexture(unsigned int iTextureUnit, GLenum eTarget, unsigned int iTextureID)
* @brief @todo <WRITE BRIEF SkyTextureState::SetTexture DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyTextureState::SetTexture FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyTextureState::SetTexture(unsigned int iTextureUnit,
GLenum eTarget,
unsigned int iTextureID)
{
if (iTextureUnit >= s_iNumTextureUnits)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyTextureState::BindTexture(): Invalid texture unit.");
}
_pTextureUnitState[iTextureUnit].eActiveTarget = eTarget;
_pTextureUnitState[iTextureUnit].iBoundTexture = iTextureID;
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureState::EnableTexture
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::EnableTexture(unsigned int iTextureUnit, bool bEnable)
* @brief @todo <WRITE BRIEF SkyTextureState::EnableTexture DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyTextureState::EnableTexture FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyTextureState::EnableTexture(unsigned int iTextureUnit, bool bEnable)
{
if (iTextureUnit >= s_iNumTextureUnits)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyTextureState::EnableTexture(): Invalid texture unit.");
}
_pTextureUnitState[iTextureUnit].bEnabled = bEnable;
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyTextureState::SetTextureParameter
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::SetTextureParameter(unsigned int iTextureUnit, GLenum eParameter, GLenum eMode)
* @brief @todo <WRITE BRIEF SkyTextureState::SetTextureParameter DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyTextureState::SetTextureParameter FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyTextureState::SetTextureParameter(unsigned int iTextureUnit,
GLenum eParameter,
GLenum eMode)
{
if (iTextureUnit >= s_iNumTextureUnits)
{
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyTextureState::SetTextureParameter(): Invalid texture unit.");
}
switch (eParameter)
{
case GL_TEXTURE_WRAP_S:
_pTextureUnitState[iTextureUnit].eWrapMode[TexState::SKY_TEXCOORD_S] = eMode;
break;
case GL_TEXTURE_WRAP_T:
_pTextureUnitState[iTextureUnit].eWrapMode[TexState::SKY_TEXCOORD_T] = eMode;
break;
case GL_TEXTURE_WRAP_R:
_pTextureUnitState[iTextureUnit].eWrapMode[TexState::SKY_TEXCOORD_R] = eMode;
break;
case GL_TEXTURE_MIN_FILTER:
_pTextureUnitState[iTextureUnit].eFilterMode[TexState::SKY_FILTER_MIN] = eMode;
break;
case GL_TEXTURE_MAG_FILTER:
_pTextureUnitState[iTextureUnit].eFilterMode[TexState::SKY_FILTER_MAG] = eMode;
break;
default:
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyTExtureState::SetTextureParameter(): Invalid parameter.");
break;
}
return SKYRESULT_OK;
}

View File

@@ -1,206 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyTextureState.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyTextureState.hpp
*
* Interface Definition for class SkyTextureState, which encapsulates OpenGL texture state.
*/
#ifndef __SKYTEXTURESTATE_HPP__
#define __SKYTEXTURESTATE_HPP__
#include "SkyUtil.hpp"
#include "SkyTexture.hpp"
#include "SkyContext.hpp"
#include <map>
//------------------------------------------------------------------------------
/**
* @class SkyTextureState
* @brief A wrapper for texture unit state.
*
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
*/
class SkyTextureState
{
public: // methods
SkyTextureState();
~SkyTextureState();
SKYRESULT Force();
SKYRESULT Activate();
SKYRESULT SetTexture(unsigned int iTextureUnit, GLenum eTarget, SkyTexture& texture);
SKYRESULT SetTexture(unsigned int iTextureUnit, GLenum eTarget, unsigned int iTextureID);
SKYRESULT EnableTexture(unsigned int iTextureUnit, bool bEnable);
SKYRESULT SetTextureParameter(unsigned int iTextureUnit,
GLenum eParameter,
GLenum eMode);
inline GLenum GetActiveTarget(unsigned int iTextureUnit) const;
inline unsigned int GetTextureID(unsigned int iTextureUnit) const;
inline bool IsTextureEnabled(unsigned int iTextureUnit) const;
inline GLenum GetTextureParameter(unsigned int iTextureUnit, GLenum eParameter) const;
protected: // datatypes
struct TexState
{
TexState() : eActiveTarget(GL_TEXTURE_2D), iBoundTexture(0), bEnabled(false)
{
// set state to GL defaults.
int i;
for (i = 0; i < SKY_TEXCOORD_COUNT; ++i) { eWrapMode[i] = GL_REPEAT; }
eFilterMode[SKY_FILTER_MIN] = GL_NEAREST_MIPMAP_LINEAR;
eFilterMode[SKY_FILTER_MAG] = GL_LINEAR;
}
enum TexCoord
{
SKY_TEXCOORD_S,
SKY_TEXCOORD_T,
SKY_TEXCOORD_R,
SKY_TEXCOORD_COUNT
};
enum TexFilter
{
SKY_FILTER_MIN,
SKY_FILTER_MAG,
SKY_FILTER_COUNT
};
GLenum eActiveTarget;
unsigned int iBoundTexture;
bool bEnabled;
GLenum eWrapMode[SKY_TEXCOORD_COUNT];
GLenum eFilterMode[SKY_FILTER_COUNT];
};
protected: // data
TexState *_pTextureUnitState; // one per texture unit
static unsigned int s_iNumTextureUnits;
};
//------------------------------------------------------------------------------
// Function : SkyTextureState::GetActiveTarget
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::GetActiveTarget(unsigned int iTextureUnit) const
* @brief Returns the active texture target for the specified texture unit.
*
* If an invalid texture unit is specifed, returns GL_NONE.
*/
inline GLenum SkyTextureState::GetActiveTarget(unsigned int iTextureUnit) const
{
if (iTextureUnit >= s_iNumTextureUnits)
{
SkyTrace("SkyTextureState::GetActiveTexture(): Invalid texture unit.");
return GL_NONE;
}
return _pTextureUnitState[iTextureUnit].eActiveTarget;
}
//------------------------------------------------------------------------------
// Function : int SkyTextureState::GetTextureID
// Description :
//------------------------------------------------------------------------------
/**
* @fn int SkyTextureState::GetTextureID(unsigned int iTextureUnit) const
* @brief Returns the texture ID associated with the specified texture unit.
*
* If an invalid texture unit is specifed, returns GL_NONE.
*/
inline unsigned int SkyTextureState::GetTextureID(unsigned int iTextureUnit) const
{
if (iTextureUnit >= s_iNumTextureUnits)
{
SkyTrace("SkyTextureState::GetTextureID(): Invalid texture unit.");
return GL_NONE;
}
return _pTextureUnitState[iTextureUnit].iBoundTexture;
}
//------------------------------------------------------------------------------
// Function : SkyTextureState::IsTextureEnabled
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::IsTextureEnabled(unsigned int iTextureUnit) const
* @brief Returns the status (enabled or disabled) of the specified texture unit.
*
* If an invalid texture unit is specifed, returns false.
*/
inline bool SkyTextureState::IsTextureEnabled(unsigned int iTextureUnit) const
{
if (iTextureUnit >= s_iNumTextureUnits)
{
SkyTrace("SkyTextureState::IsTextureEnabled(): Invalid texture unit.");
return false;
}
return _pTextureUnitState[iTextureUnit].bEnabled;
}
//------------------------------------------------------------------------------
// Function : SkyTextureState::GetTextureParameter
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyTextureState::GetTextureParameter(unsigned int iTextureUnit, GLenum eParamter) const
* @brief Returns the current value of @eParameter on the specified texture unit.
*
* If an invalid texture unit or parameter is specified, returns GL_NONE.
*/
inline GLenum SkyTextureState::GetTextureParameter(unsigned int iTextureUnit, GLenum eParameter) const
{
if (iTextureUnit >= s_iNumTextureUnits)
{
SkyTrace("SkyTextureState::GetTextureParamter(): Invalid texture unit.");
return GL_NONE;
}
switch (eParameter)
{
case GL_TEXTURE_WRAP_S:
return _pTextureUnitState[iTextureUnit].eWrapMode[TexState::SKY_TEXCOORD_S];
break;
case GL_TEXTURE_WRAP_T:
return _pTextureUnitState[iTextureUnit].eWrapMode[TexState::SKY_TEXCOORD_T];
break;
case GL_TEXTURE_WRAP_R:
return _pTextureUnitState[iTextureUnit].eWrapMode[TexState::SKY_TEXCOORD_R];
break;
case GL_TEXTURE_MIN_FILTER:
return _pTextureUnitState[iTextureUnit].eFilterMode[TexState::SKY_FILTER_MIN];
break;
case GL_TEXTURE_MAG_FILTER:
return _pTextureUnitState[iTextureUnit].eFilterMode[TexState::SKY_FILTER_MAG];
break;
default:
SkyTrace("SkyTExtureState::SetTextureParameter(): Invalid parameter.");
break;
}
return GL_NONE;
}
#endif //__SKYTEXTURESTATE_HPP__

View File

@@ -1,50 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyUtil.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyUtil.cpp
*
* Implemtation of global utility functions.
*/
#include "SkyUtil.hpp"
//------------------------------------------------------------------------------
// Function : SkyTrace
// Description :
//------------------------------------------------------------------------------
/**
* SkyTrace( char* strMsg, ... )
* @brief Prints formatted output, debug only.
*
* Includes file and line number information automatically.
*/
void SkyTrace( char* strMsg, ... )
{
#if defined(DEBUG) | defined(_DEBUG)
char strBuffer[512];
va_list args;
va_start(args, strMsg);
_vsnprintf( strBuffer, 512, strMsg, args );
va_end(args);
fprintf(stderr, "[SkyTrace] %s(%d): %s\n",__FILE__, __LINE__, strBuffer);
#endif
}

View File

@@ -1,192 +0,0 @@
//------------------------------------------------------------------------------
// File : SkyUtil.hpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyUtil.hpp
* @brief Safe deallocation functions, result codes, trace functions, and macros.
*/
#ifndef __SKYUTIL_HPP__
#define __SKYUTIL_HPP__
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
//-----------------------------------------------------------------------------
// Useful constants
//-----------------------------------------------------------------------------
//! Pi.
const float SKY_PI = 4.0f * (float) atan(1.0f);
//! 1.0 / Pi
const float SKY_INV_PI = 1.0f / SKY_PI;
//! 1.0 / (4.0 * Pi)
const float SKY_INV_4PI = 1.0f / (4.0f * SKY_PI);
//-----------------------------------------------------------------------------
// Safe deallocation
//-----------------------------------------------------------------------------
//! Delete and set pointer to NULL.
#define SAFE_DELETE(p) { delete (p); (p)=NULL; }
//! Delete an array and set pointer to NULL.
#define SAFE_DELETE_ARRAY(p) { delete[] (p); (p)=NULL; }
//#define SAFE_RELEASE(p) { (p) = NULL; }
//{ if(p) { (p)->Release(); (p)=NULL; } }
//------------------------------------------------------------------------------
// Useful Macros
//------------------------------------------------------------------------------
//! Convert Degrees to Radians
#define SKYDEGREESTORADS 0.01745329252f
//! Convert Radians to Degrees
#define SKYRADSTODEGREES 57.2957795131f
//------------------------------------------------------------------------------
// Function : SkyGetLogBaseTwo
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyGetLogBaseTwo(int iNum)
* @brief Returns the integer base two logarithm of the integer input.
*/
inline int SkyGetLogBaseTwo(int iNum)
{
int i, n;
for(i = iNum-1, n = 0; i > 0; i >>= 1, n++ );
return n;
}
//------------------------------------------------------------------------------
// Function : SkyTrace
// Description :
//------------------------------------------------------------------------------
void SkyTrace( char* strMsg, ... );
//.----------------------------------------------------------------------------.
//| Result Codes |
//.----------------------------------------------------------------------------.
//! SKYRESULTs are used for returning error information that can be used to trace bugs.
typedef int SKYRESULT;
//! Returns true if the SKYRESULT is a success result.
#define SKYSUCCEEDED(Status) ((SKYRESULT)(Status) >= 0)
//! Returns true if the SKYRESULT is a failure result.
#define SKYFAILED(Status) ((SKYRESULT)(Status) < 0)
//! SKYRESULTs are used for returning error information that can be used to trace bugs.
enum SKYRESULT_CODES
{
// SUCCESS CODES: non-negative
SKYRESULT_OK = 1,
// FAILURE CODES: negative
SKYRESULT_FAIL = -1
};
//-----------------------------------------------------------------------------
// FAIL_RETURN
//-----------------------------------------------------------------------------
// Print debug messages to the WIN32 debug window
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Function : FAIL_RETURN
// Description :
//------------------------------------------------------------------------------
/**
* @fn FAIL_RETURN(p)
* @brief Prints a trace message if @a p failed, and returns the failure code.
*
* Outputs in a format that can be double-clicked in DevStudio to open the
* appropriate file and location.
*/
#if defined(DEBUG) | defined(_DEBUG)
#define FAIL_RETURN(p) \
{ \
SKYRESULT __SKYUTIL__result__; \
if ( SKYFAILED( __SKYUTIL__result__ = (p) ) ) { \
fprintf(stderr, "!!!! FAIL_RETURN TRAP !!!! %s: %d: %d\n",__FILE__, __LINE__, __SKYUTIL__result__); \
return __SKYUTIL__result__; \
} \
}
#else
#define FAIL_RETURN(p) p
#endif
//------------------------------------------------------------------------------
// Function : FAIL_RETURN_MSG
// Description :
//------------------------------------------------------------------------------
/**
* @fn FAIL_RETURN_MSG(p,str)
* @brief Similar to FAIL_RETURN, but also appends a user-supplied message.
*
* @see FAIL_RETURN, FAIL_RETURN_MSG
*/
#if defined(DEBUG) | defined(_DEBUG)
#define FAIL_RETURN_MSG(p,str) \
{ \
SKYRESULT __SKYUTIL__result__; \
if ( SKYFAILED( __SKYUTIL__result__ = (p) ) ) { \
fprintf(stderr, "!!!! FAIL_RETURN_MSG TRAP !!!! %s: %d: %d: %s\n",__FILE__,__LINE__,__SKYUTIL__result__,str); \
return __SKYUTIL__result__; \
} \
}
#else
#define FAIL_RETURN_MSG(p,str) p
#endif
//------------------------------------------------------------------------------
// Function : FAIL_RETURN_MSGBOX
// Description :
//------------------------------------------------------------------------------
/**
* @fn FAIL_RETURN_MSGBOX(p,str)
* @brief Similar to FAIL_RETURN_MSG, but also displays the error in a message box (in Windows).
*
* @see FAIL_RETURN_MSG, FAIL_RETURN
*/
#if defined(DEBUG) | defined(_DEBUG)
#ifdef USEWINDOWSOUTPUT
#define FAIL_RETURN_MSGBOX(p,str) \
{ \
SKYRESULT __SKYUTIL__result__; \
if ( SKYFAILED( __SKYUTIL__result__ = (p) ) ) { \
char msg[512]; \
sprintf(msg, "%s: %d: %d: %s\n",__FILE__,__LINE__,__SKYUTIL__result__,str); \
MessageBox(NULL, msg, "!!!! FAIL_RETURN_MSG TRAP !!!!", MB_OK); \
return __SKYUTIL__result__; \
} \
}
#else
#define FAIL_RETURN_MSGBOX(p,str) \
{ \
SKYRESULT __SKYUTIL__result__; \
if ( SKYFAILED( __SKYUTIL__result__ = (p) ) ) { \
fprintf(stderr, "!!!! FAIL_RETURN_MSG TRAP !!!! %s: %d: %d: %s\n",__FILE__,__LINE__,__D3DUTIL__hres__,str); \
return __SKYUTIL__result__; \
} \
}
#endif
#else
#define FAIL_RETURN_MSGBOX(p,str) p
#endif
#endif //__SKYUTIL_HPP__

View File

@@ -1,93 +0,0 @@
//------------------------------------------------------------------------------
// File : camdisplay.cpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// camdisplay.cpp
//============================================================================
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include GLUT_H
#include "camera.hpp"
//----------------------------------------------------------------------------
// OPENGL CAMERA FRUSTUM DRAWING ROUTINES
//----------------------------------------------------------------------------
void Camera::Display() const
{
// CALC EIGHT CORNERS OF FRUSTUM (NEAR PTS AND FAR PTS)
Vec3f V[8];
CalcVerts(V);
// DRAW THE FRUSTUM IN WIREFRAME
glBegin(GL_LINE_LOOP); // TOP FACE
glVertex3fv(&(V[4].x)); glVertex3fv(&(V[5].x));
glVertex3fv(&(V[1].x)); glVertex3fv(&(V[0].x));
glEnd();
glBegin(GL_LINE_LOOP); // BOTTOM FACE
glVertex3fv(&(V[3].x)); glVertex3fv(&(V[2].x));
glVertex3fv(&(V[6].x)); glVertex3fv(&(V[7].x));
glEnd();
glBegin(GL_LINE_LOOP); // LEFT FACE
glVertex3fv(&(V[1].x)); glVertex3fv(&(V[5].x));
glVertex3fv(&(V[6].x)); glVertex3fv(&(V[2].x));
glEnd();
glBegin(GL_LINE_LOOP); // RIGHT FACE
glVertex3fv(&(V[0].x)); glVertex3fv(&(V[3].x));
glVertex3fv(&(V[7].x)); glVertex3fv(&(V[4].x));
glEnd();
glBegin(GL_LINE_LOOP); // NEAR FACE
glVertex3fv(&(V[1].x)); glVertex3fv(&(V[2].x));
glVertex3fv(&(V[3].x)); glVertex3fv(&(V[0].x));
glEnd();
glBegin(GL_LINE_LOOP); // FAR FACE
glVertex3fv(&(V[4].x)); glVertex3fv(&(V[7].x));
glVertex3fv(&(V[6].x)); glVertex3fv(&(V[5].x));
glEnd();
// DRAW PROJECTOR LINES FROM EYE TO CORNERS OF VIEWPLANE WINDOW
glBegin(GL_LINES);
glVertex3fv(&(Orig.x)); glVertex3fv(&(V[1].x));
glVertex3fv(&(Orig.x)); glVertex3fv(&(V[2].x));
glVertex3fv(&(Orig.x)); glVertex3fv(&(V[3].x));
glVertex3fv(&(Orig.x)); glVertex3fv(&(V[0].x));
glEnd();
}
void Camera::DisplayInGreen() const
{
//draws the camera in unlit green lines, then restores the GL state
glPushAttrib(GL_LIGHTING_BIT);
glDisable(GL_LIGHTING);
glPushAttrib(GL_LINE_BIT);
glLineWidth(1.0);
glColor3f(0,1,0);
Display();
glPopAttrib();
glPopAttrib();
}

View File

@@ -1,412 +0,0 @@
//------------------------------------------------------------------------------
// File : camera.cpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// camera.cpp : camera class implementation
//----------------------------------------------------------------------------
// $Id$
//============================================================================
#include <simgear/compiler.h>
#include "camera.hpp"
#include STL_IOSTREAM
//----------------------------------------------------------------------------
// CONSTRUCTOR: defines a default camera system defined as (45 DEG FOV)
//----------------------------------------------------------------------------
Camera::Camera()
{
X.Set(1,0,0); Y.Set(0,1,0); Z.Set(0,0,1);
Orig.Set(0,0,0);
Near=0.5f; Far=140.0f; wL=-1; wR=1; wT=1; wB=-1;
}
Camera::Camera(const Camera &Cam)
{
Copy(Cam);
}
void Camera::Copy(const Camera &Cam)
{
X=Cam.X; Y=Cam.Y; Z=Cam.Z; Orig=Cam.Orig;
Near=Cam.Near; Far=Cam.Far;
wL=Cam.wL; wR=Cam.wR; wT=Cam.wT; wB=Cam.wB;
}
//----------------------------------------------------------------------------
// OpenGL CAMERA ORIENTATION ROUTINE (glLookAt)
//----------------------------------------------------------------------------
void Camera::LookAt(
const Vec3f& Eye, const Vec3f& ViewRefPt, const Vec3f& ViewUp)
{
Z = Eye-ViewRefPt; Z.Normalize(); // CALC CAM AXES ("/" IS CROSS-PROD)
X = ViewUp/Z; X.Normalize();
Y = Z/X; Y.Normalize();
Orig = Eye;
}
//----------------------------------------------------------------------------
// OpenGL PERSPECTIVE FRUSTUM DEFINITION ROUTINE (gluPerspective)
// Aspect = Width/Height; Yfov in degrees
//----------------------------------------------------------------------------
void Camera::Perspective(float Yfov, float Aspect, float Ndist, float Fdist)
{
Yfov *= 0.0174532f; // CONVERT TO RADIANS
Near=Ndist; Far=Fdist;
wT=(float)tan(Yfov*0.5f)*Near; wB=-wT;
wR=wT*Aspect; wL=-wR;
}
//----------------------------------------------------------------------------
// OpenGL PERSPECTIVE FRUSTUM DEFINITION ROUTINE (glFrustum). Window extents
// are defined on the viewplane at z=-Ndist.
//----------------------------------------------------------------------------
void Camera::Frustum(float l, float r, float b, float t, float Ndist, float Fdist)
{
Near=Ndist; Far=Fdist;
wR=r; wL=l; wB=b; wT=t;
}
//----------------------------------------------------------------------------
// Completely defines a camera as a tight fitting frustum surrounding the
// given bounding sphere. This is useful when most precision
// is required in pixel and depth resolution (for example, shadow-maps).
// The resulting camera is not skewed!
//----------------------------------------------------------------------------
void Camera::TightlyFitToSphere(
const Vec3f& Eye, const Vec3f& ViewUp, const Vec3f& Cntr, float Rad)
{
// FIRST DEFINE COORDINATE FRAME
LookAt(Eye,Cntr,ViewUp);
// PROJECTED DIST TO CNTR ALONG VIEWDIR
float DistToCntr = (Cntr-Orig) * ViewDir();
// CALC TIGHT-FITTING NEAR AND FAR PLANES
Near = DistToCntr-Rad;
Far = DistToCntr+Rad;
//x = n*R / sqrt(d2 - r2)
if (Near<=0 || Far<=0)
printf("ERROR (Camera::TightlyFitToSphere) Eye is inside the sphere!\n");
// CALC TIGHT-FITTING SIDES
wT = (Near * Rad) / (float)sqrt(DistToCntr*DistToCntr - Rad*Rad);//(Near * Rad) / DistToCntr;
wB = -wT;
wL = wB;
wR = wT;
}
//----------------------------------------------------------------------------
// Routines to return the Lookat, Perspective, and Frustum params.
// NOTE: Perspective is designed for non-skewed cameras: the viewing
// direction must be centered on the viewplane window. Use frustum
// for off-axis cameras.
//----------------------------------------------------------------------------
void Camera::GetLookAtParams(Vec3f *Eye, Vec3f *ViewRefPt, Vec3f *ViewUp) const
{
*Eye = Orig;
*ViewRefPt = Orig - Z;
*ViewUp = Y;
}
void Camera::GetPerspectiveParams(float *Yfov, float *Aspect,
float *Ndist, float *Fdist) const
{
*Yfov = (float)atan(wT/Near) * 57.29578f * 2.0f; // CONVERT TO DEGREES
*Aspect = wR/wT;
*Ndist = Near;
*Fdist = Far;
}
void Camera::GetFrustumParams(float *l, float *r, float *b, float *t,
float *Ndist, float *Fdist) const
{
*l = wL;
*r = wR;
*b = wB;
*t = wT;
*Ndist = Near;
*Fdist = Far;
}
//----------------------------------------------------------------------------
// RETURNS THE COP OR EYE IN WORLD COORDS (ORIG OF CAMERA SYSTEM)
//----------------------------------------------------------------------------
const Vec3f& Camera::wCOP() const
{
return( Orig );
}
//----------------------------------------------------------------------------
// RETURNS THE VIEWING DIRECTION
//----------------------------------------------------------------------------
Vec3f Camera::ViewDir() const
{
return( -Z );
}
Vec3f Camera::ViewDirOffAxis() const
{
float x=(wL+wR)*0.5f, y=(wT+wB)*0.5f; // MIDPOINT ON VIEWPLANE WINDOW
Vec3f ViewDir = X*x + Y*y - Z*Near;
ViewDir.Normalize();
return( ViewDir );
}
//----------------------------------------------------------------------------
// Vec3f WORLD-TO-CAM AND CAM-TO-WORLD ROUTINES
//----------------------------------------------------------------------------
Vec3f Camera::WorldToCam(const Vec3f& wP) const
{
Vec3f sP(wP-Orig);
Vec3f cP(X*sP,Y*sP,Z*sP); return(cP);
}
// Return the z-value of the world point in camera space
float Camera::WorldToCamZ(const Vec3f& wP) const
{
Vec3f sP(wP-Orig);
float zdist = Z*sP;
return(zdist);
}
Vec3f Camera::CamToWorld(const Vec3f& cP) const
{
Vec3f wP(X*cP.x + Y*cP.y + Z*cP.z + Orig); return(wP);
}
//----------------------------------------------------------------------------
// Makes the camera pose be the identity. World and camera space will be the
// same. Window extents and near/far planes are unaffected.
//----------------------------------------------------------------------------
void Camera::LoadIdentityXform()
{
X.Set(1,0,0);
Y.Set(0,1,0);
Z.Set(0,0,1);
Orig.Set(0,0,0);
}
//----------------------------------------------------------------------------
// Applies an OpenGL style premult/col vector xform to the coordinate frame.
// Only rotates, translates, and uniform scales are allowed.
// Window extents and near/far planes are affected by scaling.
//----------------------------------------------------------------------------
void Camera::Xform(const float M[16])
{
X.Set( X.x*M[0] + X.y*M[4] + X.z*M[8],
X.x*M[1] + X.y*M[5] + X.z*M[9],
X.x*M[2] + X.y*M[6] + X.z*M[10] );
Y.Set( Y.x*M[0] + Y.y*M[4] + Y.z*M[8],
Y.x*M[1] + Y.y*M[5] + Y.z*M[9],
Y.x*M[2] + Y.y*M[6] + Y.z*M[10] );
Z.Set( Z.x*M[0] + Z.y*M[4] + Z.z*M[8],
Z.x*M[1] + Z.y*M[5] + Z.z*M[9],
Z.x*M[2] + Z.y*M[6] + Z.z*M[10] );
Orig.Set( Orig.x*M[0] + Orig.y*M[4] + Orig.z*M[8] + M[12],
Orig.x*M[1] + Orig.y*M[5] + Orig.z*M[9] + M[13],
Orig.x*M[2] + Orig.y*M[6] + Orig.z*M[10] + M[14] );
// MUST RENORMALIZE AXES TO FIND THE UNIFORM SCALE
float Scale = X.Length();
X /= Scale;
Y /= Scale;
Z /= Scale;
// SCALE THE WINDOW EXTENTS AND THE NEAR/FAR PLANES
wL*=Scale;
wR*=Scale;
wB*=Scale;
wT*=Scale;
Near*=Scale;
Far*=Scale;
};
//----------------------------------------------------------------------------
// Translates the camera by the vector amount trans.
//----------------------------------------------------------------------------
void Camera::Translate(const Vec3f& trans)
{
Orig += trans;
}
//----------------------------------------------------------------------------
// Translates the camera about its origin by the rotation matrix M.
//----------------------------------------------------------------------------
void Camera::Rotate(const float M[9])
{
X.Set( X.x*M[0] + X.y*M[3] + X.z*M[6],
X.x*M[1] + X.y*M[4] + X.z*M[7],
X.x*M[2] + X.y*M[5] + X.z*M[8] );
Y.Set( Y.x*M[0] + Y.y*M[3] + Y.z*M[6],
Y.x*M[1] + Y.y*M[4] + Y.z*M[7],
Y.x*M[2] + Y.y*M[5] + Y.z*M[8] );
Z.Set( Z.x*M[0] + Z.y*M[3] + Z.z*M[6],
Z.x*M[1] + Z.y*M[4] + Z.z*M[7],
Z.x*M[2] + Z.y*M[5] + Z.z*M[8] );
}
//----------------------------------------------------------------------------
// Returns the COMPOSITE xform matrix that takes a point in the object space
// to a screen space (pixel) point. The inverse is also provided.
// You have to give the pixel dimensions of the viewport window.
//----------------------------------------------------------------------------
float* Camera::GetXform_Screen2Obj(float* M, int WW, int WH) const
{
Screen2WorldXform16fv(M,&(X.x),&(Y.x),&(Z.x),&(Orig.x),
wL,wR,wB,wT,Near,Far,WW,WH);
return(M);
}
float* Camera::GetXform_Obj2Screen(float* M, int WW, int WH) const
{
World2ScreenXform16fv(M,&(X.x),&(Y.x),&(Z.x),&(Orig.x),
wL,wR,wB,wT,Near,Far,WW,WH);
return(M);
}
//----------------------------------------------------------------------------
// OPENGL STYLE CAMERA VIEWING MATRIX ROUTINES (PREMULT/COL VECT, 4x4 MATRIX)
// A POINT IN THE WORLD SPACE CAN BE TRANSFORMED TO A PIXEL ON THE CAMERA
// VIEWPLANE BY TRANSFORMING WITH THE COMPOSITE MATRIX: C = V*P*M
// WHERE V IS THE Viewport XFORM, P IS THE Projection XFORM, AND M IS THE
// Modelview XFORM. The associated inverse matrices are also provided.
//----------------------------------------------------------------------------
float* Camera::GetModelviewMatrix(float* M) const
{
Viewing16fv(M,&(X.x),&(Y.x),&(Z.x),&(Orig.x));
return(M);
}
float* Camera::GetInvModelviewMatrix(float* M) const
{
invViewing16fv(M,&(X.x),&(Y.x),&(Z.x),&(Orig.x));
return(M);
}
float* Camera::GetProjectionMatrix(float* M) const
{
Frustum16fv(M,wL,wR,wB,wT,Near,Far);
return(M);
}
void Camera::SetModelviewMatrix(const float* M)
{
Viewing2CoordFrame16fv(M, &(X.x), &(Y.x), &(Z.x), &(Orig.x));
}
float* Camera::GetInvProjectionMatrix(float* M) const
{
invFrustum16fv(M,wL,wR,wB,wT,Near,Far);
return(M);
}
float* Camera::GetViewportMatrix(float* M, int WW, int WH) const
{
Viewport16fv(M,WW,WH);
return(M);
}
float* Camera::GetInvViewportMatrix(float* M, int WW, int WH) const
{
invViewport16fv(M,WW,WH);
return(M);
}
//----------------------------------------------------------------------------
// Given a screen pixel location (sx,sy) w/ (0,0) at the lower-left and the
// screen dimensions, return the ray (start,dir) of the ray in world coords.
//----------------------------------------------------------------------------
void Camera::GetPixelRay(float sx, float sy, int ww, int wh,
Vec3f *Start, Vec3f *Dir) const
{
Vec3f wTL = Orig + (X*wL) + (Y*wT) - (Z*Near); // FIND LOWER-LEFT
Vec3f dX = (X*(wR-wL))/(float)ww; // WORLD WIDTH OF PIXEL
Vec3f dY = (Y*(wT-wB))/(float)wh; // WORLD HEIGHT OF PIXEL
wTL += (dX*sx - dY*sy); // INCR TO WORLD PIXEL
wTL += (dX*0.5 - dY*0.5); // INCR TO PIXEL CNTR
*Start = Orig;
*Dir = wTL-Orig;
}
//----------------------------------------------------------------------------
// READ AND WRITE CAMERA AXES AND ORIGIN TO AND FROM A FILE GIVEN A FILE PTR.
//----------------------------------------------------------------------------
void Camera::WriteToFile(FILE *fp) const
{
if (fp==NULL) { printf("ERROR WRITING CAM TO FILE!\n"); return; }
fprintf(fp,"%f %f %f %f %f %f %f %f %f %f %f %f\n",
X.x,X.y,X.z, Y.x,Y.y,Y.z, Z.x,Z.y,Z.z, Orig.x,Orig.y,Orig.z);
}
int Camera::ReadFromFile(FILE *fp) // RETURNS "1" IF SUCCESSFUL, "0" IF EOF
{
int Cond = fscanf(fp,"%f %f %f %f %f %f %f %f %f %f %f %f",
&X.x,&X.y,&X.z, &Y.x,&Y.y,&Y.z,
&Z.x,&Z.y,&Z.z, &Orig.x,&Orig.y,&Orig.z);
return(Cond!=EOF);
}
//----------------------------------------------------------------------------
// 0=RTN,1=LTN,2=LBN,3=RBN,4=RTF,5=LTF,6=LBF,7=RBF
// (Left,Right, Bottom,Top, Near,Far)
// In order, near pts counter-clockwise starting with right-top-near (RTN) pt
// and then far pts ccw starting with right-top-far (RTF) pt
//----------------------------------------------------------------------------
void Camera::CalcVerts(Vec3f *V) const // MUST BE PREALLOCED : "Vec3f V[8]"
{
// WINDOW EXTENTS ARE DEFINED ON THE NEAR PLANE, CALC NEAR PTS (IN CAM COORDS)
float NearZ = -Near;
V[0].Set(wR,wT,NearZ);
V[1].Set(wL,wT,NearZ);
V[2].Set(wL,wB,NearZ);
V[3].Set(wR,wB,NearZ);
// CALC FAR PTS (IN CAM COORDS)
float FarZ=-Far, FN=Far/Near;
float fwL=wL*FN, fwR=wR*FN, fwB=wB*FN, fwT=wT*FN;
V[4].Set(fwR,fwT,FarZ);
V[5].Set(fwL,fwT,FarZ);
V[6].Set(fwL,fwB,FarZ);
V[7].Set(fwR,fwB,FarZ);
// XFORM FRUSTUM IN CAM COORDS TO WORLD SPACE
for (int i=0; i<8; i++)
V[i] = CamToWorld(V[i]);
}
//----------------------------------------------------------------------------
// PRINT ROUTINE
//----------------------------------------------------------------------------
void Camera::Print() const
{
printf("Camera System Parameters:\n");
printf(" X: (%.3f, %.3f, %.3f)\n", X.x, X.y, X.z);
printf(" Y: (%.3f, %.3f, %.3f)\n", Y.x, Y.y, Y.z);
printf(" Z: (%.3f, %.3f, %.3f)\n", Z.x, Z.y, Z.z);
printf(" Origin: (%.3f, %.3f, %.3f)\n", Orig.x, Orig.y, Orig.z);
printf(" NFLRBT: (%.3f, %.3f, %.3f, %.3f, %.3f, %.3f)\n",
Near,Far,wL,wR,wB,wT);
};

View File

@@ -1,102 +0,0 @@
//------------------------------------------------------------------------------
// File : camera.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// camera.hpp : OPENGL-style camera class definition
// Defines and stores a "camera" composed of 3 coord axes, an origin for
// these axes (center-of-projection or eye location), a near and far plane
// as distances from the origin projected along the viewing direction,
// the viewplane window extents (projection window defined in cam coords
// on the viewplane - near plane). ViewPlane is defined as the near plane.
// Viewing direction is always defined along the -Z axis with eye at origin.
//----------------------------------------------------------------------------
// $Id$
//============================================================================
#ifndef CAMERA
#define CAMERA
#include <stdio.h>
#include "vec3f.hpp"
#include "mat16fv.hpp"
class Camera
{
public:
Vec3f X, Y, Z; // NORMALIZED CAMERA COORDINATE-AXIS VECTORS
Vec3f Orig; // LOCATION OF ORIGIN OF CAMERA SYSTEM IN WORLD COORDS
float wL,wR,wB,wT; // WINDOW EXTENTS DEFINED AS A RECT ON NearPlane
float Near,Far; // DISTANCES TO NEAR AND FAR PLANES (IN VIEWING DIR)
Camera();
Camera(const Camera &Cam);
void Copy(const Camera &Cam);
void LookAt(const Vec3f& Eye, const Vec3f& ViewRefPt, const Vec3f& ViewUp);
void Perspective(float Yfov, float Aspect, float Ndist, float Fdist);
void Frustum(float l, float r, float b, float t, float Ndist, float Fdist);
void TightlyFitToSphere(
const Vec3f& Eye, const Vec3f& ViewUp, const Vec3f& Cntr, float Rad);
void GetLookAtParams(Vec3f *Eye, Vec3f *ViewRefPt, Vec3f *ViewUp) const;
void GetPerspectiveParams(float *Yfov, float *Aspect,
float *Ndist, float *Fdist) const;
void GetFrustumParams(float *l, float *r, float *b, float *t,
float *Ndist, float *Fdist) const;
const Vec3f& wCOP() const; // WORLD COORDINATE CENTER-OF-PROJECTION (EYE)
Vec3f ViewDir() const; // VIEWING DIRECTION
Vec3f ViewDirOffAxis() const;
float* GetXform_Screen2Obj(float* M, int WW, int WH) const;
float* GetXform_Obj2Screen(float* M, int WW, int WH) const;
float* GetModelviewMatrix(float* M) const;
float* GetProjectionMatrix(float* M) const;
float* GetViewportMatrix(float* M, int WW, int WH) const;
void SetModelviewMatrix(const float* M);
float* GetInvModelviewMatrix(float* M) const;
float* GetInvProjectionMatrix(float* M) const;
float* GetInvViewportMatrix(float* M, int WW, int WH) const;
Vec3f WorldToCam(const Vec3f &wP) const;
float WorldToCamZ(const Vec3f &wP) const;
Vec3f CamToWorld(const Vec3f &cP) const;
void LoadIdentityXform();
void Xform(const float M[16]);
void Translate(const Vec3f& trans);
void Rotate(const float M[9]);
void GetPixelRay(float sx, float sy, int ww, int wh,
Vec3f *Start, Vec3f *Dir) const;
void WriteToFile(FILE *fp) const;
int ReadFromFile(FILE *fp); // RETURNS "1" IF SUCCESSFUL, "0" IF EOF
void CalcVerts(Vec3f *V) const; // CALCS EIGHT CORNERS OF VIEW-FRUSTUM
void Print() const;
void Display() const;
void DisplaySolid() const;
void DisplayInGreen() const;
};
#endif

View File

@@ -1,324 +0,0 @@
//------------------------------------------------------------------------------
// File : camutils.cpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// camutils.cpp : a set of camera utility functions
//============================================================================
#include "camutils.hpp"
#include "plane.hpp"
#include "tri.hpp"
#include "minmaxbox.hpp"
//----------------------------------------------------------------------------
// Given a camera's 8 corner vertices and its 6 side planes and a triangle ABC,
// return whether or not the tri overlaps the camera's frustum.
//----------------------------------------------------------------------------
int CamTriOverlap(const Vec3f V[8], const float P[][4],
const Vec3f& A, const Vec3f& B, const Vec3f& C)
{
// TEST TRIANGLE AGAINST ALL PLANES OF CAMERA, FOR EACH VERTEX CLASSIFY
// AS INSIDE OR OUTSIDE OF PLANE (BY SETTING APPROPRIATE BIT IN BITMASK)
// FOR EACH VERTEX, WE HAVE A BITMASK INDICATING WHETHER THE VERTEX
// IS IN OR OUT OF EACH PLANE (LS 6-BITS, SET MEANS "OUT")
unsigned int BitMaskA=0, BitMaskB=0, BitMaskC=0;
unsigned int PlaneBitMask=1; // CURRENT PLANE BEING CHECKED
int i;
for (i=0; i<6; i++)
{
if ( PlanePtOutTest(P[i], &(A.x)) ) BitMaskA |= PlaneBitMask;
if ( PlanePtOutTest(P[i], &(B.x)) ) BitMaskB |= PlaneBitMask;
if ( PlanePtOutTest(P[i], &(C.x)) ) BitMaskC |= PlaneBitMask;
PlaneBitMask<<=1;
}
// TRIVIAL ACCEPTANCE: IF ANY VERTEX IS COMPLETELY INSIDE ALL PLANES (=0)
if (BitMaskA==0 || BitMaskB==0 || BitMaskC==0) return(1);
// TRIVIAL REJECTION: IF ALL VERTICES ARE OUTSIDE OF ANY PLANE
PlaneBitMask=1;
for (i=0; i<6; i++)
{
if ((BitMaskA & BitMaskB & BitMaskC & PlaneBitMask) > 0) return(0);
PlaneBitMask<<=1;
}
// TEST EDGES OF TRIANGLE AGAINST PLANES OF CAMERA
float InT, OutT;
if ( PlanesEdgeIsect(P,6,&(A.x),&(B.x),&InT,&OutT) ) return(1);
if ( PlanesEdgeIsect(P,6,&(B.x),&(C.x),&InT,&OutT) ) return(1);
if ( PlanesEdgeIsect(P,6,&(C.x),&(A.x),&InT,&OutT) ) return(1);
// TEST EDGES OF CAMERA AGAINST TRIANGLE
float IsectPt[3];
if ( EdgeTriIsect(&(V[0].x),&(V[4].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[1].x),&(V[5].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[2].x),&(V[6].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[3].x),&(V[7].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[1].x),&(V[0].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[5].x),&(V[4].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[6].x),&(V[7].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[2].x),&(V[3].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[4].x),&(V[7].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[5].x),&(V[6].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[1].x),&(V[2].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
if ( EdgeTriIsect(&(V[0].x),&(V[3].x),&(A.x),&(B.x),&(C.x),IsectPt) ) return(1);
return(0);
}
int CamTriOverlap(const Camera *Cam,
const Vec3f& A, const Vec3f& B, const Vec3f& C)
{
// GET CAMERA VERTICES
Vec3f V[8];
Cam->CalcVerts(V);
// CALCULATE SIX CAMERA PLANES FROM CAMERA VERTICES
float P[6][4];
CalcCamPlanes(V,P);
return( CamTriOverlap(V,P,A,B,C) );
}
//----------------------------------------------------------------------------
// Temporary implementation of CamQuadOverlap (uses CamTriOverlap).
//----------------------------------------------------------------------------
int CamQuadOverlap(
const Camera *Cam,
const Vec3f& A, const Vec3f& B, const Vec3f& C, const Vec3f& D)
{
if ( CamTriOverlap(Cam,A,B,C) ) return(1);
if ( CamTriOverlap(Cam,C,D,A) ) return(1);
return(0);
}
int CamQuadOverlap(
const Camera *Cam,
const float A[3], const float B[3], const float C[3], const float D[3])
{
Vec3f a(A),b(B),c(C),d(D);
return( CamQuadOverlap(Cam,a,b,c,d) );
}
//----------------------------------------------------------------------------
// Calculate the six planes for a camera. User must have prealloced an array
// of 24 floats (6 planes * 4 coeffs each). Two version: 1 that calculates
// the camera vertices, requires the cam verts to be precomputed
//----------------------------------------------------------------------------
void CalcCamPlanes(const Vec3f *V, float P[][4])
{
PlaneEquation(P[0], &(V[2].x),&(V[5].x),&(V[6].x)); // LEFT
PlaneEquation(P[1], &(V[0].x),&(V[7].x),&(V[4].x)); // RIGHT
PlaneEquation(P[2], &(V[3].x),&(V[6].x),&(V[7].x)); // BOTTOM
PlaneEquation(P[3], &(V[1].x),&(V[4].x),&(V[5].x)); // TOP
PlaneEquation(P[4], &(V[1].x),&(V[2].x),&(V[0].x)); // NEAR
PlaneEquation(P[5], &(V[4].x),&(V[6].x),&(V[5].x)); // FAR
}
void CalcCamPlanes(const Camera *Cam, float P[][4])
{
Vec3f V[8];
Cam->CalcVerts(V);
CalcCamPlanes(V,P);
}
//--------------------------------------------------------------------------
// Camera view-frustum/MinMaxBox (AABB) overlap test: given the extents of the
// AABB returns the type of overlap determined (complete out(1), partial (0),
// complete in (-1)) m and M are the min and max extents of the AABB respectively.
// Version is provided that takes in a precomputed set of camera vertices
// and planes
//--------------------------------------------------------------------------
int CamMinMaxBoxOverlap(
const Camera *Cam, const Vec3f V1[8], const float cP[][4],
const Vec3f& m, const Vec3f& M)
{
// GO FOR TRIVIAL REJECTION OR ACCEPTANCE USING "FASTER OVERLAP TEST"
int CompletelyIn=1; // ASSUME COMPLETELY IN UNTIL ONE COUNTEREXAMPLE
int R; // TEST RETURN VALUE
for (int i=0; i<6; i++)
{
R=PlaneMinMaxBoxOverlap(cP[i],&(m.x),&(M.x));
if(R==COMPLETEOUT) return(COMPLETEOUT);
else if(R==PARTIAL) CompletelyIn=0;
}
if (CompletelyIn) return(COMPLETEIN); // CHECK IF STILL COMPLETELY "IN"
// TEST IF VIEW-FRUSTUM EDGES PROTRUDE THROUGH AABB
float InT, OutT;
if ( EdgeMinMaxBoxIsect(&(V1[0].x),&(V1[4].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[1].x),&(V1[5].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[2].x),&(V1[6].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[3].x),&(V1[7].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[0].x),&(V1[1].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[1].x),&(V1[2].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[2].x),&(V1[3].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[3].x),&(V1[0].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[4].x),&(V1[5].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[5].x),&(V1[6].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[6].x),&(V1[7].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
if ( EdgeMinMaxBoxIsect(&(V1[7].x),&(V1[0].x),&(m.x),&(M.x),&InT,&OutT) ) return(PARTIAL);
// COMPUTE VERTICES OF AABB
float bV[8][3];
GetMinMaxBoxVerts(&(m.x),&(M.x),bV);
// TEST FOR PROTRUSION OF AABB EDGES THROUGH VIEW-FRUSTUM
if ( PlanesEdgeIsect(cP,6,bV[0],bV[4],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[1],bV[5],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[2],bV[6],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[3],bV[7],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[0],bV[1],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[1],bV[2],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[2],bV[3],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[3],bV[0],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[4],bV[5],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[5],bV[6],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[6],bV[7],&InT,&OutT) ) return(PARTIAL);
if ( PlanesEdgeIsect(cP,6,bV[7],bV[0],&InT,&OutT) ) return(PARTIAL);
// VF MUST BE COMPLETELY ENCLOSED SINCE PT IS NOT "OUT "OF ANY AABB PLANE.
//return(COMPLETEOUT);
return (PARTIAL);
};
int CamMinMaxBoxOverlap(
const Camera *Cam, const float m[3], const float M[3])
{
// GET CAMERA VERTICES
Vec3f V1[8];
Cam->CalcVerts(V1);
// CALCULATE SIX CAMERA PLANES FROM CAMERA VERTICES
float cP[6][4];
CalcCamPlanes(V1,cP);
return( CamMinMaxBoxOverlap(Cam,V1,cP,m,M) );
};
// ----------------------------------------------------------------------
// Returns 1 if and only if the specified box is completely culled away.
bool VFC(const Camera *Cam, const float m[3], const float M[3])
{
return (CamMinMaxBoxOverlap(Cam, m, M) == COMPLETEOUT);
}
//----------------------------------------------------------------------------
// Given the 8 corner vertices and the 6 side planes for two cameras,
// returns the type of overlap (complete out(1), partial (0), complete in (-1))
// with respect to the first camera.
//----------------------------------------------------------------------------
int CamCamOverlap(
const Vec3f V1[8], const float P1[][4],
const Vec3f V2[8], const float P2[][4])
{
int i, NumVertsOutAllPlanes, NumVertsOutOnePlane;
float InT, OutT;
// TEST ALL CAM1 VERTICES AGAINST PLANES OF CAM2
NumVertsOutAllPlanes=0;
for (i=0; i<6; i++)
{
NumVertsOutOnePlane=0;
for (int j=0; j<8; j++)
NumVertsOutOnePlane += PlanePtOutTest(P2[i],&(V1[i].x));
if (NumVertsOutOnePlane==8) return(1); // TRIVIAL REJECT, COMPLETELY OUT!
NumVertsOutAllPlanes+=NumVertsOutOnePlane;
}
if (NumVertsOutAllPlanes==0) return(0); // TRIVIAL ACCEPT, PARTIAL!
// TEST ALL CAM2 VERTICES AGAINST PLANES OF CAM1
NumVertsOutAllPlanes=0;
for (i=0; i<6; i++)
{
NumVertsOutOnePlane=0;
for (int j=0; j<8; j++)
NumVertsOutOnePlane += PlanePtOutTest(P1[i],&(V2[i].x));
if (NumVertsOutOnePlane==8) return(1); // TRIVIAL REJECT, COMPLETELY OUT!
NumVertsOutAllPlanes+=NumVertsOutOnePlane;
}
if (NumVertsOutAllPlanes==0) return(-1); // TRIVIAL ACCEPT, COMPLETELY IN!
// TEST ALL CAM1 EDGES AGAINST SET OF CAM2 PLANES
if ( PlanesEdgeIsect(P2,6,&(V1[0].x),&(V1[4].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[1].x),&(V1[5].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[2].x),&(V1[6].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[3].x),&(V1[7].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[0].x),&(V1[1].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[1].x),&(V1[2].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[2].x),&(V1[3].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[3].x),&(V1[0].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[4].x),&(V1[5].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[5].x),&(V1[6].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[6].x),&(V1[7].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P2,6,&(V1[7].x),&(V1[0].x),&InT,&OutT) ) return(0);
// TEST ALL CAM2 EDGES AGAINST SET OF CAM1 PLANES
if ( PlanesEdgeIsect(P1,6,&(V2[0].x),&(V2[4].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[1].x),&(V2[5].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[2].x),&(V2[6].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[3].x),&(V2[7].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[0].x),&(V2[1].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[1].x),&(V2[2].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[2].x),&(V2[3].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[3].x),&(V2[0].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[4].x),&(V2[5].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[5].x),&(V2[6].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[6].x),&(V2[7].x),&InT,&OutT) ) return(0);
if ( PlanesEdgeIsect(P1,6,&(V2[7].x),&(V2[0].x),&InT,&OutT) ) return(0);
return(1);
}
int CamCamOverlap(const Camera *Cam1, const Camera *Cam2)
{
// GET CAMERA VERTICES
Vec3f V1[8], V2[8];
Cam1->CalcVerts(V1);
Cam2->CalcVerts(V2);
// CALCULATE SIX CAMERA PLANES FROM CAMERA VERTICES
float P1[6][4], P2[6][4];
CalcCamPlanes(V1,P1);
CalcCamPlanes(V2,P2);
return( CamCamOverlap(V1,P1,V2,P2) );
}
//--------------------------------------------------------------------------
// Given a camera and a plane (defined by four coefficient of implicit
// form: Ax+By+Cz+D=0), reflect the camera about the plane and invert
// back into right-handed system (reflection inverts the space, so we
// have to invert the X-axis and flip the window boundaries).
//--------------------------------------------------------------------------
void CamReflectAboutPlane(Camera *Cam, const float Plane[4])
{
// CREATE PLANAR REFLECTION MATRIX
float M[16];
PlanarReflection16fv(M,Plane);
// XFORM CAMERA
Cam->Xform(M);
// RESULTING CAM IS LEFT-HANDED, FLIP THE X-AXIS, FLIP X WINDOW BOUNDS
Cam->X = -(Cam->X);
float t = -(Cam->wL);
Cam->wL = -(Cam->wR);
Cam->wR = t;
}

View File

@@ -1,58 +0,0 @@
//------------------------------------------------------------------------------
// File : camutils.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// camutils.hpp : a set of camera utility functions
//============================================================================
#include "camera.hpp"
#define COMPLETEOUT 1
#define PARTIAL 0
#define COMPLETEIN -1
int CamTriOverlap(const Vec3f V[8], const float P[][4],
const Vec3f& A, const Vec3f& B, const Vec3f& C);
int CamTriOverlap(const Camera *Cam,
const Vec3f& A, const Vec3f& B, const Vec3f& C);
int CamQuadOverlap(
const Camera *Cam,
const Vec3f& A, const Vec3f& B, const Vec3f& C, const Vec3f& D);
int CamQuadOverlap(
const Camera *Cam,
const float A[3], const float B[3], const float C[3], const float D[3]);
void CalcCamPlanes(const Vec3f V[8], float P[][4]);
void CalcCamPlanes(const Camera *Cam, float P[][4]);
int CamMinMaxBoxOverlap(const Camera *Cam,
const Vec3f cV[8], const float cP[][4],
const Vec3f& m, const Vec3f& M);
int CamMinMaxBoxOverlap(const Camera *Cam,
const float m[3], const float M[3]);
bool VFC(const Camera *Cam, const float m[3], const float M[3]);
int CamCamOverlap(const Vec3f V1[8], const float P1[][4],
const Vec3f V2[8], const float P2[][4]);
int CamCamOverlap(const Camera *Cam1, const Camera *Cam2);
void CamReflectAboutPlane(Camera *Cam, const float Plane[4]);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,606 +0,0 @@
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
/**
(c) Copyright 1993, Silicon Graphics, Inc.
ALL RIGHTS RESERVED
Permission to use, copy, modify, and distribute this software
for any purpose and without fee is hereby granted, provided
that the above copyright notice appear in all copies and that
both the copyright notice and this permission notice appear in
supporting documentation, and that the name of Silicon
Graphics, Inc. not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission.
THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
"AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
PERFORMANCE OF THIS SOFTWARE.
US Government Users Restricted Rights
Use, duplication, or disclosure by the Government is subject to
restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
(c)(1)(ii) of the Rights in Technical Data and Computer
Software clause at DFARS 252.227-7013 and/or in similar or
successor clauses in the FAR or the DOD or NASA FAR
Supplement. Unpublished-- rights reserved under the copyright
laws of the United States. Contractor/manufacturer is Silicon
Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
94039-7311.
OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <math.h>
#include <simgear/compiler.h>
#include "glut_shapes.h"
#include SG_GLU_H
/* Some <math.h> files do not define M_PI... */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
static GLUquadricObj *quadObj;
#define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
static void
initQuadObj(void)
{
quadObj = gluNewQuadric();
if (!quadObj)
/* __glutFatalError("out of memory.") */;
}
/* CENTRY */
void APIENTRY
glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_LINE);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluSphere(quadObj, radius, slices, stacks);
}
void APIENTRY
glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_FILL);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluSphere(quadObj, radius, slices, stacks);
}
void APIENTRY
glutWireCone(GLdouble base, GLdouble height,
GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_LINE);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluCylinder(quadObj, base, 0.0, height, slices, stacks);
}
void APIENTRY
glutSolidCone(GLdouble base, GLdouble height,
GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_FILL);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluCylinder(quadObj, base, 0.0, height, slices, stacks);
}
/* ENDCENTRY */
static void
drawBox(GLfloat size, GLenum type)
{
static GLfloat n[6][3] =
{
{-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{0.0, -1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, -1.0}
};
static GLint faces[6][4] =
{
{0, 1, 2, 3},
{3, 2, 6, 7},
{7, 6, 5, 4},
{4, 5, 1, 0},
{5, 6, 2, 1},
{7, 4, 0, 3}
};
GLfloat v[8][3];
GLint i;
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
for (i = 5; i >= 0; i--) {
glBegin(type);
glNormal3fv(&n[i][0]);
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
glVertex3fv(&v[faces[i][3]][0]);
glEnd();
}
}
/* CENTRY */
void APIENTRY
glutWireCube(GLdouble size)
{
drawBox(size, GL_LINE_LOOP);
}
void APIENTRY
glutSolidCube(GLdouble size)
{
drawBox(size, GL_QUADS);
}
/* ENDCENTRY */
static void
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
glBegin(GL_QUAD_STRIP);
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
}
glEnd();
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
}
/* CENTRY */
void APIENTRY
glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings)
{
glPushAttrib(GL_POLYGON_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
doughnut(innerRadius, outerRadius, nsides, rings);
glPopAttrib();
}
void APIENTRY
glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings)
{
doughnut(innerRadius, outerRadius, nsides, rings);
}
/* ENDCENTRY */
static GLfloat dodec[20][3];
static void
initDodecahedron(void)
{
GLfloat alpha, beta;
alpha = sqrt(2.0 / (3.0 + sqrt(5.0)));
beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
/* *INDENT-OFF* */
dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
/* *INDENT-ON* */
}
#define DIFF3(_a,_b,_c) { \
(_c)[0] = (_a)[0] - (_b)[0]; \
(_c)[1] = (_a)[1] - (_b)[1]; \
(_c)[2] = (_a)[2] - (_b)[2]; \
}
static void
crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
{
GLfloat p[3]; /* in case prod == v1 or v2 */
p[0] = v1[1] * v2[2] - v2[1] * v1[2];
p[1] = v1[2] * v2[0] - v2[2] * v1[0];
p[2] = v1[0] * v2[1] - v2[0] * v1[1];
prod[0] = p[0];
prod[1] = p[1];
prod[2] = p[2];
}
static void
normalize(GLfloat v[3])
{
GLfloat d;
d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
if (d == 0.0) {
/* __glutWarning("normalize: zero length vector"); */
v[0] = d = 1.0;
}
d = 1 / d;
v[0] *= d;
v[1] *= d;
v[2] *= d;
}
static void
pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
{
GLfloat n0[3], d1[3], d2[3];
DIFF3(dodec[a], dodec[b], d1);
DIFF3(dodec[b], dodec[c], d2);
crossprod(d1, d2, n0);
normalize(n0);
glBegin(shadeType);
glNormal3fv(n0);
glVertex3fv(&dodec[a][0]);
glVertex3fv(&dodec[b][0]);
glVertex3fv(&dodec[c][0]);
glVertex3fv(&dodec[d][0]);
glVertex3fv(&dodec[e][0]);
glEnd();
}
static void
dodecahedron(GLenum type)
{
static int inited = 0;
if (inited == 0) {
inited = 1;
initDodecahedron();
}
pentagon(0, 1, 9, 16, 5, type);
pentagon(1, 0, 3, 18, 7, type);
pentagon(1, 7, 11, 10, 9, type);
pentagon(11, 7, 18, 19, 6, type);
pentagon(8, 17, 16, 9, 10, type);
pentagon(2, 14, 15, 6, 19, type);
pentagon(2, 13, 12, 4, 14, type);
pentagon(2, 19, 18, 3, 13, type);
pentagon(3, 0, 5, 12, 13, type);
pentagon(6, 15, 8, 10, 11, type);
pentagon(4, 17, 8, 15, 14, type);
pentagon(4, 12, 5, 16, 17, type);
}
/* CENTRY */
void APIENTRY
glutWireDodecahedron(void)
{
dodecahedron(GL_LINE_LOOP);
}
void APIENTRY
glutSolidDodecahedron(void)
{
dodecahedron(GL_TRIANGLE_FAN);
}
/* ENDCENTRY */
static void
recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
GLenum shadeType)
{
GLfloat q0[3], q1[3];
DIFF3(n1, n2, q0);
DIFF3(n2, n3, q1);
crossprod(q0, q1, q1);
normalize(q1);
glBegin(shadeType);
glNormal3fv(q1);
glVertex3fv(n1);
glVertex3fv(n2);
glVertex3fv(n3);
glEnd();
}
static void
subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
GLenum shadeType)
{
int depth;
GLfloat w0[3], w1[3], w2[3];
GLfloat l;
int i, j, k, n;
depth = 1;
for (i = 0; i < depth; i++) {
for (j = 0; i + j < depth; j++) {
k = depth - i - j;
for (n = 0; n < 3; n++) {
w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
/ depth;
w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
/ depth;
}
l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
w0[0] /= l;
w0[1] /= l;
w0[2] /= l;
l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
w1[0] /= l;
w1[1] /= l;
w1[2] /= l;
l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
w2[0] /= l;
w2[1] /= l;
w2[2] /= l;
recorditem(w1, w0, w2, shadeType);
}
}
}
static void
drawtriangle(int i, GLfloat data[][3], int ndx[][3],
GLenum shadeType)
{
GLfloat *x0, *x1, *x2;
x0 = data[ndx[i][0]];
x1 = data[ndx[i][1]];
x2 = data[ndx[i][2]];
subdivide(x0, x1, x2, shadeType);
}
/* octahedron data: The octahedron produced is centered at the
origin and has radius 1.0 */
static GLfloat odata[6][3] =
{
{1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, -1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, -1.0}
};
static int ondex[8][3] =
{
{0, 4, 2},
{1, 2, 4},
{0, 3, 4},
{1, 4, 3},
{0, 2, 5},
{1, 5, 2},
{0, 5, 3},
{1, 3, 5}
};
static void
octahedron(GLenum shadeType)
{
int i;
for (i = 7; i >= 0; i--) {
drawtriangle(i, odata, ondex, shadeType);
}
}
/* CENTRY */
void APIENTRY
glutWireOctahedron(void)
{
octahedron(GL_LINE_LOOP);
}
void APIENTRY
glutSolidOctahedron(void)
{
octahedron(GL_TRIANGLES);
}
/* ENDCENTRY */
/* icosahedron data: These numbers are rigged to make an
icosahedron of radius 1.0 */
#define X .525731112119133606
#define Z .850650808352039932
static GLfloat idata[12][3] =
{
{-X, 0, Z},
{X, 0, Z},
{-X, 0, -Z},
{X, 0, -Z},
{0, Z, X},
{0, Z, -X},
{0, -Z, X},
{0, -Z, -X},
{Z, X, 0},
{-Z, X, 0},
{Z, -X, 0},
{-Z, -X, 0}
};
static int iindex[20][3] =
{
{0, 4, 1},
{0, 9, 4},
{9, 5, 4},
{4, 5, 8},
{4, 8, 1},
{8, 10, 1},
{8, 3, 10},
{5, 3, 8},
{5, 2, 3},
{2, 7, 3},
{7, 10, 3},
{7, 6, 10},
{7, 11, 6},
{11, 0, 6},
{0, 1, 6},
{6, 1, 10},
{9, 0, 11},
{9, 11, 2},
{9, 2, 5},
{7, 2, 11},
};
static void
icosahedron(GLenum shadeType)
{
int i;
for (i = 19; i >= 0; i--) {
drawtriangle(i, idata, iindex, shadeType);
}
}
/* CENTRY */
void APIENTRY
glutWireIcosahedron(void)
{
icosahedron(GL_LINE_LOOP);
}
void APIENTRY
glutSolidIcosahedron(void)
{
icosahedron(GL_TRIANGLES);
}
/* ENDCENTRY */
/* tetrahedron data: */
#define T 1.73205080756887729
static GLfloat tdata[4][3] =
{
{T, T, T},
{T, -T, -T},
{-T, T, -T},
{-T, -T, T}
};
static int tndex[4][3] =
{
{0, 1, 3},
{2, 1, 0},
{3, 2, 0},
{1, 2, 3}
};
static void
tetrahedron(GLenum shadeType)
{
int i;
for (i = 3; i >= 0; i--)
drawtriangle(i, tdata, tndex, shadeType);
}
/* CENTRY */
void APIENTRY
glutWireTetrahedron(void)
{
tetrahedron(GL_LINE_LOOP);
}
void APIENTRY
glutSolidTetrahedron(void)
{
tetrahedron(GL_TRIANGLES);
}
/* ENDCENTRY */

View File

@@ -1,57 +0,0 @@
#ifndef __GLUT_SHAPES_H
#define __GLUT_SHAPES_H 1
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#if defined(__CYGWIN__) /* && !defined(USING_X) */
#define WIN32
#endif
#if defined(WIN32) /* MINGW and MSC predefine WIN32 */
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include SG_GL_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef APIENTRY
#define APIENTRY
#endif
extern void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
;
extern void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks
);
extern void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices,
GLint stacks);
extern void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices,
GLint stacks);
extern void APIENTRY glutWireCube(GLdouble size);
extern void APIENTRY glutSolidCube(GLdouble size);
extern void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
extern void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
extern void APIENTRY glutWireDodecahedron(void);
extern void APIENTRY glutSolidDodecahedron(void);
extern void APIENTRY glutWireTeapot(GLdouble size);
extern void APIENTRY glutSolidTeapot(GLdouble size);
extern void APIENTRY glutWireOctahedron(void);
extern void APIENTRY glutSolidOctahedron(void);
extern void APIENTRY glutWireTetrahedron(void);
extern void APIENTRY glutSolidTetrahedron(void);
extern void APIENTRY glutWireIcosahedron(void);
extern void APIENTRY glutSolidIcosahedron(void);
#ifdef __cplusplus
}
#endif
#endif // !__GLUT_SHAPES_H

View File

@@ -1,475 +0,0 @@
//------------------------------------------------------------------------------
// File : mat16fv.cpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// $Id$
//----------------------------------------------------------------------------
// mat16fv.cpp : opengl-style float[16] matrix routines.
//
// OPENGL STYLE CAMERA VIEWING MATRIX ROUTINES (PREMULT/ROW VECT, 4x4 MATRIX)
// A POINT IN THE WORLD SPACE CAN BE TRANSFORMED TO A PIXEL ON THE CAMERA
// VIEWPLANE BY TRANSFORMING WITH THE COMPOSITE MATRIX: C = V*P*M
// WHERE V IS THE Viewport XFORM, P IS THE Projection XFORM, AND M IS THE
// Modelview XFORM. The associated inverse matrices are also provided.
// Matrices are of the following form:
// M[16] : 0 4 8 12
// 1 5 9 13
// 2 6 10 14
// 3 7 11 15
//============================================================================
#include <stdio.h>
#include <math.h>
#include "vec3fv.hpp"
float* Copy16fv(float* A, const float* B) // A=B
{
A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
A[8]=B[8]; A[9]=B[9]; A[10]=B[10]; A[11]=B[11];
A[12]=B[12]; A[13]=B[13]; A[14]=B[14]; A[15]=B[15];
return A;
}
float* Mult16fv(float* C, const float* A, const float* B) // C=A*B
{
float tC[16];
tC[0] = A[0]*B[0] + A[4]*B[1] + A[8]*B[2] + A[12]*B[3];
tC[1] = A[1]*B[0] + A[5]*B[1] + A[9]*B[2] + A[13]*B[3];
tC[2] = A[2]*B[0] + A[6]*B[1] + A[10]*B[2] + A[14]*B[3];
tC[3] = A[3]*B[0] + A[7]*B[1] + A[11]*B[2] + A[15]*B[3];
tC[4] = A[0]*B[4] + A[4]*B[5] + A[8]*B[6] + A[12]*B[7];
tC[5] = A[1]*B[4] + A[5]*B[5] + A[9]*B[6] + A[13]*B[7];
tC[6] = A[2]*B[4] + A[6]*B[5] + A[10]*B[6] + A[14]*B[7];
tC[7] = A[3]*B[4] + A[7]*B[5] + A[11]*B[6] + A[15]*B[7];
tC[8] = A[0]*B[8] + A[4]*B[9] + A[8]*B[10] + A[12]*B[11];
tC[9] = A[1]*B[8] + A[5]*B[9] + A[9]*B[10] + A[13]*B[11];
tC[10] = A[2]*B[8] + A[6]*B[9] + A[10]*B[10] + A[14]*B[11];
tC[11] = A[3]*B[8] + A[7]*B[9] + A[11]*B[10] + A[15]*B[11];
tC[12] = A[0]*B[12] + A[4]*B[13] + A[8]*B[14] + A[12]*B[15];
tC[13] = A[1]*B[12] + A[5]*B[13] + A[9]*B[14] + A[13]*B[15];
tC[14] = A[2]*B[12] + A[6]*B[13] + A[10]*B[14] + A[14]*B[15];
tC[15] = A[3]*B[12] + A[7]*B[13] + A[11]*B[14] + A[15]*B[15];
Copy16fv(C,tC);
return(C);
}
float* Mult16fv3fv(float *NewV, const float* M, const float *V)
{
NewV[0] = M[0]*V[0] + M[4]*V[1] + M[8]*V[2];
NewV[1] = M[1]*V[0] + M[5]*V[1] + M[9]*V[2];
NewV[2] = M[2]*V[0] + M[6]*V[1] + M[10]*V[2];
return(NewV);
}
float* Mult16fv3fvPerspDiv(float *NewV, const float* M, const float *V)
{
float W = M[3]*V[0] + M[7]*V[1] + M[11]*V[2] + M[15];
NewV[0] = (M[0]*V[0] + M[4]*V[1] + M[8]*V[2] + M[12]) / W;
NewV[1] = (M[1]*V[0] + M[5]*V[1] + M[9]*V[2] + M[13]) / W;
NewV[2] = (M[2]*V[0] + M[6]*V[1] + M[10]*V[2] + M[14]) / W;
return(NewV);
}
float* Mult16fv4fv(float *NewV, const float* M, const float *V)
{
NewV[0] = M[0]*V[0] + M[4]*V[1] + M[8]*V[2] + M[12]*V[3];
NewV[1] = M[1]*V[0] + M[5]*V[1] + M[9]*V[2] + M[13]*V[3];
NewV[2] = M[2]*V[0] + M[6]*V[1] + M[10]*V[2] + M[14]*V[3];
NewV[3] = M[3]*V[0] + M[7]*V[1] + M[11]*V[2] + M[15]*V[3];
return(NewV);
}
float* Identity16fv(float* M)
{
M[0]=M[5]=M[10]=M[15]=1;
M[1]=M[2]=M[3]=M[4]=M[6]=M[7]=M[8]=M[9]=M[11]=M[12]=M[13]=M[14]=0;
return(M);
}
float* Transpose16fv(float* M)
{
#define SWAP(a,b,t) (t)=(a);(a)=(b);(b)=(t);
float t;
SWAP(M[1],M[4],t);
SWAP(M[2],M[8],t);
SWAP(M[6],M[9],t);
SWAP(M[3],M[12],t);
SWAP(M[7],M[13],t);
SWAP(M[11],M[14],t);
return(M);
}
float* Rotate16fv(float *M, float DegAng, const float Axis[3])
{
float RadAng = DegAng * 0.0174532f;
float ca=(float)cos(RadAng),
sa=(float)sin(RadAng);
if (Axis[0]==1 && Axis[1]==0 && Axis[2]==0) // ABOUT X-AXIS
{
M[0]=1; M[4]=0; M[8]=0; M[12]=0;
M[1]=0; M[5]=ca; M[9]=-sa; M[13]=0;
M[2]=0; M[6]=sa; M[10]=ca; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
if (Axis[0]==0 && Axis[1]==1 && Axis[2]==0) // ABOUT Y-AXIS
{
M[0]=ca; M[4]=0; M[8]=sa; M[12]=0;
M[1]=0; M[5]=1; M[9]=0; M[13]=0;
M[2]=-sa; M[6]=0; M[10]=ca; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
if (Axis[0]==0 && Axis[1]==0 && Axis[2]==1) // ABOUT Z-AXIS
{
M[0]=ca; M[4]=-sa; M[8]=0; M[12]=0;
M[1]=sa; M[5]=ca; M[9]=0; M[13]=0;
M[2]=0; M[6]=0; M[10]=1; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
else // ARBITRARY AXIS
{
float l = Axis[0]*Axis[0]+Axis[1]*Axis[1]+Axis[2]*Axis[2];
float x, y, z;
x=Axis[0],y=Axis[1],z=Axis[2];
if (l > 1.0001f || l < 0.9999f && l!=0)
{
// needs normalization
l=1.0f/(float)sqrt(l);
x*=l; y*=l; z*=l;
}
float x2=x*x, y2=y*y, z2=z*z;
M[0]=x2+ca*(1-x2); M[4]=(x*y)+ca*(-x*y)+sa*(-z); M[8]=(x*z)+ca*(-x*z)+sa*y;
M[1]=(x*y)+ca*(-x*y)+sa*z; M[5]=y2+ca*(1-y2); M[9]=(y*z)+ca*(-y*z)+sa*(-x);
M[2]=(x*z)+ca*(-x*z)+sa*(-y); M[6]=(y*z)+ca*(-y*z)+sa*x; M[10]=z2+ca*(1-z2);
M[12]=M[13]=M[14]=M[3]=M[7]=M[11]=0;
M[15]=1;
}
return(M);
}
float* invRotate16fv(float *M, float DegAng, const float Axis[3])
{
Rotate16fv(M,DegAng,Axis);
Transpose16fv(M);
return(M);
}
float* Scale16fv(float* M, float sx, float sy, float sz)
{
M[0]=sx; M[4]=0; M[8]=0; M[12]=0;
M[1]=0; M[5]=sy; M[9]=0; M[13]=0;
M[2]=0; M[6]=0; M[10]=sz; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
float* invScale16fv(float* M, float sx, float sy, float sz)
{
M[0]=1/sx; M[4]=0; M[8]=0; M[12]=0;
M[1]=0; M[5]=1/sy; M[9]=0; M[13]=0;
M[2]=0; M[6]=0; M[10]=1/sz; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
float* Translate16fv(float* M, float tx, float ty, float tz)
{
M[0]=1; M[4]=0; M[8]=0; M[12]=tx;
M[1]=0; M[5]=1; M[9]=0; M[13]=ty;
M[2]=0; M[6]=0; M[10]=1; M[14]=tz;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
float* invTranslate16fv(float* M, float tx, float ty, float tz)
{
M[0]=1; M[4]=0; M[8]=0; M[12]=-tx;
M[1]=0; M[5]=1; M[9]=0; M[13]=-ty;
M[2]=0; M[6]=0; M[10]=1; M[14]=-tz;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
float* LookAt(float* M,
const float Eye[3],
const float LookAtPt[3],
const float ViewUp[3])
{
float X[3], Y[3], Z[3];
Subtract3fv(Z,Eye,LookAtPt); Normalize3fv(Z);
CrossProd3fv(X,ViewUp,Z); Normalize3fv(X);
CrossProd3fv(Y,Z,X); Normalize3fv(Y);
M[0]=X[0]; M[4]=X[1]; M[8]=X[2]; M[12]=-DotProd3fv(X,Eye); // TRANS->ROT
M[1]=Y[0]; M[5]=Y[1]; M[9]=Y[2]; M[13]=-DotProd3fv(Y,Eye);
M[2]=Z[0]; M[6]=Z[1]; M[10]=Z[2]; M[14]=-DotProd3fv(Z,Eye);
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
float* invLookAt(float* M,
const float Eye[3],
const float LookAtPt[3],
const float ViewUp[3])
{
float X[3], Y[3], Z[3];
Subtract3fv(Z,Eye,LookAtPt); Normalize3fv(Z);
CrossProd3fv(X,ViewUp,Z); Normalize3fv(X);
CrossProd3fv(Y,Z,X); Normalize3fv(Y);
M[0]=X[0]; M[4]=Y[0]; M[8]=Z[0]; M[12]=Eye[0]; // ROT->TRANS
M[1]=X[1]; M[5]=Y[1]; M[9]=Z[1]; M[13]=Eye[1];
M[2]=X[2]; M[6]=Y[2]; M[10]=Z[2]; M[14]=Eye[2];
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
float* Frustum16fv(float* M, float l, float r, float b, float t,
float n, float f)
{
M[0]=(2*n)/(r-l); M[4]=0; M[8]=(r+l)/(r-l); M[12]=0;
M[1]=0; M[5]=(2*n)/(t-b); M[9]=(t+b)/(t-b); M[13]=0;
M[2]=0; M[6]=0; M[10]=-(f+n)/(f-n); M[14]=(-2*f*n)/(f-n);
M[3]=0; M[7]=0; M[11]=-1; M[15]=0;
return(M);
}
float* invFrustum16fv(float* M, float l, float r, float b, float t,
float n, float f)
{
M[0]=(r-l)/(2*n); M[4]=0; M[8]=0; M[12]=(r+l)/(2*n);
M[1]=0; M[5]=(t-b)/(2*n); M[9]=0; M[13]=(t+b)/(2*n);
M[2]=0; M[6]=0; M[10]=0; M[14]=-1;
M[3]=0; M[7]=0; M[11]=-(f-n)/(2*f*n); M[15]=(f+n)/(2*f*n);
return(M);
}
float* Perspective(float* M, float Yfov, float Aspect,
float Ndist, float Fdist)
{
Yfov *= 0.0174532f; // CONVERT TO RADIANS
float wT=(float)tan(Yfov*0.5f)*Ndist, wB=-wT;
float wR=wT*Aspect, wL=-wR;
Frustum16fv(M,wL,wR,wB,wT,Ndist,Fdist);
return(M);
}
float* invPerspective(float* M, float Yfov, float Aspect,
float Ndist, float Fdist)
{
Yfov *= 0.0174532f; // CONVERT TO RADIANS
float wT=(float)tan(Yfov*0.5f)*Ndist, wB=-wT;
float wR=wT*Aspect, wL=-wR;
invFrustum16fv(M,wL,wR,wB,wT,Ndist,Fdist);
return(M);
}
float* Viewing16fv(
float* M,
const float X[3], const float Y[3], const float Z[3], const float O[3])
{
M[0]=X[0]; M[4]=X[1]; M[8]=X[2]; M[12]=-DotProd3fv(X,O);
M[1]=Y[0]; M[5]=Y[1]; M[9]=Y[2]; M[13]=-DotProd3fv(Y,O);
M[2]=Z[0]; M[6]=Z[1]; M[10]=Z[2]; M[14]=-DotProd3fv(Z,O);
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
// THE INVERSE OF Viewing16fv,
// THIS TAKES A VIEW MATRIX AND RETURNS VIEWING AXES.
// MATRIX ASSUMED TO BE ORTHONORMAL
void Viewing2CoordFrame16fv(
const float *M, float X[3], float Y[3], float Z[3], float O[3])
{
X[0]=M[0]; X[1]=M[4]; X[2]=M[8]; O[0]=-DotProd3fv(M,M+12);
Y[0]=M[1]; Y[1]=M[5]; Y[2]=M[9]; O[1]=-DotProd3fv(M+4,M+12);
Z[0]=M[2]; Z[1]=M[6]; Z[2]=M[10]; O[2]=-DotProd3fv(M+8,M+12);
};
float* invViewing16fv(
float* M,
const float X[3], const float Y[3], const float Z[3], const float O[3])
{
M[0]=X[0]; M[4]=Y[0]; M[8]=Z[0]; M[12]=O[0];
M[1]=X[1]; M[5]=Y[1]; M[9]=Z[1]; M[13]=O[1];
M[2]=X[2]; M[6]=Y[2]; M[10]=Z[2]; M[14]=O[2];
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
float* Viewport16fv(float* M, int WW, int WH)
{
float WW2=(float)WW*0.5f, WH2=(float)WH*0.5f;
M[0]=WW2; M[4]=0; M[8]=0; M[12]=WW2;
M[1]=0; M[5]=WH2; M[9]=0; M[13]=WH2;
M[2]=0; M[6]=0; M[10]=0.5f; M[14]=0.5f;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
float* invViewport16fv(float* M, int WW, int WH)
{
float WW2=2.0f/(float)WW, WH2=2.0f/(float)WH;
M[0]=WW2; M[4]=0; M[8]=0; M[12]=-1.0;
M[1]=0; M[5]=WH2; M[9]=0; M[13]=-1.0;
M[2]=0; M[6]=0; M[10]=2.0; M[14]=-1.0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
//--------------------------------------------------------------------------
// Given the coefficient [A B C D] of a plane in the implicit form
// Ax+By+Cz+D=0 (see plane.hpp), this routine generates a reflection matrix
// that will "reflect" all points/vectors about the given plane.
// NOTE: the plane is assumed to be normalized: normal vector (A,B,C) is
// normalized (unit-length), and D is the negative distance from the origin
// to the plane along the normal.
//--------------------------------------------------------------------------
float* PlanarReflection16fv(float M[16], const float P[4])
{
float AA=P[0]*P[0], AB=P[0]*P[1], AC=P[0]*P[2], AD=P[0]*P[3],
BB=P[1]*P[1], BC=P[1]*P[2], BD=P[1]*P[3],
CC=P[2]*P[2], CD=P[2]*P[3];
M[0]=1-2*AA; M[4]=-2*AB; M[8]=-2*AC; M[12]=-2*AD;
M[1]=-2*AB; M[5]=1-2*BB; M[9]=-2*BC; M[13]=-2*BD;
M[2]=-2*AC; M[6]=-2*BC; M[10]=1-2*CC; M[14]=-2*CD;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
//--------------------------------------------------------------------------
// Returns a matrix that will xform a point from the given object-space
// coordinate frame to world space
// A composite matrix is formed as follows:
// C = Translation * Rotation * Scaling (using column vectors/pre-multiplication)
// WorldPt = C * ModelPt
// The corresponding inverse Xform is also provided (GetWorld2ObjXform)
//--------------------------------------------------------------------------
float* Obj2WorldXform16fv(
float *M,
const float X[3], const float Y[3], const float Z[3],
const float O[3], float Scale)
{
float sX[3], sY[3], sZ[3]; // CREATE SCALED VERSION OF ROT AXES
ScalarMult3fv(sX,X,Scale);
ScalarMult3fv(sY,Y,Scale);
ScalarMult3fv(sZ,Z,Scale);
M[0]=sX[0]; M[4]=sY[0]; M[8]=sZ[0]; M[12]=O[0];
M[1]=sX[1]; M[5]=sY[1]; M[9]=sZ[1]; M[13]=O[1];
M[2]=sX[2]; M[6]=sY[2]; M[10]=sZ[2]; M[14]=O[2];
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
float* World2ObjXform16fv(
float *M,
const float X[3], const float Y[3], const float Z[3],
const float O[3], float Scale)
{
if (Scale<=0) { printf("Too small scale!\n"); Scale=1; }
float invScale = 1/Scale;
float sX[3], sY[3], sZ[3];
ScalarMult3fv(sX,X,invScale);
ScalarMult3fv(sY,Y,invScale);
ScalarMult3fv(sZ,Z,invScale);
M[0]=sX[0]; M[4]=sX[1]; M[8]=sX[2]; M[12]=-DotProd3fv(O,sX);
M[1]=sY[0]; M[5]=sY[1]; M[9]=sY[2]; M[13]=-DotProd3fv(O,sY);
M[2]=sZ[0]; M[6]=sZ[1]; M[10]=sZ[2]; M[14]=-DotProd3fv(O,sZ);
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
return(M);
}
// ONLY TRANSLATES, ROTATES, AND SCALES ARE ALLOWED
float XformCoordFrame16fv(
const float *M, float X[3], float Y[3], float Z[3], float O[3])
{
Set3fv(X, X[0]*M[0] + X[1]*M[4] + X[2]*M[8],
X[0]*M[1] + X[1]*M[5] + X[2]*M[9],
X[0]*M[2] + X[1]*M[6] + X[2]*M[10] );
Set3fv(Y, Y[0]*M[0] + Y[1]*M[4] + Y[2]*M[8],
Y[0]*M[1] + Y[1]*M[5] + Y[2]*M[9],
Y[0]*M[2] + Y[1]*M[6] + Y[2]*M[10] );
Set3fv(Z, Z[0]*M[0] + Z[1]*M[4] + Z[2]*M[8],
Z[0]*M[1] + Z[1]*M[5] + Z[2]*M[9],
Z[0]*M[2] + Z[1]*M[6] + Z[2]*M[10] );
Set3fv(O, O[0]*M[0] + O[1]*M[4] + O[2]*M[8] + M[12],
O[0]*M[1] + O[1]*M[5] + O[2]*M[9] + M[13],
O[0]*M[2] + O[1]*M[6] + O[2]*M[10] + M[14] );
// MUST RENORMALIZE AXES TO FIND THE UNIFORM SCALE
float Scale = Length3fv(X);
ScalarDiv3fv(X,Scale);
ScalarDiv3fv(Y,Scale);
ScalarDiv3fv(Z,Scale);
// RETURN UNIFORM SCALING OF AXES (how much coordinate frame was scaled)
return(Scale);
};
//----------------------------------------------------------------------------
// Given a complete definition for a particular view (viewing, projection,
// and viewport), returns the COMPOSITE xform matrix that takes a point in the
// world space to a screen space (pixel) point. The inverse is also provided.
//----------------------------------------------------------------------------
float* Screen2WorldXform16fv(
float* M,
const float X[3], const float Y[3], const float Z[3], // VIEWING AXES
const float O[3], // VIEWING ORIGIN
float l, float r, float b, float t, float n, float f, // PROJECTION
int WW, int WH) // VIEWPORT
{
// C = InverseModelview * InverseProjection * InverseViewport
float N[16];
invViewing16fv(M,X,Y,Z,O);
invFrustum16fv(N,l,r,b,t,n,f);
Mult16fv(M,M,N); // M=M*N;
invViewport16fv(N,WW,WH);
Mult16fv(M,M,N); // M=M*N;
return(M);
}
float* World2ScreenXform16fv(
float* M,
const float X[3], const float Y[3], const float Z[3], // VIEWING AXES
const float O[3], // VIEWING ORIGIN
float l, float r, float b, float t, float n, float f, // PROJECTION
int WW, int WH) // VIEWPORT
{
// C = Viewport * Projection * Modelview
float N[16];
Viewport16fv(M,WW,WH);
Frustum16fv(N,l,r,b,t,n,f);
Mult16fv(M,M,N); // M=M*N;
Viewing16fv(N,X,Y,Z,O);
Mult16fv(M,M,N); // M=M*N;
return(M);
}
void Print16fv(const float* M)
{
printf("\n%f %f %f %f\n",M[0],M[4],M[8],M[12]);
printf("%f %f %f %f\n",M[1],M[5],M[9],M[13]);
printf("%f %f %f %f\n",M[2],M[6],M[10],M[14]);
printf("%f %f %f %f\n\n",M[3],M[7],M[11],M[15]);
}

View File

@@ -1,119 +0,0 @@
//------------------------------------------------------------------------------
// File : mat16fv.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// mat16fv.hpp : opengl-style float[16] matrix routines.
//----------------------------------------------------------------------------
// $Id$
//============================================================================
float* Copy16fv(float* A, const float* B); // A=B
float* Mult16fv(float* C, const float* A, const float* B); // C=A*B
float* Mult16fv3fv(
float *NewV, const float* M, const float *V); // NewV = M * [Vx,Vy,Vz,0]
float* Mult16fv3fvPerspDiv(
float *NewV, const float* M, const float *V); // NewV = M * [Vx,Vy,Vz,1]
float* Mult16fv4fv(
float *NewV, const float* M, const float *V); // NewV = M * [Vx,Vy,Vz,Vw]
float* Identity16fv(float* M);
float* Transpose16fv(float* M);
float* Rotate16fv(float *M, float DegAng, const float Axis[3]);
float* invRotate16fv(float *M, float DegAng, const float Axis[3]);
float* Scale16fv(float* M, float sx, float sy, float sz);
float* invScale16fv(float* M, float sx, float sy, float sz);
float* Translate16fv(float* M, float tx, float ty, float tz);
float* invTranslate16fv(float* M, float tx, float ty, float tz);
float* LookAt(
float* M,
const float Eye[3],
const float LookAtPt[3],
const float ViewUp[3]);
float* invLookAt(
float* M,
const float Eye[3],
const float LookAtPt[3],
const float ViewUp[3]);
float* Frustum16fv(
float* M, float l, float r, float b, float t, float n, float f);
float* invFrustum16fv(
float* M, float l, float r, float b, float t, float n, float f);
float* Perspective(
float* M, float Yfov, float Aspect, float Ndist, float Fdist);
float* invPerspective(
float* M, float Yfov, float Aspect, float Ndist, float Fdist);
float* Viewing16fv(
float* M,
const float X[3], const float Y[3], const float Z[3],
const float O[3]);
float* invViewing16fv(
float* M,
const float X[3], const float Y[3], const float Z[3],
const float O[3]);
void Viewing2CoordFrame16fv(
const float *M, float X[3], float Y[3], float Z[3], float O[3]);
float* Viewport16fv(float* M, int WW, int WH);
float* invViewport16fv(float* M, int WW, int WH);
float* PlanarReflection16fv(float M[16], const float P[4]);
float XformCoordFrame16fv(
const float *M, float X[3], float Y[3], float Z[3], float O[3]);
float* Obj2WorldXform16fv(
float *M, float X[3], float Y[3], float Z[3], float O[3], float Scale);
float* World2ObjXform16fv(
float *M,
const float X[3],
const float Y[3],
const float Z[3],
const float O[3],
float Scale);
float* Screen2WorldXform16fv(
float* M,
const float X[3], const float Y[3], const float Z[3], const float O[3],
float l, float r, float b, float t, float n, float f,
int WW, int WH);
float* World2ScreenXform16fv(
float* M,
const float X[3], const float Y[3], const float Z[3], const float O[3],
float l, float r, float b, float t, float n, float f,
int WW, int WH);
void Print16fv(const float* M);

View File

@@ -1,113 +0,0 @@
//------------------------------------------------------------------------------
// File : mat33.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// mat33.hpp : 3x3 matrix template.
//============================================================================
#ifndef _MAT33_
#define _MAT33_
#include "vec3f.hpp"
#include "mat44.hpp"
static const float Mat33TORADS = 0.0174532f;
static const float Mat33VIEWPORT_TOL = 0.001f;
//----------------------------------------------------------------------------
// M[9] = [ 0 3 6 ]
// [ 1 4 7 ]
// [ 2 5 8 ]
//
//
//
// [ x' y' z' ] = [ 0 3 6 ] [ x ]
// [ 1 4 7 ] * [ y ]
// [ 2 5 8 ] [ z ]
//----------------------------------------------------------------------------
template<class Type>
class Mat33
{
public:
Type M[9]; // 0,1,2 = 1st col; 3,4,5 = 2nd col; etc.
Mat33();
Mat33(const Type *N);
Mat33(Type M0, Type M3, Type M6,
Type M1, Type M4, Type M7,
Type M2, Type M5, Type M8);
Mat33<Type>& operator = (const Mat33& A); // ASSIGNMENT (=)
// ASSIGNMENT (=) FROM AN ARRAY OF Type
Mat33<Type>& operator = (const Type* a);
Mat33<Type> operator * (const Mat33& A) const; // MULTIPLICATION (*)
// MAT-VECTOR MULTIPLICATION (*)
Vec3<Type> operator * (const Vec3<Type>& V) const;
// MAT-VECTOR PRE-MULTIPLICATON (*)
friend Vec3<Type> operator * (const Vec3<Type>& V, const Mat33<Type>& M);
// SCALAR POST-MULTIPLICATION
Mat33<Type> operator * (Type a) const;
// SCALAR PRE-MULTIPLICATION
friend Mat33<Type> operator * (Type a, const Mat44<Type>& M);
Mat33<Type> operator / (Type a) const; // SCALAR DIVISION
Mat33<Type> operator + (Mat33& M) const; // ADDITION (+)
Mat33<Type>& operator += (Mat33& M); // ACCUMULATE ADD (+=)
Mat33<Type>& operator -= (Mat33& M); // ACCUMULATE SUB (-=)
Mat33<Type>& operator *= (Type a); // ACCUMULATE MULTIPLY (*=)
Mat33<Type>& operator /= (Type a); // ACCUMULATE DIVIDE (/=)
bool Inverse(Mat33<Type> &inv, Type tolerance) const;// MATRIX INVERSE
operator const Type*() const; // CAST TO A Type ARRAY
operator Type*(); // CAST TO A Type ARRAY
void RowMajor(Type m[9]); // return array in row-major order
Type& operator()(int col, int row); // 2D ARRAY ACCESSOR
const Type& operator()(int col, int row) const; // 2D ARRAY ACCESSOR
void Set(const Type* a); // SAME AS ASSIGNMENT (=) FROM AN ARRAY OF TypeS
void Set(Type M0, Type M3, Type M6,
Type M1, Type M4, Type M7,
Type M2, Type M5, Type M8);
void Identity();
void Zero();
void Transpose();
void Scale(Type Sx, Type Sy, Type Sz);
void Scale(const Vec3<Type>& S);
void invScale(Type Sx, Type Sy, Type Sz);
void invScale(const Vec3<Type>& S);
void Rotate(Type DegAng, const Vec3<Type>& Axis);
void invRotate(Type DegAng, const Vec3<Type>& Axis);
void Star(const Vec3<Type>& v); // SKEW-SYMM MATRIX EQUIV TO CROSS PROD WITH V
void OuterProduct(const Vec3<Type>& u, const Vec3<Type>& v); // SET TO u * v^t
Type Trace() const;
void Print() const;
void CopyInto(Type *Mat) const;
static void SWAP(Type& a, Type& b) {Type t; t=a;a=b;b=t;}
};
#include "mat33impl.hpp"
typedef Mat33<float> Mat33f;
typedef Mat33<double> Mat33d;
#endif

View File

@@ -1,412 +0,0 @@
//------------------------------------------------------------------------------
// File : mat33impl.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// mat33impl.hpp : 3x3 matrix template.
// This is the template implementation file. It is included by mat33.hpp.
//============================================================================
//---------------------------------------------------------------------------
// CONSTRUCTORS
//---------------------------------------------------------------------------
template<class Type>
Mat33<Type>::Mat33()
{
Identity();
}
template<class Type>
Mat33<Type>::Mat33(const Type *N)
{
M[0]=N[0]; M[3]=N[3]; M[6]=N[6];
M[1]=N[1]; M[4]=N[4]; M[7]=N[7];
M[2]=N[2]; M[5]=N[5]; M[8]=N[8];
}
template<class Type>
Mat33<Type>::Mat33(Type M0, Type M3, Type M6,
Type M1, Type M4, Type M7,
Type M2, Type M5, Type M8)
{
M[0]=M0; M[3]=M3; M[6]=M6;
M[1]=M1; M[4]=M4; M[7]=M7;
M[2]=M2; M[5]=M5; M[8]=M8;
}
//---------------------------------------------------------------------------
// MATRIX/MATRIX AND MATRIX/VECTOR OPERATORS
//---------------------------------------------------------------------------
template<class Type>
Mat33<Type>& Mat33<Type>::operator = (const Mat33& A) // ASSIGNMENT (=)
{
M[0]=A.M[0]; M[3]=A.M[3]; M[6]=A.M[6];
M[1]=A.M[1]; M[4]=A.M[4]; M[7]=A.M[7];
M[2]=A.M[2]; M[5]=A.M[5]; M[8]=A.M[8];
return(*this);
}
template<class Type>
Mat33<Type>& Mat33<Type>::operator = (const Type* a) {
for (int i=0;i<9;i++) {
M[i] = a[i];
}
return *this;
}
template<class Type>
Mat33<Type> Mat33<Type>::operator * (const Mat33& A) const // MULTIPLICATION (*)
{
Mat33<Type> NewM(
M[0]*A.M[0] + M[3]*A.M[1] + M[6]*A.M[2], // ROW 1
M[0]*A.M[3] + M[3]*A.M[4] + M[6]*A.M[5],
M[0]*A.M[6] + M[3]*A.M[7] + M[6]*A.M[8],
M[1]*A.M[0] + M[4]*A.M[1] + M[7]*A.M[2], // ROW 2
M[1]*A.M[3] + M[4]*A.M[4] + M[7]*A.M[5],
M[1]*A.M[6] + M[4]*A.M[7] + M[7]*A.M[8],
M[2]*A.M[0] + M[5]*A.M[1] + M[8]*A.M[2], // ROW 3
M[2]*A.M[3] + M[5]*A.M[4] + M[8]*A.M[5],
M[2]*A.M[6] + M[5]*A.M[7] + M[8]*A.M[8]);
return(NewM);
}
// MAT-VECTOR MULTIPLICATION (*)
template<class Type>
Vec3<Type> Mat33<Type>::operator * (const Vec3<Type>& V) const
{
Vec3<Type> NewV;
NewV.x = M[0]*V.x + M[3]*V.y + M[6]*V.z;
NewV.y = M[1]*V.x + M[4]*V.y + M[7]*V.z;
NewV.z = M[2]*V.x + M[5]*V.y + M[8]*V.z;
return(NewV);
}
// MAT-VECTOR PRE-MULTIPLICATON (*) (non-member)
// interpreted as V^t M
template<class Type>
Vec3<Type> operator *(const Vec3<Type>& V, const Mat33<Type>& A)
{
Vec3<Type> NewV;
NewV.x = A[0]*V.x + A[1]*V.y + A[2]*V.z;
NewV.y = A[3]*V.x + A[4]*V.y + A[5]*V.z;
NewV.z = A[6]*V.x + A[7]*V.y + A[8]*V.z;
return(NewV);
}
// SCALAR POST-MULTIPLICATION
template<class Type>
Mat33<Type> Mat33<Type>::operator * (Type a) const
{
Mat33<Type> NewM;
for (int i = 0; i < 9; i++)
NewM[i] = M[i]*a;
return(NewM);
}
// SCALAR PRE-MULTIPLICATION (non-member)
template <class Type>
Mat33<Type> operator * (Type a, const Mat44<Type>& M)
{
Mat33<Type> NewM;
for (int i = 0; i < 9; i++)
NewM[i] = a*M[i];
return(NewM);
}
template <class Type>
Mat33<Type> Mat33<Type>::operator / (Type a) const // SCALAR DIVISION
{
Mat33<Type> NewM;
Type ainv = Type(1.0)/a;
for (int i = 0; i < 9; i++)
NewM[i] = M[i]*ainv;
return(NewM);
}
template <class Type>
Mat33<Type> Mat33<Type>::operator + (Mat33& N) const // ADDITION (+)
{
Mat33<Type> NewM;
for (int i = 0; i < 9; i++)
NewM[i] = M[i]+N.M[i];
return(NewM);
}
template <class Type>
Mat33<Type>& Mat33<Type>::operator += (Mat33& N) // ACCUMULATE ADD (+=)
{
for (int i = 0; i < 9; i++)
M[i] += N.M[i];
return(*this);
}
template <class Type>
Mat33<Type>& Mat33<Type>::operator -= (Mat33& N) // ACCUMULATE SUB (-=)
{
for (int i = 0; i < 9; i++)
M[i] -= N.M[i];
return(*this);
}
template <class Type>
Mat33<Type>& Mat33<Type>::operator *= (Type a) // ACCUMULATE MULTIPLY (*=)
{
for (int i = 0; i < 9; i++)
M[i] *= a;
return(*this);
}
template <class Type>
Mat33<Type>& Mat33<Type>::operator /= (Type a) // ACCUMULATE DIVIDE (/=)
{
Type ainv = Type(1.0)/a;
for (int i = 0; i < 9; i++)
M[i] *= ainv;
return(*this);
}
template<class Type>
bool Mat33<Type>::Inverse(Mat33<Type> &inv, Type tolerance) const // MATRIX INVERSE
{
// Invert using cofactors.
inv[0] = M[4]*M[8] - M[7]*M[5];
inv[3] = M[6]*M[5] - M[3]*M[8];
inv[6] = M[3]*M[7] - M[6]*M[4];
inv[1] = M[7]*M[2] - M[1]*M[8];
inv[4] = M[0]*M[8] - M[6]*M[2];
inv[7] = M[6]*M[1] - M[0]*M[7];
inv[2] = M[1]*M[5] - M[4]*M[2];
inv[5] = M[3]*M[2] - M[0]*M[5];
inv[8] = M[0]*M[4] - M[3]*M[1];
Type det = M[0]*inv[0] + M[3]*inv[1] + M[6]*inv[2];
if (fabs(det) <= tolerance) // singular
return false;
Type invDet = 1.0f / det;
for (int i = 0; i < 9; i++) {
inv[i] *= invDet;
}
return true;
}
template<class Type>
Mat33<Type>::operator const Type*() const
{
return M;
}
template<class Type>
Mat33<Type>::operator Type*()
{
return M;
}
template<class Type>
void Mat33<Type>::RowMajor(Type m[9])
{
m[0] = M[0]; m[1] = M[3]; m[2] = M[6];
m[3] = M[1]; m[4] = M[4]; m[5] = M[7];
m[6] = M[2]; m[7] = M[5]; m[8] = M[8];
}
template<class Type>
Type& Mat33<Type>::operator()(int col, int row)
{
return M[3*col+row];
}
template<class Type>
const Type& Mat33<Type>::operator()(int col, int row) const
{
return M[3*col+row];
}
template<class Type>
void Mat33<Type>::Set(const Type* a)
{
for (int i=0;i<9;i++) {
M[i] = a[i];
}
}
template<class Type>
void Mat33<Type>::Set(Type M0, Type M3, Type M6,
Type M1, Type M4, Type M7,
Type M2, Type M5, Type M8)
{
M[0]=M0; M[3]=M3; M[6]=M6;
M[1]=M1; M[4]=M4; M[7]=M7;
M[2]=M2; M[5]=M5; M[8]=M8;
}
//---------------------------------------------------------------------------
// Standard Matrix Operations
//---------------------------------------------------------------------------
template<class Type>
void Mat33<Type>::Identity()
{
M[0]=M[4]=M[8]=1;
M[1]=M[2]=M[3]=M[5]=M[6]=M[7]=0;
}
template<class Type>
void Mat33<Type>::Zero()
{
M[0]=M[1]=M[2]=M[3]=M[4]=M[5]=M[6]=M[7]=M[8]=0;
}
template<class Type>
void Mat33<Type>::Transpose()
{
SWAP(M[1],M[3]);
SWAP(M[2],M[6]);
SWAP(M[5],M[7]);
}
//---------------------------------------------------------------------------
// Standard Matrix Affine Transformations
//---------------------------------------------------------------------------
template<class Type>
void Mat33<Type>::Scale(Type Sx, Type Sy, Type Sz)
{
M[0]=Sx; M[3]=0; M[6]=0;
M[1]=0; M[4]=Sy; M[7]=0;
M[2]=0; M[5]=0; M[8]=Sz;
}
template<class Type>
void Mat33<Type>::Scale(const Vec3<Type>& S)
{
M[0]=S.x; M[3]=0; M[6]=0;
M[1]=0; M[4]=S.y; M[7]=0;
M[2]=0; M[5]=0; M[8]=S.z;
}
template<class Type>
void Mat33<Type>::invScale(Type Sx, Type Sy, Type Sz)
{
M[0]=1/Sx; M[3]=0; M[6]=0;
M[1]=0; M[4]=1/Sy; M[7]=0;
M[2]=0; M[5]=0; M[8]=1/Sz;
}
template<class Type>
void Mat33<Type>::invScale(const Vec3<Type>& S)
{
M[0]=1/S.x; M[3]=0; M[6]=0;
M[1]=0; M[4]=1/S.y; M[7]=0;
M[2]=0; M[5]=0; M[8]=1/S.z;
}
template<class Type>
void Mat33<Type>::Rotate(Type DegAng, const Vec3<Type>& Axis)
{
Type RadAng = DegAng*Mat33TORADS;
Type ca=(Type)cos(RadAng),
sa=(Type)sin(RadAng);
if (Axis.x==1 && Axis.y==0 && Axis.z==0) // ABOUT X-AXIS
{
M[0]=1; M[3]=0; M[6]=0;
M[1]=0; M[4]=ca; M[7]=-sa;
M[2]=0; M[5]=sa; M[8]=ca;
}
else if (Axis.x==0 && Axis.y==1 && Axis.z==0) // ABOUT Y-AXIS
{
M[0]=ca; M[3]=0; M[6]=sa;
M[1]=0; M[4]=1; M[7]=0;
M[2]=-sa; M[5]=0; M[8]=ca;
}
else if (Axis.x==0 && Axis.y==0 && Axis.z==1) // ABOUT Z-AXIS
{
M[0]=ca; M[3]=-sa; M[6]=0;
M[1]=sa; M[4]=ca; M[7]=0;
M[2]=0; M[5]=0; M[8]=1;
}
else // ARBITRARY AXIS
{
Type l = Axis.LengthSqr();
Type x, y, z;
x=Axis.x, y=Axis.y, z=Axis.z;
if (l > Type(1.0001) || l < Type(0.9999) && l!=0)
{
// needs normalization
l=Type(1.0)/sqrt(l);
x*=l; y*=l; z*=l;
}
Type x2=x*x, y2=y*y, z2=z*z;
M[0]=x2+ca*(1-x2); M[3]=(x*y)+ca*(-x*y)+sa*(-z); M[6]=(x*z)+ca*(-x*z)+sa*y;
M[1]=(x*y)+ca*(-x*y)+sa*z; M[4]=y2+ca*(1-y2); M[7]=(y*z)+ca*(-y*z)+sa*(-x);
M[2]=(x*z)+ca*(-x*z)+sa*(-y); M[5]=(y*z)+ca*(-y*z)+sa*x; M[8]=z2+ca*(1-z2);
}
}
template<class Type>
void Mat33<Type>::invRotate(Type DegAng, const Vec3<Type>& Axis)
{
Rotate(DegAng,Axis);
Transpose();
}
template <class Type>
inline void Mat33<Type>::Star(const Vec3<Type>& v)
{
M[0]= 0; M[3]=-v.z; M[6]= v.y;
M[1]= v.z; M[4]= 0; M[7]=-v.x;
M[2]=-v.y; M[5]= v.x; M[8]= 0;
}
template <class Type>
inline void Mat33<Type>::OuterProduct(const Vec3<Type>& u, const Vec3<Type>& v)
{
M[0]=u.x*v.x; M[3]=u.x*v.y; M[6]=u.x*v.z;
M[1]=u.y*v.x; M[4]=u.y*v.y; M[7]=u.y*v.z;
M[2]=u.z*v.x; M[5]=u.z*v.y; M[8]=u.z*v.z;
}
template<class Type>
inline Type Mat33<Type>::Trace() const
{
return M[0] + M[4] + M[8];
}
//---------------------------------------------------------------------------
// Handy matrix printing routine.
//---------------------------------------------------------------------------
template<class Type>
void Mat33<Type>::Print() const
{
printf("\n%f %f %f\n",M[0],M[3],M[6]);
printf("%f %f %f\n",M[1],M[4],M[7]);
printf("%f %f %f\n",M[2],M[5],M[8]);
}
//---------------------------------------------------------------------------
// Copy contents of matrix into matrix array.
//---------------------------------------------------------------------------
template<class Type>
void Mat33<Type>::CopyInto(Type *Mat) const
{
Mat[0]=M[0]; Mat[3]=M[3]; Mat[6]=M[6];
Mat[1]=M[1]; Mat[4]=M[4]; Mat[7]=M[7];
Mat[2]=M[2]; Mat[5]=M[5]; Mat[8]=M[8];
}

View File

@@ -1,135 +0,0 @@
//------------------------------------------------------------------------------
// File : mat44.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// mat44.hpp : 4x4 OpenGL-style matrix template.
//============================================================================
#ifndef _MAT44_
#define _MAT44_
#include "vec3f.hpp"
#include "vec4f.hpp"
static const float Mat44TORADS = 0.0174532f;
static const float Mat44VIEWPORT_TOL = 0.001f;
//----------------------------------------------------------------------------
// M[16] = [ 0 4 8 12 ] | 16 floats were used instead of the normal [4][4]
// [ 1 5 9 13 ] | to be compliant with OpenGL. OpenGL uses
// [ 2 6 10 14 ] | premultiplication with column vectors. These
// [ 3 7 11 15 ] | matrices can be fed directly into the OpenGL
// | matrix stack with glLoadMatrix or glMultMatrix.
//
// [ x' y' z' w' ] = [ 0 4 8 12 ] [ x ]
// [ 1 5 9 13 ] * [ y ]
// [ 2 6 10 14 ] [ z ]
// [ 3 7 11 15 ] [ w ]
//
// Loading a [4][4] format matrix directly into the matrix stack (assuming
// premult/col vecs) results in a transpose matrix. M[0]=M[0][0], but
// M[1]!=M[1][0] since M[0][1] would cast to M[1].
//
// However, if we assumed postmult/row vectors we could use [4][4] format,
// but all transformations in this module would be transposed.
//----------------------------------------------------------------------------
template<class Type>
class Mat44
{
public:
Type M[16]; // 0,1,2,3 = 1st col; 4,5,6,7 = 2nd col; etc.
Mat44();
Mat44(const Type *N);
Mat44(Type M0, Type M4, Type M8, Type M12,
Type M1, Type M5, Type M9, Type M13,
Type M2, Type M6, Type M10, Type M14,
Type M3, Type M7, Type M11, Type M15);
Mat44<Type>& operator = (const Mat44& A); // ASSIGNMENT (=)
Mat44<Type>& operator = (const Type* a); // ASSIGNMENT (=) FROM AN ARRAY OF TypeS
Mat44<Type> operator * (const Mat44& A) const; // MULTIPLICATION (*)
Vec3<Type> operator * (const Vec3<Type>& V) const; // MAT-VECTOR MULTIPLICATION (*) W/ PERSP DIV
Vec3<Type> multNormal(const Vec3<Type>& V) const; // MAT-VECTOR MULTIPLICATION _WITHOUT_ PERSP DIV
Vec3<Type> multPoint(const Vec3<Type>& V) const; // MAT-POINT MULTIPLICATION _WITHOUT_ PERSP DIV
Vec4<Type> operator * (const Vec4<Type>& V) const; // MAT-VECTOR MULTIPLICATION (*)
Mat44<Type> operator * (Type a) const; // SCALAR POST-MULTIPLICATION
Mat44<Type>& operator *= (Type a); // ACCUMULATE MULTIPLY (*=)
////////////// NOT IMPLEMENTED YET. ANY TAKERS?
// friend Vec3<Type> operator * (const Vec3<Type>& V, const Mat44& M); // MAT-VECTOR PRE-MULTIPLICATON (*) W/ PERP DIV
// friend Vec4<Type> operator * (const Vec4<Type>& V, const Mat44& M); // MAT-VECTOR PRE-MULTIPLICATON (*)
// friend Mat44<Type> operator * (Type a, const Mat44& M) const; // SCALAR PRE-MULTIPLICATION
// Mat44<Type> operator / (Type a) const; // SCALAR DIVISION
// Mat44<Type> operator + (Mat44& M) const; // ADDITION (+)
// Mat44<Type>& operator += (Mat44& M); // ACCUMULATE ADD (+=)
// Mat44<Type>& operator /= (Type a); // ACCUMULATE DIVIDE (/=)
// bool Invserse(); // MATRIX INVERSE
////////////// NOT IMPLEMENTED YET. ANY TAKERS?
operator const Type*() const; // CAST TO A Type ARRAY
operator Type*(); // CAST TO A Type ARRAY
Type& operator()(int col, int row); // 2D ARRAY ACCESSOR
const Type& operator()(int col, int row) const; // 2D ARRAY ACCESSOR
void Set(const Type* a); // SAME AS ASSIGNMENT (=) FROM AN ARRAY OF TypeS
void Set(Type M0, Type M4, Type M8, Type M12,
Type M1, Type M5, Type M9, Type M13,
Type M2, Type M6, Type M10, Type M14,
Type M3, Type M7, Type M11, Type M15);
void Identity();
void Transpose();
void Translate(Type Tx, Type Ty, Type Tz);
void Translate(const Vec3<Type>& T);
void invTranslate(Type Tx, Type Ty, Type Tz);
void invTranslate(const Vec3<Type>& T);
void Scale(Type Sx, Type Sy, Type Sz);
void Scale(const Vec3<Type>& S);
void invScale(Type Sx, Type Sy, Type Sz);
void invScale(const Vec3<Type>& S);
void Rotate(Type DegAng, const Vec3<Type>& Axis);
void invRotate(Type DegAng, const Vec3<Type>& Axis);
Type Trace(void) const;
void Frustum(Type l, Type r, Type b, Type t, Type n, Type f);
void invFrustum(Type l, Type r, Type b, Type t, Type n, Type f);
void Perspective(Type Yfov, Type Aspect, Type Ndist, Type Fdist);
void invPerspective(Type Yfov, Type Aspect, Type Ndist, Type Fdist);
void Viewport(int WW, int WH);
void invViewport(int WW, int WH);
void LookAt(const Vec3<Type>& Eye,
const Vec3<Type>& LookAtPt,
const Vec3<Type>& ViewUp);
void invLookAt(const Vec3<Type>& Eye,
const Vec3<Type>& LookAtPt,
const Vec3<Type>& ViewUp);
void Viewport2(int WW, int WH);
void invViewport2(int WW, int WH);
void Print() const;
void CopyInto(Type *Mat) const;
static void SWAP(Type& a, Type& b) {Type t; t=a;a=b;b=t;}
};
#include "mat44impl.hpp"
typedef Mat44<float> Mat44f;
typedef Mat44<double> Mat44d;
#endif

View File

@@ -1,536 +0,0 @@
//------------------------------------------------------------------------------
// File : mat44impl.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// mat44.hpp : 4x4 OpenGL-style matrix template.
// This is the template implementation file. It is included by mat44.hpp.
//============================================================================
//---------------------------------------------------------------------------
// CONSTRUCTORS
//---------------------------------------------------------------------------
template<class Type>
Mat44<Type>::Mat44()
{
Identity();
}
template<class Type>
Mat44<Type>::Mat44(const Type *N)
{
M[0]=N[0]; M[4]=N[4]; M[8]=N[8]; M[12]=N[12];
M[1]=N[1]; M[5]=N[5]; M[9]=N[9]; M[13]=N[13];
M[2]=N[2]; M[6]=N[6]; M[10]=N[10]; M[14]=N[14];
M[3]=N[3]; M[7]=N[7]; M[11]=N[11]; M[15]=N[15];
}
template<class Type>
Mat44<Type>::Mat44(Type M0, Type M4, Type M8, Type M12,
Type M1, Type M5, Type M9, Type M13,
Type M2, Type M6, Type M10, Type M14,
Type M3, Type M7, Type M11, Type M15)
{
M[0]=M0; M[4]=M4; M[8]=M8; M[12]=M12;
M[1]=M1; M[5]=M5; M[9]=M9; M[13]=M13;
M[2]=M2; M[6]=M6; M[10]=M10; M[14]=M14;
M[3]=M3; M[7]=M7; M[11]=M11; M[15]=M15;
}
//---------------------------------------------------------------------------
// MATRIX/MATRIX AND MATRIX/VECTOR OPERATORS
//---------------------------------------------------------------------------
template<class Type>
Mat44<Type>& Mat44<Type>::operator = (const Mat44& A) // ASSIGNMENT (=)
{
M[0]=A.M[0]; M[4]=A.M[4]; M[8]=A.M[8]; M[12]=A.M[12];
M[1]=A.M[1]; M[5]=A.M[5]; M[9]=A.M[9]; M[13]=A.M[13];
M[2]=A.M[2]; M[6]=A.M[6]; M[10]=A.M[10]; M[14]=A.M[14];
M[3]=A.M[3]; M[7]=A.M[7]; M[11]=A.M[11]; M[15]=A.M[15];
return(*this);
}
template<class Type>
Mat44<Type>& Mat44<Type>::operator = (const Type* a) {
for (int i=0;i<16;i++) {
M[i] = a[i];
}
return *this;
}
template<class Type>
Mat44<Type> Mat44<Type>::operator * (const Mat44& A) const // MULTIPLICATION (*)
{
Mat44<Type> NewM( M[0]*A.M[0] + M[4]*A.M[1] + M[8]*A.M[2] + M[12]*A.M[3], // ROW 1
M[0]*A.M[4] + M[4]*A.M[5] + M[8]*A.M[6] + M[12]*A.M[7],
M[0]*A.M[8] + M[4]*A.M[9] + M[8]*A.M[10] + M[12]*A.M[11],
M[0]*A.M[12] + M[4]*A.M[13] + M[8]*A.M[14] + M[12]*A.M[15],
M[1]*A.M[0] + M[5]*A.M[1] + M[9]*A.M[2] + M[13]*A.M[3], // ROW 2
M[1]*A.M[4] + M[5]*A.M[5] + M[9]*A.M[6] + M[13]*A.M[7],
M[1]*A.M[8] + M[5]*A.M[9] + M[9]*A.M[10] + M[13]*A.M[11],
M[1]*A.M[12] + M[5]*A.M[13] + M[9]*A.M[14] + M[13]*A.M[15],
M[2]*A.M[0] + M[6]*A.M[1] + M[10]*A.M[2] + M[14]*A.M[3], // ROW 3
M[2]*A.M[4] + M[6]*A.M[5] + M[10]*A.M[6] + M[14]*A.M[7],
M[2]*A.M[8] + M[6]*A.M[9] + M[10]*A.M[10] + M[14]*A.M[11],
M[2]*A.M[12] + M[6]*A.M[13] + M[10]*A.M[14] + M[14]*A.M[15],
M[3]*A.M[0] + M[7]*A.M[1] + M[11]*A.M[2] + M[15]*A.M[3], // ROW 4
M[3]*A.M[4] + M[7]*A.M[5] + M[11]*A.M[6] + M[15]*A.M[7],
M[3]*A.M[8] + M[7]*A.M[9] + M[11]*A.M[10] + M[15]*A.M[11],
M[3]*A.M[12] + M[7]*A.M[13] + M[11]*A.M[14] + M[15]*A.M[15] );
return(NewM);
}
template<class Type>
Vec3<Type> Mat44<Type>::operator * (const Vec3<Type>& V) const // MAT-VECTOR MULTIPLICATION (*) W/ PERSP DIV
{
Type W = M[3]*V.x + M[7]*V.y + M[11]*V.z + M[15];
Vec3<Type> NewV( (M[0]*V.x + M[4]*V.y + M[8]*V.z + M[12]) / W,
(M[1]*V.x + M[5]*V.y + M[9]*V.z + M[13]) / W,
(M[2]*V.x + M[6]*V.y + M[10]*V.z + M[14]) / W );
return(NewV);
}
// MAT-VECTOR MULTIPLICATION _WITHOUT_ PERSP DIV
// For transforming normals or other pure vectors.
// Assumes matrix is affine, i.e. bottom row is 0,0,0,1
template<class Type>
Vec3<Type> Mat44<Type>::multNormal(const Vec3<Type>& N) const
{
Vec3<Type> NewN( (M[0]*N.x + M[4]*N.y + M[8]*N.z ),
(M[1]*N.x + M[5]*N.y + M[9]*N.z ),
(M[2]*N.x + M[6]*N.y + M[10]*N.z) );
return (NewN);
}
// MAT-POINT MULTIPLICATION _WITHOUT_ PERSP DIV
// (for transforming points in space)
// Assumes matrix is affine, i.e. bottom row is 0,0,0,1
template<class Type>
Vec3<Type> Mat44<Type>::multPoint(const Vec3<Type>& P) const
{
Vec3<Type> NewP( (M[0]*P.x + M[4]*P.y + M[8]*P.z + M[12]),
(M[1]*P.x + M[5]*P.y + M[9]*P.z + M[13]),
(M[2]*P.x + M[6]*P.y + M[10]*P.z + M[14]) );
return (NewP);
}
template<class Type>
Vec4<Type> Mat44<Type>::operator * (const Vec4<Type>& V) const // MAT-VECTOR MULTIPLICATION (*)
{
Vec4<Type> NewV;
NewV.x = M[0]*V.x + M[4]*V.y + M[8]*V.z + M[12]*V.w;
NewV.y = M[1]*V.x + M[5]*V.y + M[9]*V.z + M[13]*V.w;
NewV.z = M[2]*V.x + M[6]*V.y + M[10]*V.z + M[14]*V.w;
NewV.w = M[3]*V.x + M[7]*V.y + M[11]*V.z + M[15]*V.w;
return(NewV);
}
template<class Type>
Mat44<Type> Mat44<Type>::operator * (Type a) const // SCALAR POST-MULTIPLICATION
{
Mat44<Type> NewM( M[0] * a, M[1] * a, M[2] * a, M[3] * a,
M[4] * a, M[5] * a, M[6] * a, M[7] * a,
M[8] * a, M[9] * a, M[10] * a, M[11] * a,
M[12] * a, M[13] * a, M[14] * a, M[15] * a);
return NewM;
}
template<class Type>
Mat44<Type>& Mat44<Type>::operator *= (Type a) // SCALAR ACCUMULATE POST-MULTIPLICATION
{
for (int i = 0; i < 16; i++)
{
M[i] *= a;
}
return *this;
}
template<class Type>
Mat44<Type>::operator const Type*() const
{
return M;
}
template<class Type>
Mat44<Type>::operator Type*()
{
return M;
}
template<class Type>
Type& Mat44<Type>::operator()(int col, int row)
{
return M[4*col+row];
}
template<class Type>
const Type& Mat44<Type>::operator()(int col, int row) const
{
return M[4*col+row];
}
template<class Type>
void Mat44<Type>::Set(const Type* a)
{
for (int i=0;i<16;i++) {
M[i] = a[i];
}
}
template<class Type>
void Mat44<Type>::Set(Type M0, Type M4, Type M8, Type M12,
Type M1, Type M5, Type M9, Type M13,
Type M2, Type M6, Type M10, Type M14,
Type M3, Type M7, Type M11, Type M15)
{
M[0]=M0; M[4]=M4; M[8]=M8; M[12]=M12;
M[1]=M1; M[5]=M5; M[9]=M9; M[13]=M13;
M[2]=M2; M[6]=M6; M[10]=M10; M[14]=M14;
M[3]=M3; M[7]=M7; M[11]=M11; M[15]=M15;
}
//---------------------------------------------------------------------------
// Standard Matrix Operations
//---------------------------------------------------------------------------
template<class Type>
void Mat44<Type>::Identity()
{
M[0]=M[5]=M[10]=M[15]=1;
M[1]=M[2]=M[3]=M[4]=M[6]=M[7]=M[8]=M[9]=M[11]=M[12]=M[13]=M[14]=0;
}
template<class Type>
void Mat44<Type>::Transpose()
{
SWAP(M[1],M[4]);
SWAP(M[2],M[8]);
SWAP(M[6],M[9]);
SWAP(M[3],M[12]);
SWAP(M[7],M[13]);
SWAP(M[11],M[14]);
}
//---------------------------------------------------------------------------
// Standard Matrix Affine Transformations
//---------------------------------------------------------------------------
template <class Type>
void Mat44<Type>::Translate(Type Tx, Type Ty, Type Tz)
{
M[0]=1; M[4]=0; M[8]=0; M[12]=Tx;
M[1]=0; M[5]=1; M[9]=0; M[13]=Ty;
M[2]=0; M[6]=0; M[10]=1; M[14]=Tz;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::Translate(const Vec3<Type>& T)
{
M[0]=1; M[4]=0; M[8]=0; M[12]=T.x;
M[1]=0; M[5]=1; M[9]=0; M[13]=T.y;
M[2]=0; M[6]=0; M[10]=1; M[14]=T.z;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::invTranslate(Type Tx, Type Ty, Type Tz)
{
M[0]=1; M[4]=0; M[8]=0; M[12]=-Tx;
M[1]=0; M[5]=1; M[9]=0; M[13]=-Ty;
M[2]=0; M[6]=0; M[10]=1; M[14]=-Tz;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::invTranslate(const Vec3<Type>& T)
{
M[0]=1; M[4]=0; M[8]=0; M[12]=-T.x;
M[1]=0; M[5]=1; M[9]=0; M[13]=-T.y;
M[2]=0; M[6]=0; M[10]=1; M[14]=-T.z;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::Scale(Type Sx, Type Sy, Type Sz)
{
M[0]=Sx; M[4]=0; M[8]=0; M[12]=0;
M[1]=0; M[5]=Sy; M[9]=0; M[13]=0;
M[2]=0; M[6]=0; M[10]=Sz; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::Scale(const Vec3<Type>& S)
{
M[0]=S.x; M[4]=0; M[8]=0; M[12]=0;
M[1]=0; M[5]=S.y; M[9]=0; M[13]=0;
M[2]=0; M[6]=0; M[10]=S.z; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::invScale(Type Sx, Type Sy, Type Sz)
{
M[0]=1/Sx; M[4]=0; M[8]=0; M[12]=0;
M[1]=0; M[5]=1/Sy; M[9]=0; M[13]=0;
M[2]=0; M[6]=0; M[10]=1/Sz; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::invScale(const Vec3<Type>& S)
{
M[0]=1/S.x; M[4]=0; M[8]=0; M[12]=0;
M[1]=0; M[5]=1/S.y; M[9]=0; M[13]=0;
M[2]=0; M[6]=0; M[10]=1/S.z; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::Rotate(Type DegAng, const Vec3<Type>& Axis)
{
Type RadAng = DegAng*Mat44TORADS;
Type ca=(Type)cos(RadAng),
sa=(Type)sin(RadAng);
if (Axis.x==1 && Axis.y==0 && Axis.z==0) // ABOUT X-AXIS
{
M[0]=1; M[4]=0; M[8]=0; M[12]=0;
M[1]=0; M[5]=ca; M[9]=-sa; M[13]=0;
M[2]=0; M[6]=sa; M[10]=ca; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
else if (Axis.x==0 && Axis.y==1 && Axis.z==0) // ABOUT Y-AXIS
{
M[0]=ca; M[4]=0; M[8]=sa; M[12]=0;
M[1]=0; M[5]=1; M[9]=0; M[13]=0;
M[2]=-sa; M[6]=0; M[10]=ca; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
else if (Axis.x==0 && Axis.y==0 && Axis.z==1) // ABOUT Z-AXIS
{
M[0]=ca; M[4]=-sa; M[8]=0; M[12]=0;
M[1]=sa; M[5]=ca; M[9]=0; M[13]=0;
M[2]=0; M[6]=0; M[10]=1; M[14]=0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
else // ARBITRARY AXIS
{
Type l = Axis.LengthSqr();
Type x, y, z;
x=Axis.x, y=Axis.y, z=Axis.z;
if (l > Type(1.0001) || l < Type(0.9999) && l!=0)
{
// needs normalization
l=Type(1.0)/sqrt(l);
x*=l; y*=l; z*=l;
}
Type x2=x*x, y2=y*y, z2=z*z;
M[0]=x2+ca*(1-x2); M[4]=(x*y)+ca*(-x*y)+sa*(-z); M[8]=(x*z)+ca*(-x*z)+sa*y;
M[1]=(x*y)+ca*(-x*y)+sa*z; M[5]=y2+ca*(1-y2); M[9]=(y*z)+ca*(-y*z)+sa*(-x);
M[2]=(x*z)+ca*(-x*z)+sa*(-y); M[6]=(y*z)+ca*(-y*z)+sa*x; M[10]=z2+ca*(1-z2);
M[12]=M[13]=M[14]=M[3]=M[7]=M[11]=0;
M[15]=1;
}
}
template<class Type>
void Mat44<Type>::invRotate(Type DegAng, const Vec3<Type>& Axis)
{
Rotate(DegAng,Axis);
Transpose();
}
template<class Type>
inline Type Mat44<Type>::Trace() const
{
return M[0] + M[5] + M[10] + M[15];
}
//---------------------------------------------------------------------------
// Same as glFrustum() : Perspective transformation matrix defined by a
// truncated pyramid viewing frustum that starts at the origin (eye)
// going in the -Z axis direction (viewer looks down -Z)
// with the four pyramid sides passing through the sides of a window
// defined through x=l, x=r, y=b, y=t on the viewplane at z=-n.
// The top and bottom of the pyramid are truncated by the near and far
// planes at z=-n and z=-f. A 4-vector (x,y,z,w) inside this frustum
// transformed by this matrix will have x,y,z values in the range
// [-w,w]. Homogeneous clipping is applied to restrict (x,y,z) to
// this range. Later, a perspective divide by w will result in an NDC
// coordinate 3-vector of the form (x/w,y/w,z/w,w/w)=(x',y',z',1) where
// x', y', and z' all are in the range [-1,1]. Perspectively divided z'
// will be in [-1,1] with -1 being the near plane and +1 being the far.
//---------------------------------------------------------------------------
template<class Type>
void Mat44<Type>::Frustum(Type l, Type r, Type b, Type t, Type n, Type f)
{
M[0]=(2*n)/(r-l); M[4]=0; M[8]=(r+l)/(r-l); M[12]=0;
M[1]=0; M[5]=(2*n)/(t-b); M[9]=(t+b)/(t-b); M[13]=0;
M[2]=0; M[6]=0; M[10]=-(f+n)/(f-n); M[14]=(-2*f*n)/(f-n);
M[3]=0; M[7]=0; M[11]=-1; M[15]=0;
}
template<class Type>
void Mat44<Type>::invFrustum(Type l, Type r, Type b, Type t, Type n, Type f)
{
M[0]=(r-l)/(2*n); M[4]=0; M[8]=0; M[12]=(r+l)/(2*n);
M[1]=0; M[5]=(t-b)/(2*n); M[9]=0; M[13]=(t+b)/(2*n);
M[2]=0; M[6]=0; M[10]=0; M[14]=-1;
M[3]=0; M[7]=0; M[11]=-(f-n)/(2*f*n); M[15]=(f+n)/(2*f*n);
}
//---------------------------------------------------------------------------
// Same as gluPerspective : calls Frustum()
//---------------------------------------------------------------------------
template<class Type>
void Mat44<Type>::Perspective(Type Yfov, Type Aspect, Type Ndist, Type Fdist)
{
Yfov *= 0.0174532f; // CONVERT TO RADIANS
Type wT=tanf(Yfov*0.5f)*Ndist, wB=-wT;
Type wR=wT*Aspect, wL=-wR;
Frustum(wL,wR,wB,wT,Ndist,Fdist);
}
template<class Type>
void Mat44<Type>::invPerspective(Type Yfov, Type Aspect, Type Ndist, Type Fdist)
{
Yfov *= 0.0174532f; // CONVERT TO RADIANS
Type wT=tanf(Yfov*0.5f)*Ndist, wB=-wT;
Type wR=wT*Aspect, wL=-wR;
invFrustum(wL,wR,wB,wT,Ndist,Fdist);
}
//---------------------------------------------------------------------------
// OpenGL VIEWPORT XFORM MATRIX : given Window width and height in pixels
// Transforms the x,y,z NDC values in [-1,1] to (x',y') pixel values and
// normalized z' in [0,1] (near and far respectively).
//---------------------------------------------------------------------------
template<class Type>
void Mat44<Type>::Viewport(int WW, int WH)
{
Type WW2=(Type)WW*0.5f, WH2=(Type)WH*0.5f;
M[0]=WW2; M[4]=0; M[8]=0; M[12]=WW2;
M[1]=0; M[5]=WH2; M[9]=0; M[13]=WH2;
M[2]=0; M[6]=0; M[10]=0.5; M[14]=0.5;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::invViewport(int WW, int WH)
{
Type WW2=2.0f/(Type)WW, WH2=2.0f/(Type)WH;
M[0]=WW2; M[4]=0; M[8]=0; M[12]=-1.0;
M[1]=0; M[5]=WH2; M[9]=0; M[13]=-1.0;
M[2]=0; M[6]=0; M[10]=2.0; M[14]=-1.0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
//---------------------------------------------------------------------------
// Same as gluLookAt()
//---------------------------------------------------------------------------
template<class Type>
void Mat44<Type>::LookAt(const Vec3<Type>& Eye,
const Vec3<Type>& LookAtPt,
const Vec3<Type>& ViewUp)
{
Vec3<Type> Z = Eye-LookAtPt; Z.Normalize(); // CALC CAM AXES ("/" IS CROSS-PROD)
Vec3<Type> X = ViewUp/Z; X.Normalize();
Vec3<Type> Y = Z/X; Y.Normalize();
Vec3<Type> Tr = -Eye;
M[0]=X.x; M[4]=X.y; M[8]=X.z; M[12]=X*Tr; // TRANS->ROT
M[1]=Y.x; M[5]=Y.y; M[9]=Y.z; M[13]=Y*Tr;
M[2]=Z.x; M[6]=Z.y; M[10]=Z.z; M[14]=Z*Tr;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::invLookAt(const Vec3<Type>& Eye,
const Vec3<Type>& LookAtPt,
const Vec3<Type>& ViewUp)
{
Vec3<Type> Z = Eye-LookAtPt; Z.Normalize(); // CALC CAM AXES ("/" IS CROSS-PROD)
Vec3<Type> X = ViewUp/Z; X.Normalize();
Vec3<Type> Y = Z/X; Y.Normalize();
M[0]=X.x; M[4]=Y.x; M[8]=Z.x; M[12]=Eye.x; // ROT->TRANS
M[1]=X.y; M[5]=Y.y; M[9]=Z.y; M[13]=Eye.y;
M[2]=X.z; M[6]=Y.z; M[10]=Z.z; M[14]=Eye.z;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
//---------------------------------------------------------------------------
// VIEWPORT TRANFORMATION MATRIX : given Window width and height in pixels
// FROM "JIM BLINN'S CORNER" JULY '91. This function transforms an
// 4-vector in homogeneous space of the form (x,y,z,w) where
// -w<=x,y,z<=w into (x',y',z',1) where (x',y') is the vectors
// projected pixel location in ([0,WW-1],[0,WH-1]) and z' is the
// normalized depth value mapped into [0,1]; 0 is the near plane
// and 1 is the far plane. Mat44VIEWPORT_TOL is introduced to have correct
// mappings. (-1,-1,?,?) in NDC refers to the bottom-left of the
// viewplane window and (0,0,?,?) in screen space refers to the
// bottom-left pixel.
//---------------------------------------------------------------------------
template<class Type>
void Mat44<Type>::Viewport2(int WW, int WH)
{
Type WW2=(WW-Mat44VIEWPORT_TOL)*0.5f, WH2=(WH-Mat44VIEWPORT_TOL)*0.5f;
M[0]=WW2; M[4]=0; M[8]=0; M[12]=WW2;
M[1]=0; M[5]=WH2; M[9]=0; M[13]=WH2;
M[2]=0; M[6]=0; M[10]=0.5; M[14]=0.5;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
template<class Type>
void Mat44<Type>::invViewport2(int WW, int WH)
{
Type WW2=2.0f/(WW-Mat44VIEWPORT_TOL), WH2=2.0f/(WH-Mat44VIEWPORT_TOL);
M[0]=WW2; M[4]=0; M[8]=0; M[12]=-1.0;
M[1]=0; M[5]=WH2; M[9]=0; M[13]=-1.0;
M[2]=0; M[6]=0; M[10]=2.0; M[14]=-1.0;
M[3]=0; M[7]=0; M[11]=0; M[15]=1;
}
//---------------------------------------------------------------------------
// Handy matrix printing routine.
//---------------------------------------------------------------------------
template<class Type>
void Mat44<Type>::Print() const
{
printf("\n%f %f %f %f\n",M[0],M[4],M[8],M[12]);
printf("%f %f %f %f\n",M[1],M[5],M[9],M[13]);
printf("%f %f %f %f\n",M[2],M[6],M[10],M[14]);
printf("%f %f %f %f\n\n",M[3],M[7],M[11],M[15]);
}
//---------------------------------------------------------------------------
// Copy contents of matrix into matrix array.
//---------------------------------------------------------------------------
template<class Type>
void Mat44<Type>::CopyInto(Type *Mat) const
{
Mat[0]=M[0]; Mat[4]=M[4]; Mat[8]=M[8]; Mat[12]=M[12];
Mat[1]=M[1]; Mat[5]=M[5]; Mat[9]=M[9]; Mat[13]=M[13];
Mat[2]=M[2]; Mat[6]=M[6]; Mat[10]=M[10]; Mat[14]=M[14];
Mat[3]=M[3]; Mat[7]=M[7]; Mat[11]=M[11]; Mat[15]=M[15];
}

View File

@@ -1,66 +0,0 @@
//------------------------------------------------------------------------------
// File : mat44test.cpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//----------------------------------------------------------------------------
// mat44test -- test compilation of all the functions in mat44 library
//----------------------------------------------------------------------------
// $Id$
//----------------------------------------------------------------------------
#include <iostream.h>
#include "vec3f.hpp"
#include "mat44.hpp"
int main(int argc, char *argv[])
{
cout << "This is not a comprehensive correctness test. " << endl
<< "It merely tests whether all the functions in mat44 will compile." <<endl;
Mat44f m;
float m2[16];
Vec3f v(1.0, 1.0, 1.0);
Vec3f up(0.0, 1.0, 0.0);
m.Identity();
m.Transpose();
m.Translate(1.0, 1.0, 1.0);
m.Translate(v);
m.invTranslate(v);
m.Scale(1.0, 1.0, 1.0);
m.Scale(v);
m.invScale(1.0, 1.0, 1.0);
m.invScale(v);
m.Rotate(90, v);
m.invRotate(90, v);
m.Frustum(-1.0, 1.0, -1.0, 1.0, 0.01, 20);
m.invFrustum(-1.0, 1.0, -1.0, 1.0, 0.01, 20);
m.Perspective(60, 1.4, 0.01, 20);
m.invPerspective(60, 1.4, 0.01, 20);
m.Viewport(200, 200);
m.invViewport(200, 200);
m.LookAt(Vec3f::ZERO, v, up);
m.invLookAt(Vec3f::ZERO, v, up);
m.Viewport2(200, 200);
m.invViewport2(200, 200);
m.Print();
m.Transpose();
m.Print();
// These two should be transpose of one another
m.CopyInto(m2);
cout << "Ok there is this one test to make sure Transpose() is correct.\n"
"The above two matricies should be the transpose of one another.\n" << endl;
}

View File

@@ -1,108 +0,0 @@
//------------------------------------------------------------------------------
// File : minmaxbox.cpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//=========================================================================
// minmaxbox.cpp : min-max box routines
//=========================================================================
//-----------------------------------------------------------------------------
// Calculates the eight corner vertices of the MinMaxBox.
// V must be prealloced.
// 5---4
// / /|
// 1---0 | VERTS : 0=RTN,1=LTN,2=LBN,3=RBN,4=RTF,5=LTF,6=LBF,7=RBF
// | | 7 (L,R, B,T, N,F) = (Left,Right, Bottom,Top, Near,Far)
// | |/
// 2---3
//-----------------------------------------------------------------------------
void GetMinMaxBoxVerts(const float Min[3], const float Max[3], float V[8][3])
{
#define SET(v,x,y,z) v[0]=x; v[1]=y; v[2]=z;
SET(V[0],Max[0],Max[1],Max[2]); SET(V[4],Max[0],Max[1],Min[2]);
SET(V[1],Min[0],Max[1],Max[2]); SET(V[5],Min[0],Max[1],Min[2]);
SET(V[2],Min[0],Min[1],Max[2]); SET(V[6],Min[0],Min[1],Min[2]);
SET(V[3],Max[0],Min[1],Max[2]); SET(V[7],Max[0],Min[1],Min[2]);
}
//--------------------------------------------------------------------------
// Ray-MinMaxBox intersection test. Returns 0 or 1, calcs In-Out "HitTimes"
// IsectPts can be calculated as:
// InIsectPt = Start + Dir * InT (if InT>0)
// OutIsectPt = Start + Dir * OutT (if OutT>0)
//--------------------------------------------------------------------------
int RayMinMaxBoxIsect(const float Start[3], const float Dir[3],
const float Min[3], const float Max[3],
float *InT, float *OutT)
{
*InT=-99999, *OutT=99999; // INIT INTERVAL T-VAL ENDPTS TO -/+ "INFINITY"
float NewInT, NewOutT; // STORAGE FOR NEW T VALUES
// X-SLAB (PARALLEL PLANES PERPENDICULAR TO X-AXIS) INTERSECTION (Xaxis is Normal)
if (Dir[0] == 0) // CHECK IF RAY IS PARALLEL TO THE SLAB PLANES
{ if ((Start[0] < Min[0]) || (Start[0] > Max[0])) return(0); }
else
{
NewInT = (Min[0]-Start[0])/Dir[0]; // CALC Tval ENTERING MIN PLANE
NewOutT = (Max[0]-Start[0])/Dir[0]; // CALC Tval ENTERING MAX PLANE
if (NewOutT>NewInT) { if (NewInT>*InT) *InT=NewInT; if (NewOutT<*OutT) *OutT=NewOutT; }
else { if (NewOutT>*InT) *InT=NewOutT; if (NewInT<*OutT) *OutT=NewInT; }
if (*InT>*OutT) return(0);
}
// Y-SLAB (PARALLEL PLANES PERPENDICULAR TO Y-AXIS) INTERSECTION (Yaxis is Normal)
if (Dir[1] == 0) // CHECK IF RAY IS PARALLEL TO THE SLAB PLANES
{ if ((Start[1] < Min[1]) || (Start[1] > Max[1])) return(0); }
else
{
NewInT = (Min[1]-Start[1])/Dir[1]; // CALC Tval ENTERING MIN PLANE
NewOutT = (Max[1] - Start[1])/Dir[1]; // CALC Tval ENTERING MAX PLANE
if (NewOutT>NewInT) { if (NewInT>*InT) *InT=NewInT; if (NewOutT<*OutT) *OutT=NewOutT; }
else { if (NewOutT>*InT) *InT=NewOutT; if (NewInT<*OutT) *OutT=NewInT; }
if (*InT>*OutT) return(0);
}
// Z-SLAB (PARALLEL PLANES PERPENDICULAR TO Z-AXIS) INTERSECTION (Zaxis is Normal)
if (Dir[2] == 0) // CHECK IF RAY IS PARALLEL TO THE SLAB PLANES
{ if ((Start[2] < Min[2]) || (Start[2] > Max[2])) return(0); }
else
{
NewInT = (Min[2]-Start[2])/Dir[2]; // CALC Tval ENTERING MIN PLANE
NewOutT = (Max[2]-Start[2])/Dir[2]; // CALC Tval ENTERING MAX PLANE
if (NewOutT>NewInT) { if (NewInT>*InT) *InT=NewInT; if (NewOutT<*OutT) *OutT=NewOutT; }
else { if (NewOutT>*InT) *InT=NewOutT; if (NewInT<*OutT) *OutT=NewInT; }
if (*InT>*OutT) return(0);
}
// CHECK IF INTERSECTIONS ARE "AT OR BEYOND" THE START OF THE RAY
if (*InT>=0 || *OutT>=0) return(1);
return(0);
}
//--------------------------------------------------------------------------
// returns whether or not an edge intersects a MinMaxBox. The hit times
// are returned just as in the ray isect test.
//--------------------------------------------------------------------------
int EdgeMinMaxBoxIsect(const float A[3], const float B[3],
const float Min[3], const float Max[3],
float *InT, float *OutT)
{
float Dir[3] = {B[0]-A[0],B[1]-A[1],B[2]-A[2]};
if ( RayMinMaxBoxIsect(A,Dir,Min,Max,InT,OutT) )
if (*InT>=0 && *InT<=1) return(1);
else if (*OutT>=0 && *OutT<=1) return(1);
return(0);
}

View File

@@ -1,30 +0,0 @@
//------------------------------------------------------------------------------
// File : minmaxbox.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//=========================================================================
// minmaxbox.hpp : min-max box routines
//=========================================================================
void GetMinMaxBoxVerts(const float Min[3], const float Max[3], float V[8][3]);
int RayMinMaxBoxIsect(const float Start[3], const float Dir[3],
const float Min[3], const float Max[3],
float *InT, float *OutT);
int EdgeMinMaxBoxIsect(const float A[3], const float B[3],
const float Min[3], const float Max[3],
float *InT, float *OutT);

View File

@@ -1,302 +0,0 @@
//------------------------------------------------------------------------------
// File : plane.cpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//=========================================================================
// plane.cpp
//=========================================================================
#include <math.h>
//--------------------------------------------------------------------------
// Calculates the plane equation coeffients P = [ A B C D ] for the plane
// equation: Ax+By+Cz+D=0 given three vertices defining the plane. The
// normalized plane normal (A,B,C) is defined using the right-hand rule.
//--------------------------------------------------------------------------
float* PlaneEquation(float P[4],
const float p0[3], const float p1[3], const float p2[3])
{
// CALCULATE PLANE NORMAL - FIRST THREE COEFFICIENTS (A,B,C)
float u[3], v[3];
u[0]=p1[0]-p0[0]; u[1]=p1[1]-p0[1]; u[2]=p1[2]-p0[2];
v[0]=p2[0]-p0[0]; v[1]=p2[1]-p0[1]; v[2]=p2[2]-p0[2];
P[0] = u[1]*v[2] - u[2]*v[1]; // CROSS-PROD BETWEEN u AND v
P[1] = u[2]*v[0] - u[0]*v[2]; // DEFINES UNNORMALIZED NORMAL
P[2] = u[0]*v[1] - u[1]*v[0];
float l = (float)sqrt(P[0]*P[0] + P[1]*P[1] + P[2]*P[2]); // NORMALIZE NORMAL
P[0]/=l; P[1]/=l; P[2]/=l;
// CALCULATE D COEFFICIENT (USING FIRST PT ON PLANE - p0)
P[3] = -(P[0]*p0[0] + P[1]*p0[1] + P[2]*p0[2]);
return(P);
}
//--------------------------------------------------------------------------
// Calculates the plane equation coeffients P = [ A B C D ] for the plane
// equation: Ax+By+Cz+D=0 given an unnormalized normal N to the plane and
// the distance along the normal to the plane Dist. The dot product between
// the normalized normal and a point on the plane should equal the distance
// along the normal to the plane (Dist): Ax+By+Cz=Dist, so D=-Dist.
//--------------------------------------------------------------------------
float* PlaneEquation(float P[4], const float N[3], float Dist)
{
// COPY AND NORMALIZE NORMAL
P[0]=N[0]; P[1]=N[1]; P[2]=N[2];
float l = (float)sqrt(P[0]*P[0] + P[1]*P[1] + P[2]*P[2]);
P[0]/=l; P[1]/=l; P[2]/=l;
// CALCULATE D COEFFICIENT
P[3]=-Dist;
return(P);
}
//--------------------------------------------------------------------------
// Calculates the plane equation coeffients P = [ A B C D ] for the plane
// equation: Ax+By+Cz+D=0 given an unnormalized normal N to the plane and
// a point pt on the plane. The dot product between the normalized normal
// and the point should equal the distance along the normal to the plane,
// thus equalling negative D.
//--------------------------------------------------------------------------
float* PlaneEquation(float P[4], const float N[3], const float pt[3])
{
// COPY AND NORMALIZE NORMAL
P[0]=N[0]; P[1]=N[1]; P[2]=N[2];
float l = (float)sqrt(P[0]*P[0] + P[1]*P[1] + P[2]*P[2]);
P[0]/=l; P[1]/=l; P[2]/=l;
// CALCULATE D COEFFICIENT (USING PT ON PLANE)
P[3] = -(P[0]*pt[0] + P[1]*pt[1] + P[2]*pt[2]);
return(P);
}
//--------------------------------------------------------------------------
// Transforms a plane by a 4x4 matrix (col-major order, assumes premult/col vect).
// The given plane coefficients are altered. The normal (A,B,C) is normalized.
// see HOFF tech report: "4x4 matrix transformation of the implicit form of the plane"
//--------------------------------------------------------------------------
void XformPlane(const float M[16], float P[4])
{
float NewP[4], L2, L;
NewP[0] = M[0]*P[0] + M[4]*P[1] + M[8]*P[2];
NewP[1] = M[1]*P[0] + M[5]*P[1] + M[9]*P[2];
NewP[2] = M[2]*P[0] + M[6]*P[1] + M[10]*P[2];
L2 = NewP[0]*NewP[0] + NewP[1]*NewP[1] + NewP[2]*NewP[2];
L = (float)sqrt(L2);
P[0] = NewP[0] / L;
P[1] = NewP[1] / L;
P[2] = NewP[2] / L;
P[3] = P[3]*L2 - (NewP[0]*M[12] + NewP[1]*M[13] + NewP[2]*M[14]);
}
//--------------------------------------------------------------------------
// return 1 if point is "outside" (normal side) of plane, 0 if "inside" or on
//--------------------------------------------------------------------------
int PlanePtOutTest(const float P[4], const float Pt[3])
{
return( (P[0]*Pt[0] + P[1]*Pt[1] + P[2]*Pt[2]) > -P[3] );
}
//--------------------------------------------------------------------------
// returns -1 inside, 0 on, 1 outside (normal side)
//--------------------------------------------------------------------------
int PlanePtInOutTest(const float P[4], const float Pt[3])
{
float DotProd = P[0]*Pt[0] + P[1]*Pt[1] + P[2]*Pt[2];
if (DotProd < -P[3]) return(-1);
if (DotProd > -P[3]) return(1);
return(0);
}
//--------------------------------------------------------------------------
// Calculates the "signed" distance of a point from a plane (in units of
// the normal length, if not normalized). +Dist is on normal dir side of plane.
//--------------------------------------------------------------------------
float PlaneDistToPt(const float P[4], const float Pt[3])
{
return( P[0]*Pt[0] + P[1]*Pt[1] + P[2]*Pt[2] + P[3] );
}
//--------------------------------------------------------------------------
// returns 1 if ray (Start,Dir) intersects plane, 0 if not
//--------------------------------------------------------------------------
int PlaneRayIsect(const float P[4], const float Start[3], const float Dir[3])
{
float NdotDir = P[0]*Dir[0] + P[1]*Dir[1] + P[2]*Dir[2];
float NdotStart = P[0]*Start[0] + P[1]*Start[1] + P[2]*Start[2];
if (NdotDir==(float)0) return(0);
float t = (-P[3] - NdotStart) / NdotDir;
if (t>=0) return(1);
return(0);
}
//--------------------------------------------------------------------------
// Also computes intersection point, if possible
//--------------------------------------------------------------------------
int PlaneRayIsect(const float P[4], const float Start[3], const float Dir[3],
float IsectPt[3])
{
float NdotDir = P[0]*Dir[0] + P[1]*Dir[1] + P[2]*Dir[2];
float NdotStart = P[0]*Start[0] + P[1]*Start[1] + P[2]*Start[2];
if (NdotDir==(float)0) return(0);
float t = (-P[3] - NdotStart) / NdotDir;
if (t>=0)
{
IsectPt[0] = Start[0] + Dir[0]*t;
IsectPt[1] = Start[1] + Dir[1]*t;
IsectPt[2] = Start[2] + Dir[2]*t;
return(1);
}
return(0);
}
//--------------------------------------------------------------------------
// Intersects a line with a plane with normal (0,0,-1) with distance d
// from the origin. The line is given by position Start and direction Dir.
//--------------------------------------------------------------------------
int ZPlaneLineIsect(float d, const float Start[3], const float Dir[3],
float IsectPt[3])
{
float NdotDir = -Dir[2];
if (NdotDir==(float)0) return(0);
float t = (d + Start[2]) / NdotDir;
IsectPt[0] = Start[0] + Dir[0]*t;
IsectPt[1] = Start[1] + Dir[1]*t;
IsectPt[2] = Start[2] + Dir[2]*t;
return(1);
}
//--------------------------------------------------------------------------
// returns 1 if edge AB intersects plane, 0 if not
//--------------------------------------------------------------------------
int PlaneEdgeIsect(const float P[4], const float A[3], const float B[3])
{
float Dir[3] = { B[0]-A[0], B[1]-A[1], B[2]-A[2] };
float NdotDir = P[0]*Dir[0] + P[1]*Dir[1] + P[2]*Dir[2];
float NdotA = P[0]*A[0] + P[1]*A[1] + P[2]*A[2];
if (NdotDir==(float)0) return(0);
float t = (-P[3] - NdotA) / NdotDir;
if (t>=0 && t<=1) return(1);
return(0);
}
//--------------------------------------------------------------------------
// Also computes intersection point, if possible
//--------------------------------------------------------------------------
int PlaneEdgeIsect(const float P[4], const float A[3], const float B[3],
float IsectPt[3])
{
float Dir[3] = { B[0]-A[0], B[1]-A[1], B[2]-A[2] };
float NdotDir = P[0]*Dir[0] + P[1]*Dir[1] + P[2]*Dir[2];
float NdotA = P[0]*A[0] + P[1]*A[1] + P[2]*A[2];
if (NdotDir==(float)0) return(0);
float t = (-P[3] - NdotA) / NdotDir;
if (t>=0 && t<=1)
{
IsectPt[0] = A[0] + Dir[0]*t;
IsectPt[1] = A[1] + Dir[1]*t;
IsectPt[2] = A[2] + Dir[2]*t;
return(1);
}
return(0);
}
//---------------------------------------------------------------------------
// Box (m,M)/ Plane P overlap test.
// returns type of overlap: 1=OUT (side of normal dir), -1=IN, 0=Overlapping
// Finds the "closest" and "farthest" points from the plane with respect
// to the plane normal dir (the "extremes" of the aabb) and tests for overlap.
// m and M are the Min and Max extents of the AABB.
//---------------------------------------------------------------------------
int PlaneMinMaxBoxOverlap(const float P[4], const float m[3], const float M[3])
{
#define SET(v,x,y,z) v[0]=x; v[1]=y; v[2]=z;
// CALC EXTREME PTS (Neg,Pos) ALONG NORMAL AXIS (Pos in dir of norm, etc.)
float Neg[3], Pos[3];
if(P[0]>0)
if(P[1]>0) { if(P[2]>0) { SET(Pos,M[0],M[1],M[2]); SET(Neg,m[0],m[1],m[2]); }
else { SET(Pos,M[0],M[1],m[2]); SET(Neg,m[0],m[1],M[2]); } }
else { if(P[2]>0) { SET(Pos,M[0],m[1],M[2]); SET(Neg,m[0],M[1],m[2]); }
else { SET(Pos,M[0],m[1],m[2]); SET(Neg,m[0],M[1],M[2]); } }
else
if(P[1]>0) { if(P[2]>0) { SET(Pos,m[0],M[1],M[2]); SET(Neg,M[0],m[1],m[2]); }
else { SET(Pos,m[0],M[1],m[2]); SET(Neg,M[0],m[1],M[2]); } }
else { if(P[2]>0) { SET(Pos,m[0],m[1],M[2]); SET(Neg,M[0],M[1],m[2]); }
else { SET(Pos,m[0],m[1],m[2]); SET(Neg,M[0],M[1],M[2]); } }
// CHECK DISTANCE TO PLANE FROM EXTREMAL POINTS TO DETERMINE OVERLAP
if (PlaneDistToPt(P,Neg) > 0) return(1);
else if (PlaneDistToPt(P,Pos) <= 0) return(-1);
return(0);
}
//---------------------------------------------------------------------------
// Edge/Planes intersection test. Returns 0 or 1, calcs In-Out "HitTimes"
// IsectPts can be calculated as:
// InIsectPt = Start + Dir * InT (if InT>0)
// OutIsectPt = Start + Dir * OutT (if OutT>0)
// Planes is defined as: float Planes[n][4] for n planes.
//---------------------------------------------------------------------------
int PlanesRayIsect(const float Planes[][4], int NumPlanes,
const float Start[3], const float Dir[3],
float *InT, float *OutT)
{
*InT=-99999, *OutT=99999; // INIT INTERVAL T-VAL ENDPTS TO -/+ INFINITY
float NdotDir, NdotStart; // STORAGE FOR REPEATED CALCS NEEDED FOR NewT CALC
float NewT;
for (int i=0; i<NumPlanes; i++) // CHECK INTERSECTION AGAINST EACH VF PLANE
{
NdotDir = Planes[i][0]*Dir[0] + Planes[i][1]*Dir[1] + Planes[i][2]*Dir[2];
NdotStart = Planes[i][0]*Start[0] + Planes[i][1]*Start[1] + Planes[i][2]*Start[2];
if (NdotDir == 0) // CHECK IF RAY IS PARALLEL TO THE SLAB PLANES
{
if (NdotStart > -Planes[i][3]) return(0); // IF STARTS "OUTSIDE", NO INTERSECTION
}
else
{
NewT = (-Planes[i][3] - NdotStart) / NdotDir; // FIND HIT "TIME" (DISTANCE)
if (NdotDir < 0) { if (NewT > *InT) *InT=NewT; } // IF "FRONTFACING", MUST BE NEW IN "TIME"
else { if (NewT < *OutT) *OutT=NewT; } // IF "BACKFACING", MUST BE NEW OUT "TIME"
}
if (*InT > *OutT) return(0); // CHECK FOR EARLY EXITS (INTERSECTION INTERVAL "OUTSIDE")
}
// IF AT LEAST ONE THE Tvals ARE IN THE INTERVAL [0,1] WE HAVE INTERSECTION
if (*InT>=0 || *OutT>=0) return(1);
return(0);
}
//--------------------------------------------------------------------------
// returns whether or not an edge AB intersects a set of planes. The hit
// times are returned just as in the ray isect test.
//--------------------------------------------------------------------------
int PlanesEdgeIsect(const float Planes[][4], int NumPlanes,
const float A[3], const float B[3],
float *InT, float *OutT)
{
float Dir[3] = {B[0]-A[0],B[1]-A[1],B[2]-A[2]};
if ( PlanesRayIsect(Planes,NumPlanes,A,Dir,InT,OutT) )
if (*InT>=0 && *InT<=1) return(1);
else if (*OutT>=0 && *OutT<=1) return(1);
return(0);
}

View File

@@ -1,51 +0,0 @@
//------------------------------------------------------------------------------
// File : plane.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//=========================================================================
// plane.hpp
//=========================================================================
// PLANE EQUATION COEFFICIENT GENERATION FUNCTIONS
float* PlaneEquation(float P[4],
const float p0[3], const float p1[3], const float p2[3]);
float* PlaneEquation(float P[4], const float N[3], float Dist);
float* PlaneEquation(float P[4], const float N[3], const float pt[3]);
int PlanePtOutTest(const float P[4], const float Pt[3]);
int PlanePtInOutTest(const float P[4], const float Pt[3]);
float PlaneDistToPt(const float P[4], const float Pt[3]);
int PlaneRayIsect(const float P[4], const float Start[3], const float Dir[3]);
int PlaneRayIsect(const float P[4], const float Start[3], const float Dir[3],
float IsectPt[3]);
int ZPlaneLineIsect(float d, const float Start[3], const float Dir[3],
float IsectPt[3]);
int PlaneEdgeIsect(const float P[4], const float A[3], const float B[3]);
int PlaneEdgeIsect(const float P[4], const float A[3], const float B[3],
float IsectPt[3]);
void XformPlane(const float M[16], float P[4]);
int PlaneMinMaxBoxOverlap(const float P[4], const float m[3],
const float M[3]);
int PlanesRayIsect(const float Planes[][4], int NumPlanes,
const float Start[3], const float Dir[3],
float *InT, float *OutT);
int PlanesEdgeIsect(const float Planes[][4], int NumPlanes,
const float A[3], const float B[3],
float *InT, float *OutT);

View File

@@ -1,106 +0,0 @@
//------------------------------------------------------------------------------
// File : tri.cpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// tri.cpp : triangle defs and intersection routines.
//============================================================================
#include <math.h>
//----------------------------------------------------------------------------
// CHECKS IF 2D POINT P IS IN A 2D TRI ABC.
//----------------------------------------------------------------------------
int PtInTri2D(float Px, float Py,
float Ax, float Ay, float Bx, float By, float Cx, float Cy)
{
float dABx=Bx-Ax, dABy=By-Ay, dBCx=Cx-Bx, dBCy=Cy-By; // "REPEATS"
if (dABx*dBCy < dABy*dBCx) // CW
{
if (dABx*(Py-Ay) >= dABy*(Px-Ax)) return(0); // ABxAP
if (dBCx*(Py-By) >= dBCy*(Px-Bx)) return(0); // BCxBP
if ((Ax-Cx)*(Py-Cy) >= (Ay-Cy)*(Px-Cx)) return(0); // CAxCP
}
else // CCW
{
if (dABx*(Py-Ay) < dABy*(Px-Ax)) return(0); // ABxAP
if (dBCx*(Py-By) < dBCy*(Px-Bx)) return(0); // BCxBP
if ((Ax-Cx)*(Py-Cy) < (Ay-Cy)*(Px-Cx)) return(0); // CAxCP
}
return(1); // "INSIDE" EACH EDGE'S IN-HALF-SPACE (PT P IS INSIDE TRIANGLE)
};
//----------------------------------------------------------------------------
// CHECKS IF 3D POINT P (ON ABC'S PLANE) IS IN 3D TRI ABC.
// P=PtOnTriPlane, N=PlaneNormal (does not have to be normalized)
//----------------------------------------------------------------------------
int PtInTri3D(const float P[3], float N[3],
const float A[3], const float B[3], const float C[3])
{
#define ABS(x) (((x)<0)?(-(x)):x) // HANDY UNIVERSAL ABSOLUTE VALUE FUNC
// DETERMINE LARGEST COMPONENT OF NORMAL (magnitude, since we want the largest projection)
N[0]=ABS(N[0]); N[1]=ABS(N[1]); N[2]=ABS(N[2]);
// PROJECT ONTO PLANE WHERE PERPENDICULAR TO LARGEST NORMAL COMPONENT AXIS
if (N[0]>N[1] && N[0]>N[2]) // X IS LARGEST SO PROJECT ONTO YZ-PLANE
return( PtInTri2D(P[1],P[2], A[1],A[2], B[1],B[2], C[1],C[2]) );
else if (N[1]>N[0] && N[1]>N[2]) // Y IS LARGEST SO PROJECT ONTO XZ-PLANE
return( PtInTri2D(P[0],P[2], A[0],A[2], B[0],B[2], C[0],C[2]) );
else // Z IS LARGEST SO PROJECT ONTO XY-PLANE
return( PtInTri2D(P[0],P[1], A[0],A[1], B[0],B[1], C[0],C[1]) );
}
//--------------------------------------------------------------------------
// Checks if an edge UV intersects a triangle ABC. Returns whether or
// not the edge intersects the plane (0 or 1) and the IsectPt.
//--------------------------------------------------------------------------
int EdgeTriIsect(const float U[3], const float V[3],
const float A[3], const float B[3], const float C[3],
float IsectPt[3])
{
// CALCULATE PLANE EQUATION COEFFICIENTS P FOR TRI ABC
float P[4];
float u[3] = {B[0]-A[0],B[1]-A[1],B[2]-A[2]};
float v[3] = {C[0]-A[0],C[1]-A[1],C[2]-A[2]};
P[0] = u[1]*v[2] - u[2]*v[1]; // CROSS-PROD BETWEEN u AND v
P[1] = u[2]*v[0] - u[0]*v[2]; // DEFINES UNNORMALIZED NORMAL
P[2] = u[0]*v[1] - u[1]*v[0];
float l = (float)sqrt(P[0]*P[0] + P[1]*P[1] + P[2]*P[2]); // NORMALIZE NORMAL
P[0]/=l; P[1]/=l; P[2]/=l;
P[3] = -(P[0]*A[0] + P[1]*A[1] + P[2]*A[2]);
// FIND INTERSECTION OF EDGE UV WITH PLANE P
int EdgeIsectsPlane=0;
float Dir[3] = { V[0]-U[0], V[1]-U[1], V[2]-U[2] };
float NdotDir = P[0]*Dir[0] + P[1]*Dir[1] + P[2]*Dir[2];
float NdotU = P[0]*U[0] + P[1]*U[1] + P[2]*U[2];
if (NdotDir==(float)0) return(0);
float t = (-P[3] - NdotU) / NdotDir;
if (t>=0 && t<=1)
{
IsectPt[0] = U[0] + Dir[0]*t;
IsectPt[1] = U[1] + Dir[1]*t;
IsectPt[2] = U[2] + Dir[2]*t;
EdgeIsectsPlane=1;
}
// FIRST, DOES THE EDGE INTERSECT THE PLANE?
if (!EdgeIsectsPlane) return(0);
// SEE IF ISECT PT IS IN THE TRI
return( PtInTri3D(IsectPt,P,A,B,C) );
}

View File

@@ -1,30 +0,0 @@
//------------------------------------------------------------------------------
// File : tri.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// tri.hpp : triangle defs and intersection routines.
//============================================================================
int PtInTri2D(float Px, float Py,
float Ax, float Ay, float Bx, float By, float Cx, float Cy);
int PtInTri3D(const float P[3], float N[3],
const float A[3], const float B[3], const float C[3]);
int EdgeTriIsect(const float U[3], const float V[3],
const float A[3], const float B[3], const float C[3],
float IsectPt[3]);

View File

@@ -1,137 +0,0 @@
//-----------------------------------------------------------------------------
// File : vec2f.hpp
//-----------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//-----------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Binaries may be compiled with
// this software without any royalties or restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//==========================================================================
// vec2.hpp : 2d vector class template. Works for any integer or real type.
//==========================================================================
#ifndef VEC2_H
#define VEC2_H
#include <stdio.h>
#include <math.h>
template<class Type>
class Vec2
{
public:
Type x, y;
Vec2 (void) {};
Vec2 (const Type X, const Type Y) { x=X; y=Y; };
Vec2 (const Vec2& v) { x=v.x; y=v.y; };
Vec2 (const Type v[2]) { x=v[0]; y=v[1]; };
void Set (const Type X, const Type Y) { x=X; y=Y; }
void Set (const Type v[2]) { x=v[0]; y=v[1]; };
operator Type*() // Type * CONVERSION
{ return (Type *)&x; }
operator const Type*() const // CONST Type * CONVERSION
{ return &x; }
Vec2& operator = (const Vec2& A) // ASSIGNMENT (=)
{ x=A.x; y=A.y;
return(*this); };
bool operator == (const Vec2& A) const // COMPARISON (==)
{ return (x==A.x && y==A.y); }
bool operator != (const Vec2& A) const // COMPARISON (!=)
{ return (x!=A.x || y!=A.y); }
Vec2 operator + (const Vec2& A) const // ADDITION (+)
{ Vec2 Sum(x+A.x, y+A.y);
return(Sum); }
Vec2 operator - (const Vec2& A) const // SUBTRACTION (-)
{ Vec2 Diff(x-A.x, y-A.y);
return(Diff); }
Type operator * (const Vec2& A) const // DOT-PRODUCT (*)
{ Type DotProd = x*A.x+y*A.y;
return(DotProd); }
Type operator / (const Vec2& A) const // CROSS-PRODUCT (/)
{ Type CrossProd = x*A.y-y*A.x;
return(CrossProd); }
Type operator ^ (const Vec2& A) const // ALSO CROSS-PRODUCT (^)
{ Type CrossProd = x*A.y-y*A.x;
return(CrossProd); }
Vec2 operator * (const Type s) const // MULTIPLY BY SCALAR (*)
{ Vec2 Scaled(x*s, y*s);
return(Scaled); }
Vec2 operator / (const Type s) const // DIVIDE BY SCALAR (/)
{ Vec2 Scaled(x/s, y/s);
return(Scaled); }
Vec2 operator & (const Vec2& A) const // COMPONENT MULTIPLY (&)
{ Vec2 CompMult(x*A.x, y*A.y);
return(CompMult); }
friend inline Vec2 operator *(Type s, const Vec2& v) // SCALAR MULT s*V
{ return Vec2(v.x*s, v.y*s); }
Vec2& operator += (const Vec2& A) // ACCUMULATED VECTOR ADDITION (+=)
{ x+=A.x; y+=A.y; return *this; }
Vec2& operator -= (const Vec2& A) // ACCUMULATED VECTOR SUBTRACTION (-=)
{ x-=A.x; y-=A.y; return *this; }
Vec2& operator *= (const Type s) // ACCUMULATED SCALAR MULT (*=)
{ x*=s; y*=s; return *this; }
Vec2& operator /= (const Type s) // ACCUMULATED SCALAR DIV (/=)
{ x/=s; y/=s; return *this; }
Vec2& operator &= (const Vec2& A) // ACCUMULATED COMPONENT MULTIPLY (&=)
{ x*=A.x; y*=A.y; return *this; }
Vec2 operator - (void) const // NEGATION (-)
{ Vec2 Negated(-x, -y);
return(Negated); };
/*
const Type& operator [] (const int i) const // ALLOWS VECTOR ACCESS AS AN ARRAY.
{ return( (i==0)?x:y ); };
Type & operator [] (const int i)
{ return( (i==0)?x:y ); };
*/
Type Length (void) const // LENGTH OF VECTOR
{ return ((Type)sqrt(x*x+y*y)); };
Type LengthSqr (void) const // LENGTH OF VECTOR (SQUARED)
{ return (x*x+y*y); };
Vec2& Normalize (void) // NORMALIZE VECTOR
{ Type L = Length(); // CALCULATE LENGTH
if (L>0) { x/=L; y/=L; }
return *this;
}; // DIV COMPONENTS BY LENGTH
Vec2 Perpendicular() const // RETURNS A PERPENDICULAR
{ Vec2 Perp(-y,x);
return(Perp); }
void UpdateMinMax(Vec2 &Min, Vec2 &Max)
{
if (x<Min.x) Min.x=x; else if (x>Max.x) Max.x=x;
if (y<Min.y) Min.y=y; else if (y>Max.y) Max.y=y;
}
void Print() const
{ printf("(%.3f, %.3f)\n",x, y); }
static Vec2 ZERO;
};
typedef Vec2<float> Vec2f;
typedef Vec2<double> Vec2d;
template<class Type> Vec2<Type> Vec2<Type>::ZERO = Vec2<Type>(0,0);
#endif

View File

@@ -1,244 +0,0 @@
//-----------------------------------------------------------------------------
// File : vec3f.hpp
//-----------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//-----------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Binaries may be compiled with
// this software without any royalties or restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//==========================================================================
// Vec3.hpp : 3d vector class template. Works for any integer or real type.
//==========================================================================
#ifndef VEC3_H
#define VEC3_H
#include <stdio.h>
#include <math.h>
/**
* @class Vec3
* @brief A templated 3-vector class
*
* Everybody in graphics has to write their own basic 3-vector class.
* And we're no exception. This one uses templates, so that with one
* definition of the class you can have a 3-vector of floats or doubles
* depending on how precise you are, or you can make 3-vectors of ints
* or unsigned char, handy for representing colors.
*
* A couple of typedefs for common instatiations are provided by
* default: Vec3f, and Vec3d, the float and double versions,
* respectively.
*
*/
template<class Type>
class Vec3
{
public:
Type x, y, z; ///< The storage for the three components of the vector
/// Default constructor.
/// Note: does \em not initialize x, y, and z!
Vec3 (void)
{};
/// Three component constructor
Vec3 (const Type X, const Type Y, const Type Z)
{ x=X; y=Y; z=Z; };
/// Copy constructor
Vec3 (const Vec3& v)
{ x=v.x; y=v.y; z=v.z; };
/// Construct from array
Vec3 (const Type v[3])
{ x=v[0]; y=v[1]; z=v[2]; };
/// Set from components
void Set (const Type X, const Type Y, const Type Z)
{ x=X; y=Y; z=Z; }
/// Set from array
void Set (const Type v[3])
{ x=v[0]; y=v[1]; z=v[2]; };
operator Type*() /// Type * CONVERSION
{ return (Type *)&x; }
operator const Type*() const /// CONST Type * CONVERSION
{ return &x; }
bool operator == (const Vec3& A) const /// COMPARISON (==)
{ return (x==A.x && y==A.y && z==A.z); }
bool operator != (const Vec3& A) const /// COMPARISON (!=)
{ return (x!=A.x || y!=A.y || z!=A.z); }
Vec3& operator = (const Vec3& A) /// ASSIGNMENT (=)
{ x=A.x; y=A.y; z=A.z;
return(*this); };
Vec3 operator + (const Vec3& A) const /// ADDITION (+)
{ Vec3 Sum(x+A.x, y+A.y, z+A.z);
return(Sum); };
Vec3 operator - (const Vec3& A) const /// SUBTRACTION (-)
{ Vec3 Diff(x-A.x, y-A.y, z-A.z);
return(Diff); };
Type operator * (const Vec3& A) const /// DOT-PRODUCT (*)
{ Type DotProd = x*A.x+y*A.y+z*A.z;
return(DotProd); };
Vec3 operator / (const Vec3& A) const /// CROSS-PRODUCT (/)
{ Vec3 CrossProd(y*A.z-z*A.y, z*A.x-x*A.z, x*A.y-y*A.x);
return(CrossProd); };
Vec3 operator ^ (const Vec3& A) const /// ALSO CROSS-PRODUCT (^)
{ Vec3 CrossProd(y*A.z-z*A.y, z*A.x-x*A.z, x*A.y-y*A.x);
return(CrossProd); };
Vec3 operator * (const Type s) const /// MULTIPLY BY SCALAR V*s (*)
{ Vec3 Scaled(x*s, y*s, z*s);
return(Scaled); };
Vec3 operator / (const Type s) const /// DIVIDE BY SCALAR (/)
{ Vec3 Scaled(x/s, y/s, z/s);
return(Scaled); };
Vec3 operator & (const Vec3& A) const /// COMPONENT MULTIPLY (&)
{ Vec3 CompMult(x*A.x, y*A.y, z*A.z);
return(CompMult); }
friend inline Vec3 operator *(Type s, const Vec3& v) /// SCALAR MULT s*V
{ return Vec3(v.x*s, v.y*s, v.z*s); }
Vec3& operator += (const Vec3& A) /// ACCUMULATED VECTOR ADDITION (+=)
{ x+=A.x; y+=A.y; z+=A.z;
return *this;}
Vec3& operator -= (const Vec3& A) /// ACCUMULATED VECTOR SUBTRACTION (-=)
{ x-=A.x; y-=A.y; z-=A.z;
return *this; }
Vec3& operator *= (const Type s) /// ACCUMULATED SCALAR MULT (*=)
{ x*=s; y*=s; z*=s;
return *this; }
Vec3& operator /= (const Type s) /// ACCUMULATED SCALAR DIV (/=)
{ x/=s; y/=s; z/=s;
return *this; }
Vec3& operator &= (const Vec3& A) /// ACCUMULATED COMPONENT MULTIPLY (&=)
{ x*=A.x; y*=A.y; z*=A.z; return *this; }
Vec3 operator - (void) const /// NEGATION (-)
{ Vec3 Negated(-x, -y, -z);
return(Negated); };
/*
const Type& operator [] (const int i) const // ALLOWS VECTOR ACCESS AS AN ARRAY.
{ return( (i==0)?x:((i==1)?y:z) ); };
Type & operator [] (const int i)
{ return( (i==0)?x:((i==1)?y:z) ); };
*/
Type Length (void) const /// LENGTH OF VECTOR
{ return ((Type)sqrt(x*x+y*y+z*z)); };
Type LengthSqr (void) const /// LENGTH OF VECTOR (SQUARED)
{ return (x*x+y*y+z*z); };
Vec3& Normalize (void) /// NORMALIZE VECTOR
{ Type L = Length(); // CALCULATE LENGTH
if (L>0) { x/=L; y/=L; z/=L; } // DIV COMPONENTS BY LENGTH
return *this;
};
/// Returns the 'star' matrix for a vector
/** This is the skew-symmetric matrix \b A such that
* \b A \b v == \p this x \b v
* (the cross-product of \p this and \b v), for any vector \b v.
* The matrix looks like this given vector (x,y,z):
* @verbatim
| 0 -z y|
| z 0 -x|
|-y x 0|
@endverbatim
*
* Return format is just an array in row-major (OpenGL/Fortran) order.
* That is [0, -z, y, z, 0, -x, -y, x, 0].
*/
Type* Star() const {
Type s[] = ( 0, -z, y,
z, 0, -x,
-y, x, 0);
return s;
}
/// Update \p Min and \p Max to enclose \p this
/** A very handy routine for working with min-max or axis aligned
* bounding boxes.
*/
void UpdateMinMax(Vec3 &Min, Vec3 &Max) const
{
if (x<Min.x) Min.x=x; else if (x>Max.x) Max.x=x;
if (y<Min.y) Min.y=y; else if (y>Max.y) Max.y=y;
if (z<Min.z) Min.z=z; else if (z>Max.z) Max.z=z;
}
/// Construct an orthonormal basis from \p this
/** Compute two unit vectors \p U and \p V that are orthogonal
* to this vector and to each other. Note that \p *this need
* not be a unit vector.
*
* The algorithm works as follows:
* Find smallest component of L (this), zero it,
* negate one of the other two and swap them. Then normalize.
* Ex. if x1 is the smallest, assign (x2,y2,z2):=(0,z1,-y1)
* Clearly now v1 dot v2 = x1*0 + y1*z1 + z1*-y1 = 0;
* Zeroing out the smallest means that the magnitude of
* the remaining vector will be as big as possible so that
* when we normalize, we are safe from dividing by anything
* close to zero (unless *this was near 0 magnitude to
* begin with, in which case lack of precision can't be avoided)
*/
void CompleteOrthonormalBasis(Vec3 &U, Vec3 &V) const
{
U = *this;
unsigned char s[3] = {0, 1, 2};
unsigned char tmpa;
U.x = U.x < 0 ? -U.x : -U.x;
U.y = U.y < 0 ? -U.y : -U.y;
U.z = U.z < 0 ? -U.z : -U.z;
if ( U[0] > U[1] )
{
tmpa = s[0];
s[0] = s[1];
s[1] = tmpa;
}
// xy min in s[0] now.
if ( U[s[0]] > U[2] ) {
tmpa = s[2];
s[2] = s[0];
s[0] = tmpa;
}
// xyz min in s[0] now
U = *this;
U[s[0]] = 0;
// Voila U is now perpendicular to *this
U.Normalize();
// And so it's easy to find a v that is too, with cross product.
V = *this ^ U;
// Or by removing components projected onto other two...
// I think the cross product may be cheaper
// V = something - V * (*this.Normalize() + U);
V.Normalize(); // wouldn't be necessary if we knew *this were normalized
}
/// Dump the vector to \c stdout in a pretty way
void Print() const
{ printf("(%.3f, %.3f, %.3f)\n",x, y, z); }
/// This is a handy way to get the zero vector just use Vec3<Type>::ZERO
static Vec3 ZERO;
};
typedef Vec3<float> Vec3f;
typedef Vec3<double> Vec3d;
template<class Type> Vec3<Type> Vec3<Type>::ZERO = Vec3<Type>(0,0,0);
#endif

View File

@@ -1,95 +0,0 @@
//------------------------------------------------------------------------------
// File : vec3fv.cpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// vec3fv.cpp
//============================================================================
#include <stdio.h>
#include <math.h>
void Set3fv(float v[3], float x, float y, float z)
{
v[0]=x;
v[1]=y;
v[2]=z;
}
void Copy3fv(float A[3], const float B[3]) // A=B
{
A[0]=B[0];
A[1]=B[1];
A[2]=B[2];
}
void ScalarMult3fv(float c[3], const float a[3], float s) // c=a*s
{
c[0] = a[0] * s;
c[1] = a[1] * s;
c[2] = a[2] * s;
}
void ScalarDiv3fv(float v[3], float s)
{
v[0] /= s;
v[1] /= s;
v[2] /= s;
}
void Add3fv(float c[3], const float a[3], const float b[3]) // c = a + b
{
c[0] = a[0] + b[0];
c[1] = a[1] + b[1];
c[2] = a[2] + b[2];
}
void Subtract3fv(float c[3], const float a[3], const float b[3]) // c = a - b
{
c[0] = a[0] - b[0];
c[1] = a[1] - b[1];
c[2] = a[2] - b[2];
}
void Negate3fv(float a[3], const float b[3]) // a = -b
{
a[0] = -b[0];
a[1] = -b[1];
a[2] = -b[2];
}
float Length3fv(const float v[3])
{
return( (float)sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]) );
}
void Normalize3fv(float v[3])
{
float l = Length3fv(v);
v[0] /= l;
v[1] /= l;
v[2] /= l;
}
float DotProd3fv(const float a[3], const float b[3])
{
return( a[0]*b[0] + a[1]*b[1] + a[2]*b[2] );
}
void CrossProd3fv(float* C, const float* A, const float* B) // C = A X B
{
Set3fv(C, A[1]*B[2]-A[2]*B[1], A[2]*B[0]-A[0]*B[2], A[0]*B[1]-A[1]*B[0]);
}

View File

@@ -1,34 +0,0 @@
//------------------------------------------------------------------------------
// File : vec3fv.hpp
//------------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//============================================================================
// vec3fv.hpp
//============================================================================
void Set3fv(float v[3], float x, float y, float z);
void Copy3fv(float A[3], const float B[3]); // A=B
void ScalarMult3fv(float c[3], const float a[3], float s);
void ScalarDiv3fv(float v[3], float s);
void Add3fv(float c[3], const float a[3], const float b[3]); // c = a + b
void Subtract3fv(float c[3], const float a[3], const float b[3]); // c = a - b
void Negate3fv(float a[3], const float b[3]); // a = -b
float Length3fv(const float v[3]);
void Normalize3fv(float v[3]);
float DotProd3fv(const float a[3], const float b[3]);
void CrossProd3fv(float* C, const float* A, const float* B); // C = A X B

View File

@@ -1,136 +0,0 @@
//-----------------------------------------------------------------------------
// File : vec4f.hpp
//-----------------------------------------------------------------------------
// GLVU : Copyright 1997 - 2002
// The University of North Carolina at Chapel Hill
//-----------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Binaries may be compiled with
// this software without any royalties or restrictions.
//
// The University of North Carolina at Chapel Hill makes no representations
// about the suitability of this software for any purpose. It is provided
// "as is" without express or implied warranty.
//==========================================================================
// vec4.hpp : 4d vector class template. Works for any integer or real type.
//==========================================================================
#ifndef VEC4_H
#define VEC4_H
#include <stdio.h>
#include <math.h>
template <class Type>
class Vec4
{
public:
Type x, y, z, w;
Vec4 (void)
{};
Vec4 (const Type X, const Type Y, const Type Z, const Type W)
{ x=X; y=Y; z=Z; w=W; };
Vec4 (const Vec4& v)
{ x=v.x; y=v.y; z=v.z; w=v.w; };
Vec4 (const Type v[4])
{ x=v[0]; y=v[1]; z=v[2]; w=v[3]; };
void Set (const Type X, const Type Y, const Type Z, const Type W)
{ x=X; y=Y; z=Z; w=W; }
void Set (const Type v[4])
{ x=v[0]; y=v[1]; z=v[2]; w=v[3]; };
operator Type*() // Type * CONVERSION
{ return (Type *)&x; }
operator const Type*() const // CONST Type * CONVERSION
{ return &x; }
Vec4& operator = (const Vec4& A) // ASSIGNMENT (=)
{ x=A.x; y=A.y; z=A.z; w=A.w;
return(*this); };
bool operator == (const Vec4& A) const // COMPARISON (==)
{ return (x==A.x && y==A.y &&
z==A.z && w==A.w); }
bool operator != (const Vec4& A) const // COMPARISON (!=)
{ return (x!=A.x || y!=A.y ||
z!=A.z || w!=A.w); }
Vec4 operator + (const Vec4& A) const // ADDITION (+)
{ Vec4 Sum(x+A.x, y+A.y, z+A.z, w+A.w);
return(Sum); };
Vec4 operator - (const Vec4& A) const // SUBTRACTION (-)
{ Vec4 Diff(x-A.x, y-A.y, z-A.z, w-A.w);
return(Diff); };
Type operator * (const Vec4& A) const // DOT-PRODUCT (*)
{ Type DotProd = x*A.x+y*A.y+z*A.z+w*A.w;
return(DotProd); };
Vec4 operator * (const Type s) const // MULTIPLY BY SCALAR (*)
{ Vec4 Scaled(x*s, y*s, z*s, w*s);
return(Scaled); };
Vec4 operator / (const Type s) const // DIVIDE BY SCALAR (/)
{ Vec4 Scaled(x/s, y/s, z/s, w/s);
return(Scaled); };
Vec4 operator & (const Vec4& A) const // COMPONENT MULTIPLY (&)
{ Vec4 CompMult(x*A.x, y*A.y, z*A.z, w*A.w);
return(CompMult); }
friend inline Vec4 operator *(Type s, const Vec4& v) // SCALAR MULT s*V
{ return Vec4(v.x*s, v.y*s, v.z*s, v.w*s); }
Vec4& operator += (const Vec4& A) // ACCUMULATED VECTOR ADDITION (+=)
{ x+=A.x; y+=A.y; z+=A.z; w+=A.w;
return *this; }
Vec4& operator -= (const Vec4& A) // ACCUMULATED VECTOR SUBTRCT (-=)
{ x-=A.x; y-=A.y; z-=A.z; w-=A.w;
return *this; }
Vec4& operator *= (const Type s) // ACCUMULATED SCALAR MULT (*=)
{ x*=s; y*=s; z*=s; w*=s;
return *this; }
Vec4& operator /= (const Type s) // ACCUMULATED SCALAR DIV (/=)
{ x/=s; y/=s; z/=s; w/=s;
return *this; }
Vec4& operator &= (const Vec4& A) // ACCUMULATED COMPONENT MULTIPLY (&=)
{ x*=A.x; y*=A.y; z*=A.z; w*=A.w; return *this; }
Vec4 operator - (void) const // NEGATION (-)
{ Vec4 Negated(-x, -y, -z, -w);
return(Negated); };
/*
const Type& operator [] (const int i) const // ALLOWS VECTOR ACCESS AS AN ARRAY.
{ return( (i==0)?x:((i==1)?y:((i==2)?z:w)) ); };
Type & operator [] (const int i)
{ return( (i==0)?x:((i==1)?y:((i==2)?z:w)) ); };
*/
Type Length (void) const // LENGTH OF VECTOR
{ return ((Type)sqrt(x*x+y*y+z*z+w*w)); };
Type LengthSqr (void) const // LENGTH OF VECTOR (SQUARED)
{ return (x*x+y*y+z*z+w*w); };
Vec4& Normalize (void) // NORMALIZE VECTOR
{ Type L = Length(); // CALCULATE LENGTH
if (L>0) { x/=L; y/=L; z/=L; w/=L; }
return *this;
}; // DIV COMPONENTS BY LENGTH
void Wdiv(void)
{ x/=w; y/=w; z/=w; w=1; }
void Print() const
{ printf("(%.3f, %.3f, %.3f, %.3f)\n",x, y, z, w); }
static Vec4 ZERO;
};
typedef Vec4<float> Vec4f;
typedef Vec4<double> Vec4d;
template<class Type> Vec4<Type> Vec4<Type>::ZERO = Vec4<Type>(0,0,0,0);
#endif