Work in progress Caelum integration

actorid
athile 15 years ago
parent 3ed03fee2f
commit 52a3233243

@ -76,7 +76,8 @@ find_package(Boost REQUIRED COMPONENTS system filesystem program_options)
find_package(OIS REQUIRED)
include_directories("."
${OGRE_INCLUDE_DIR} ${OIS_INCLUDE_DIR} ${Boost_INCLUDE_DIR}
${PLATFORM_INCLUDE_DIR})
${PLATFORM_INCLUDE_DIR}
${CMAKE_HOME_DIRECTORY}/extern/caelum/include )
link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR})
# Specify build paths
@ -123,7 +124,8 @@ add_executable(openmw
target_link_libraries(openmw
${OGRE_LIBRARIES}
${OIS_LIBRARIES}
${Boost_LIBRARIES})
${Boost_LIBRARIES}
caelum)
if (APPLE)
find_library(CARBON_FRAMEWORK Carbon)
@ -144,3 +146,5 @@ if (APPLE)
MACOSX_BUNDLE_BUNDLE_NAME "OpenMW"
)
endif (APPLE)
ADD_SUBDIRECTORY( extern/caelum )

@ -44,6 +44,7 @@ struct Light
model = esm.getHNString("MODL");
name = esm.getHNOString("FNAM");
icon = esm.getHNOString("ITEX");
assert(sizeof(data) == 24);
esm.getHNT(data, "LHDT", 24);
script = esm.getHNOString("SCRI");
sound = esm.getHNOString("SNAM");

@ -0,0 +1,11 @@
project(Caelum)
ADD_DEFINITIONS(-DCAELUM_LIB)
INCLUDE_DIRECTORIES( ${CMAKE_HOME_DIRECTORY}/extern/caelum/include )
file(GLOB_RECURSE CAELUM_SRC src/*)
file(GLOB_RECURSE CAELUM_HDR include/*)
set(SOURCES ${CAELUM_SRC} ${CAELUM_HDR})
add_library(caelum STATIC ${SOURCES})

@ -0,0 +1,228 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__ASTRONOMY_H
#define CAELUM__ASTRONOMY_H
#include "CaelumPrerequisites.h"
namespace Caelum
{
/** Static class with astronomy routines.
* This class contains various astronomical routines useful in Caelum.
*
* Most of the formulas are from http://stjarnhimlen.se/comp/ppcomp.html
* That site contains much more than was implemented here; it has code
* for determining the positions of all the planets. Only the sun and
* moon are actually useful for caelum.
*
* The formulas are isolated here in pure procedural code for easier
* testing (Tests are done as assertions in the demo).
*
* Precision is vital here, so this class uses Caelum::LongReal(double)
* instead of Ogre::Real(float) for precission. All angles are in degrees
* unless otherwise mentioned. Ogre::Degree and Ogre::Radian use
* Ogre::Real and should be avoided here.
*/
class CAELUM_EXPORT Astronomy
{
private:
Astronomy() {}
static const LongReal PI;
/** Normalize an angle to the 0, 360 range.
* @param x The angle to normalize
*/
static LongReal normalizeDegrees (LongReal x);
/// Convert radians to degrees.
static LongReal radToDeg (LongReal x);
/// Convert degrees to radians.
static LongReal degToRad (LongReal x);
static LongReal sinDeg (LongReal x);
static LongReal cosDeg (LongReal x);
static LongReal atan2Deg (LongReal y, LongReal x);
public:
/// January 1, 2000, noon
static const LongReal J2000;
/** Convert from ecliptic to ecuatorial spherical coordinates, in radians.
* @param lon Ecliptic longitude
* @param lat Ecliptic latitude
* @param rasc Right ascension
* @param decl Declination
* @warning: This function works in radians.
*/
static void convertEclipticToEquatorialRad (
LongReal lon, LongReal lat,
LongReal& rasc, LongReal& decl);
static void convertRectangularToSpherical (
LongReal x, LongReal y, LongReal z,
LongReal &rasc, LongReal &decl, LongReal &dist);
static void convertSphericalToRectangular (
LongReal rasc, LongReal decl, LongReal dist,
LongReal &x, LongReal &y, LongReal &z);
/** Convert from equatorial to horizontal coordinates.
* This function converts from angles relative to the earth's equator
* to angle relative to the horizon at a given point.
* @param jday Astronomical time as julian day.
* @param longitude Observer's longitude in degrees east.
* @param latitude Observer's latitude in degrees north.
* @param rasc Object's right ascension.
* @param decl Object's declination.
* @param azimuth Object's azimuth (clockwise degrees from true north).
* @param altitude Object's altitude (degrees above the horizon).
*/
static void convertEquatorialToHorizontal (
LongReal jday,
LongReal longitude, LongReal latitude,
LongReal rasc, LongReal decl,
LongReal &azimuth, LongReal &altitude);
/** Get the sun's position in the sky in, relative to the horizon.
* @param jday Astronomical time as julian day.
* @param longitude Observer longitude
* @param latitude Observer latitude
* @param azimuth Astronomical azimuth, measured clockwise from North = 0.
* @param altitude Astronomical altitude, elevation above the horizon.
*/
static void getHorizontalSunPosition (
LongReal jday,
LongReal longitude, LongReal latitude,
LongReal &azimuth, LongReal &altitude);
static void getHorizontalSunPosition (
LongReal jday,
Ogre::Degree longitude, Ogre::Degree latitude,
Ogre::Degree &azimuth, Ogre::Degree &altitude);
/// Gets the moon position at a specific time in ecliptic coordinates
/// @param lon: Ecliptic longitude, in radians.
/// @param lat: Ecliptic latitude, in radians.
static void getEclipticMoonPositionRad (
LongReal jday,
LongReal &lon,
LongReal &lat);
static void getHorizontalMoonPosition (
LongReal jday,
LongReal longitude, LongReal latitude,
LongReal &azimuth, LongReal &altitude);
static void getHorizontalMoonPosition (
LongReal jday,
Ogre::Degree longitude, Ogre::Degree latitude,
Ogre::Degree &azimuth, Ogre::Degree &altitude);
/** Get astronomical julian day from normal gregorian calendar.
* From wikipedia: the integer number of days that have elapsed
* since the initial epoch defined as
* noon Universal Time (UT) Monday, January 1, 4713 BC
* @note this is the time at noon, not midnight.
*/
static int getJulianDayFromGregorianDate (
int year, int month, int day);
/** Get astronomical julian day from normal gregorian calendar.
* Calculate julian day from a day in the normal gregorian calendar.
* Time should be given as UTC.
* @see http://en.wikipedia.org/wiki/Julian_day
*/
static LongReal getJulianDayFromGregorianDateTime (
int year, int month, int day,
int hour, int minute, LongReal second);
/** Get astronomical julian day from normal gregorian calendar.
* @see above (I don't know the proper doxygen syntax).
*/
static LongReal getJulianDayFromGregorianDateTime (
int year, int month, int day,
LongReal secondsFromMidnight);
/// Get gregorian date from integer julian day.
static void getGregorianDateFromJulianDay (
int julianDay, int &year, int &month, int &day);
/// Get gregorian date time from floating point julian day.
static void getGregorianDateTimeFromJulianDay (
LongReal julianDay, int &year, int &month, int &day,
int &hour, int &minute, LongReal &second);
/// Get gregorian date from floating point julian day.
static void getGregorianDateFromJulianDay (
LongReal julianDay, int &year, int &month, int &day);
/** Enter high-precission floating-point mode.
*
* By default Direct3D decreases the precission of ALL floating
* point calculations, enough to stop Caelum's astronomy routines
* from working correctly.
*
* To trigger this behaviour in a standard ogre demo select the
* Direct3D render system and set "Floating-point mode" to
* "Fastest". Otherwise it's not a problem.
*
* It can be fixed by changing the precission only inside caelum's
* astronomy routines using the _controlfp function. This only works
* for MSVC on WIN32; This is a no-op on other compilers.
*
* @note: Must be paired with restoreFloatingPointMode.
* @return Value to pass to restoreFloatingModeMode.
*/
static int enterHighPrecissionFloatingPointMode ();
/** Restore old floating point precission.
* @see enterHighPrecissionFloatingPointMode.
*/
static void restoreFloatingPointMode (int oldMode);
};
/** Dummy class to increase floting point precission in a block
* This class will raise precission in the ctor and restore it
* in the destructor. During it's lifetime floating-point
* precission will be increased.
*
* To use this class just create a instance on the stack at the start of a block.
*
* @see Astronomy::enterHighPrecissionFloatingPointMode
*/
class CAELUM_EXPORT ScopedHighPrecissionFloatSwitch
{
private:
int mOldFpMode;
public:
inline ScopedHighPrecissionFloatSwitch() {
mOldFpMode = Astronomy::enterHighPrecissionFloatingPointMode ();
}
inline ~ScopedHighPrecissionFloatSwitch() {
Astronomy::restoreFloatingPointMode (mOldFpMode);
}
};
}
#endif // CAELUM__ASTRONOMY_H

@ -0,0 +1,44 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM_H
#define CAELUM_H
#include "CaelumPrerequisites.h"
#include "CaelumScriptTranslator.h"
#include "TypeDescriptor.h"
#include "CaelumPlugin.h"
#include "CaelumExceptions.h"
#include "CaelumSystem.h"
#include "CameraBoundElement.h"
#include "SkyDome.h"
#include "Sun.h"
#include "Moon.h"
#include "UniversalClock.h"
#include "Astronomy.h"
#include "CloudSystem.h"
#include "PrecipitationController.h"
#include "FlatCloudLayer.h"
#include "ImageStarfield.h"
#include "PointStarfield.h"
#include "GroundFog.h"
#include "DepthComposer.h"
#endif // CAELUM_H

@ -0,0 +1,54 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__CAELUM_EXCEPTIONS_H
#define CAELUM__CAELUM_EXCEPTIONS_H
#include "CaelumPrerequisites.h"
namespace Caelum
{
/** Exception class for unsupported features.
* This is frequently thrown if a certain required material does not load;
* most likely because the hardware does not support the required shaders.
*/
class CAELUM_EXPORT UnsupportedException : public Ogre::Exception
{
public:
/// Constructor.
UnsupportedException
(
int number,
const Ogre::String &description,
const Ogre::String &source,
const char *file,
long line
):
Ogre::Exception (number, description, source, "UnsupportedException", file, line)
{
}
};
#define CAELUM_THROW_UNSUPPORTED_EXCEPTION(desc, src) \
throw UnsupportedException(-1, (desc), (src), __FILE__, __LINE__);
}
#endif // CAELUM__CAELUM_EXCEPTIONS_H

@ -0,0 +1,97 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__CAELUM_PLUGIN_H
#define CAELUM__CAELUM_PLUGIN_H
#include "CaelumPrerequisites.h"
#include "CaelumScriptTranslator.h"
#include "TypeDescriptor.h"
#include "OgrePlugin.h"
namespace Caelum
{
/** Implement an Ogre::Plugin for Caelum.
*
* Ogre plugins are usually loaded from config files and they register
* various stuff in ogre managers. But you can also just link to the
* library normally and call install functions manually.
*/
class CAELUM_EXPORT CaelumPlugin: public Ogre::Singleton<CaelumPlugin>, public Ogre::Plugin
{
public:
/// Get reference to singleton instance; or crash if N/A.
static CaelumPlugin& getSingleton(void);
/// Get pointer to singleton instance; or pointer if N/A.
static CaelumPlugin* getSingletonPtr(void);
CaelumPlugin();
~CaelumPlugin();
virtual void install ();
virtual void initialise ();
virtual void shutdown ();
virtual void uninstall ();
static const Ogre::String CAELUM_PLUGIN_NAME;
virtual const String& getName () const;
// Determine if the plugin was installed (if install was called).
inline bool isInstalled () const { return mIsInstalled; }
private:
bool mIsInstalled;
#if CAELUM_TYPE_DESCRIPTORS
public:
/// Get default type descriptor data for caelum components.
CaelumDefaultTypeDescriptorData* getTypeDescriptorData () { return &mTypeDescriptorData; }
private:
CaelumDefaultTypeDescriptorData mTypeDescriptorData;
#endif
#if CAELUM_SCRIPT_SUPPORT
public:
/** Load CaelumSystem and it's components from a script file.
* @param sys Target CaelumSystem.
* This is cleared using CaelumSystem::clear before loading.
* If scripting data is not found then this is not modified.
* @param objectName Name of caelum_sky_system from *.os file.
* @param scriptFileGroup The group to search in (unused in Ogre 1.6)
*/
void loadCaelumSystemFromScript (
CaelumSystem* sys,
const Ogre::String& objectName,
const Ogre::String& scriptFileGroup = Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME
);
/// @see PropScriptResourceManager
PropScriptResourceManager* getPropScriptResourceManager () { return &mPropScriptResourceManager; }
CaelumScriptTranslatorManager* getScriptTranslatorManager () { return &mScriptTranslatorManager; }
private:
PropScriptResourceManager mPropScriptResourceManager;
CaelumScriptTranslatorManager mScriptTranslatorManager;
#endif
};
}
#endif // CAELUM__CAELUM_PLUGIN_H

@ -0,0 +1,25 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef __APPLE__
#include "Ogre/Ogre.h"
#else
#include "Ogre.h"
#endif

@ -0,0 +1,177 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__CAELUM_PREREQUISITES_H
#define CAELUM__CAELUM_PREREQUISITES_H
// Include external headers
#ifdef __APPLE__
#include "Ogre/Ogre.h"
#else
#include "Ogre.h"
#endif
#include <memory>
// Define the dll export qualifier if compiling for Windows
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#ifdef CAELUM_LIB
#define CAELUM_EXPORT __declspec (dllexport)
#else
#ifdef __MINGW32__
#define CAELUM_EXPORT
#else
#define CAELUM_EXPORT __declspec (dllimport)
#endif
#endif
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#define CAELUM_EXPORT __attribute__ ((visibility("default")))
#else
#define CAELUM_EXPORT
#endif
// Define the version code
#define CAELUM_VERSION_MAIN 0
#define CAELUM_VERSION_SEC 5
#define CAELUM_VERSION_TER 0
#define CAELUM_VERSION = (CAELUM_VERSION_MAIN << 16) | (CAELUM_VERSION_SEC << 8) | CAELUM_VERSION_TER
// By default only compile type descriptors for scripting.
#ifndef CAELUM_TYPE_DESCRIPTORS
#if (OGRE_VERSION >= 0x00010600) && OGRE_USE_NEW_COMPILERS
#define CAELUM_TYPE_DESCRIPTORS 1
#else
#define CAELUM_TYPE_DESCRIPTORS 0
#endif
#endif
// Scripting support requires Ogre 1.6
// Can be also configured on compiler command line
#ifndef CAELUM_SCRIPT_SUPPORT
#if (OGRE_VERSION >= 0x00010600) && OGRE_USE_NEW_COMPILERS
#define CAELUM_SCRIPT_SUPPORT 1
#else
#define CAELUM_SCRIPT_SUPPORT 0
#endif
#else
#if !(OGRE_VERSION > 0x00010600)
#error "Caelum script support requires Ogre 1.6."
#endif
#if !(OGRE_USE_NEW_COMPILERS)
#error "Caelum script support requires Ogre 1.6 with OGRE_USE_NEW_COMPILERS."
#endif
#if !(CAELUM_TYPE_DESCRIPTORS)
#error "Caelum script support also requires type descriptors."
#endif
#endif
/// @file
/** @mainpage
*
* %Caelum is an Ogre add-on for atmospheric rendering. It is composed of a
* number of small mostly self-contained components and a big
* Caelum::CaelumSystem class which ties them all together in an easy-to-use
* way.
*
* More information is available on the wiki page:
* http://www.ogre3d.org/wiki/index.php/Caelum
*
* You can discuss and report issues in the forum:
* http://www.ogre3d.org/addonforums/viewforum.php?f=21
*/
/** Caelum namespace
*
* All of %Caelum is inside this namespace (except for macros).
*
* @note: This was caelum with a lowercase 'c' in version 0.3
*/
namespace Caelum
{
// Caelum needs a lot of precission for astronomical calculations.
// Very few calculations use it, and the precission IS required.
typedef double LongReal;
// Use some ogre types.
using Ogre::uint8;
using Ogre::uint16;
using Ogre::ushort;
using Ogre::uint32;
using Ogre::uint;
using Ogre::Real;
using Ogre::String;
/// Resource group name for caelum resources.
static const String RESOURCE_GROUP_NAME = "Caelum";
// Render group for caelum stuff
// It's best to have them all together
enum CaelumRenderQueueGroupId
{
CAELUM_RENDER_QUEUE_STARFIELD = Ogre::RENDER_QUEUE_SKIES_EARLY + 0,
CAELUM_RENDER_QUEUE_MOON_BACKGROUND = Ogre::RENDER_QUEUE_SKIES_EARLY + 1,
CAELUM_RENDER_QUEUE_SKYDOME = Ogre::RENDER_QUEUE_SKIES_EARLY + 2,
CAELUM_RENDER_QUEUE_MOON = Ogre::RENDER_QUEUE_SKIES_EARLY + 3,
CAELUM_RENDER_QUEUE_SUN = Ogre::RENDER_QUEUE_SKIES_EARLY + 4,
CAELUM_RENDER_QUEUE_CLOUDS = Ogre::RENDER_QUEUE_SKIES_EARLY + 5,
CAELUM_RENDER_QUEUE_GROUND_FOG = Ogre::RENDER_QUEUE_SKIES_EARLY + 6,
};
// Forward declarations
class UniversalClock;
class SkyDome;
class BaseSkyLight;
class Moon;
class SphereSun;
class SpriteSun;
class ImageStarfield;
class PointStarfield;
class CloudSystem;
class CaelumSystem;
class FlatCloudLayer;
class PrecipitationController;
class PrecipitationInstance;
class GroundFog;
class DepthComposer;
class DepthComposerInstance;
class DepthRenderer;
}
namespace Ogre
{
#if OGRE_VERSION <= 0x010602
// Write an Ogre::Degree to a stream.
//
// Ogre::Any requires that the wrapped type can be written to a stream;
// otherwise it will fail on instantation. This function was placed here
// so it's available everywhere. This can't be placed in namespace Caelum.
//
// Ogre 1.6.3 and up already include this operator; so it's ifdefed out.
//
// This function is never actually used; the output does not matter.
inline std::ostream& operator << (std::ostream& out, Ogre::Degree deg) {
return out << deg.valueDegrees();
}
#endif
}
#endif // CAELUM__CAELUM_PREREQUISITES_H

@ -0,0 +1,216 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__CAELUM_SCRIPT_TRANSLATOR_H
#define CAELUM__CAELUM_SCRIPT_TRANSLATOR_H
#if CAELUM_SCRIPT_SUPPORT
#include "CaelumPrerequisites.h"
#include "OgreScriptTranslator.h"
#include "TypeDescriptor.h"
namespace Caelum
{
/** Dummy resources created for property script blocks.
*
* When parsing material scripts the singleton rendersystem is available
* and materials are created using it. But Caelum's scriptable components
* require at least an active scene scene manager; and you can't require
* something like that when initializing resources.
*
* So instead a dummy resource like this is created which only remembers
* the location of the script block in the resources. Actually loading the
* properties will always reparse the script.
*
* The original file name is available from Ogre::Resource::getOrigin
*
* These resources are managed by the PropScriptResourceManager. Resource
* operations like loading and unloading are meaningless.
*/
class CAELUM_EXPORT PropScriptResource: public Ogre::Resource {
protected:
virtual void loadImpl () { }
virtual void unloadImpl () { }
virtual size_t calculateSize () const { return 0; }
public:
PropScriptResource (
Ogre::ResourceManager* creator, const Ogre::String& name, Ogre::ResourceHandle handle,
const Ogre::String& group, bool isManual, Ogre::ManualResourceLoader* loader);
~PropScriptResource();
};
/** Resource manager for PropScriptResource.
*/
class CAELUM_EXPORT PropScriptResourceManager: public Ogre::ResourceManager
{
public:
PropScriptResourceManager();
virtual PropScriptResource* createImpl(
const String& name, Ogre::ResourceHandle handle, const String& group,
bool isManual, Ogre::ManualResourceLoader* loader, const Ogre::NameValuePairList* createParams);
};
/** An Ogre::ScriptTranslator based on a TypeDescriptor.
* This class implements an Ogre::ScriptTranslator based on data from a TypeDescriptor.
*
* The target object is never created; it must be passed in the context member of the
* root node. Some other ScriptTranslator must cooperate and set the context member;
* this is similar to how Ogre::PassTranslator depends on Ogre::MaterialTranslator
* setting the context.
*
* Ogre::AbstractNode::context is an Ogre::Any which boxes objects in a way which
* stores the static (compile-time) type at assignment. You must cast the
* object into a void* before setting it as the context.
*
* Most of the actual translation functionality is in static functions; a class can
* translate based on TypeDescriptor data without deriving from this class.
*/
class CAELUM_EXPORT TypeDescriptorScriptTranslator: public Ogre::ScriptTranslator
{
public:
/** Get the value of a property or report the appropriate error.
* @return Success value.
*/
static bool getPropValueOrAddError (Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, int& value);
static bool getPropValueOrAddError (Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, float& value);
static bool getPropValueOrAddError (Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, double& value);
static bool getPropValueOrAddError (Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, bool& value);
static bool getPropValueOrAddError (Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, Ogre::Degree& value);
static bool getPropValueOrAddError (Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, Ogre::ColourValue& value);
static bool getPropValueOrAddError (Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, Ogre::String& value);
static bool getPropValueOrAddError (Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, Ogre::Vector3& value);
static bool getPropValueOrAddError (Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, Ogre::Vector2& value);
/** Translate a property using a TypeDescriptor; or report error to compiler.
*/
static void translateProperty (
Ogre::ScriptCompiler* compiler,
Ogre::PropertyAbstractNode* prop,
void* targetObject,
const TypeDescriptor* typeDescriptor);
public:
explicit TypeDescriptorScriptTranslator (TypeDescriptor* type = 0);
virtual void translate (Ogre::ScriptCompiler* compiler, const Ogre::AbstractNodePtr& node);
inline const TypeDescriptor* getTypeDescriptor () const { return mTypeDescriptor; }
inline TypeDescriptor* getTypeDescriptor () { return mTypeDescriptor; }
private:
TypeDescriptor* mTypeDescriptor;
};
/** Script translator for CaelumSystem
*/
struct CAELUM_EXPORT CaelumSystemScriptTranslator: public Ogre::ScriptTranslator
{
public:
CaelumSystemScriptTranslator();
virtual void translate (Ogre::ScriptCompiler* compiler, const Ogre::AbstractNodePtr& node);
void setTranslationTarget (CaelumSystem* target, const Ogre::String& name);
void clearTranslationTarget ();
inline bool hasTranslationTarget () const { return mTranslationTarget != 0; }
inline bool foundTranslationTarget () const { return mTranslationTargetFound; }
inline CaelumSystem* getTranslationTarget () const { return mTranslationTarget; }
inline const Ogre::String& getTranslationTargetName () const { return mTranslationTargetName; }
inline void setResourceManager (PropScriptResourceManager* value) { mResourceManager = value; }
inline PropScriptResourceManager* getResourceManager () const { return mResourceManager; }
private:
PropScriptResourceManager* mResourceManager;
CaelumSystem* mTranslationTarget;
Ogre::String mTranslationTargetName;
bool mTranslationTargetFound;
public:
/** Type descriptor for CaelumSystem itself.
* This is use for simple top-level properties.
* Components (sun, moon etc) are handled with custom code.
*/
inline const TypeDescriptor* getTypeDescriptor () const { return mTypeDescriptor; }
inline void setTypeDescriptor (const TypeDescriptor* value) { mTypeDescriptor = value; }
private:
const TypeDescriptor* mTypeDescriptor;
};
/** Script translator for CloudSystem
* Caelum::CloudSystem requires a special translator because it's made up of separate layers.
*
* Layers of different types are not supported; only instances of FlatCloudLayer.
* CloudSystem doesn't have any top-level properties.
*
* Overriding works just like for ogre texture units; and you can use name-based overriding.
* Names are not preserved after script translation; they're only used inside Ogre's script
* compilation steps.
*/
struct CAELUM_EXPORT CloudSystemScriptTranslator: public Ogre::ScriptTranslator
{
public:
virtual void translate (Ogre::ScriptCompiler* compiler, const Ogre::AbstractNodePtr& node);
};
/** ScriptTranslatorManager for caelum's scriptable objects.
* This class contains Ogre::ScriptTranslators for Caelum components.
*/
class CAELUM_EXPORT CaelumScriptTranslatorManager: public Ogre::ScriptTranslatorManager
{
public:
explicit CaelumScriptTranslatorManager (CaelumDefaultTypeDescriptorData* typeData);
virtual size_t getNumTranslators () const;
/// @copydoc Ogre::ScriptTranslatorManager::getTranslator.
virtual Ogre::ScriptTranslator* getTranslator (const Ogre::AbstractNodePtr& node);
void _setPropScriptResourceManager (PropScriptResourceManager* mgr);
inline CaelumSystemScriptTranslator* getCaelumSystemTranslator () { return &mCaelumSystemTranslator; }
private:
CaelumSystemScriptTranslator mCaelumSystemTranslator;
CloudSystemScriptTranslator mCloudSystemTranslator;
TypeDescriptorScriptTranslator mFlatCloudLayerTranslator;
TypeDescriptorScriptTranslator mSunTranslator;
TypeDescriptorScriptTranslator mMoonTranslator;
TypeDescriptorScriptTranslator mPointStarfieldTranslator;
TypeDescriptorScriptTranslator mGroundFogTranslator;
TypeDescriptorScriptTranslator mDepthComposerTranslator;
TypeDescriptorScriptTranslator mPrecipitationTranslator;
TypeDescriptorScriptTranslator mSkyDomeTranslator;
/// Maps class name to script translator.
/// Does not own memory; just holds pointers to members.
typedef std::map<Ogre::String, Ogre::ScriptTranslator*> ScriptTranslatorMap;
ScriptTranslatorMap mTranslatorMap;
};
}
#endif // CAELUM_SCRIPT_SUPPORT
#endif // CAELUM__CAELUM_SCRIPT_TRANSLATOR_H

@ -0,0 +1,672 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__CAELUM_SYSTEM_H
#define CAELUM__CAELUM_SYSTEM_H
#include "CaelumPrerequisites.h"
#include "UniversalClock.h"
#include "ImageStarfield.h"
#include "PointStarfield.h"
#include "SkyLight.h"
#include "Sun.h"
#include "Moon.h"
#include "CloudSystem.h"
#include "SkyDome.h"
#include "DepthComposer.h"
#include "PrecipitationController.h"
#include "GroundFog.h"
#include "PrivatePtr.h"
namespace Caelum
{
/** This is the "root class" of caelum.
*
* This class is created once for one SceneManager and will render the sky
* for that scene. CaelumSystem will be visible in all viewports on the
* scene and must be notified when those viewports are created and
* destroyed.
*
* @par Components
*
* %Caelum is built from several classes for different sky elements (the sun,
* clouds, etc). Those classes know very little about each other and are
* connected through this class. This class is responsible for tracking and
* updating sub-components.
*
* This class "owns" all of the subcomponents, using std::auto_ptr members.
* When you call functions like setXxx(new Xxx()) this class takes
* ownership of the object's lifetime and will try to update it as
* appropriate. All components are optional; disable one component should
* never cause a crash. When something is broken disabling components one
* by one is a very good way to find the source of the problem.
*
* The constructor can create a bunch of components with default settings
* for you; based on the CaelumSystem::CaelumComponent flags passed.
*
* @par Updating
*
* This class is responsible for updating subcomponents. There are two
* update functions which must be get called to keep CaelumSystem
* functioning properly. One is per-frame and the other is per-camera.
*
* CaelumSystem::updateSubcomponents must be called once per frame to
* advance world time and tie components together. That function will
* set certain properties on the subcomponents making up CaelumSystem
* If you want to force some properties beyond what CaelumSystem does by
* default you can do that AFTER the call to updateSubcompoments. For
* example you can override the moon's phase by calling Moon::setPhase.
*
* CaelumSystem::notifyCameraChanged must be called for each camera
* before rendering with that camera. All viewport tweaks and camera
* movement must be done BEFORE calling this function. This method will
* recenter Caelum's domes on the camera. Also, some subcomponents
* can actually depend on field-of-view and viewport resolution (like
* PointStarfield).
*
* You can register CaelumSystem as an Ogre::FrameListener and
* updateSubcomponents will be automatically called inside Ogre's
* rendering loop (inside frameStarted). If you want more control you
* should call updateSubcomponents in your own main loop. That way you
* can avoid potential issues with the ordering of multiple FrameListeners.
*
* You can register CaelumSystem as an Ogre::RenderTargetListener and
* notifyCameraChanged will be automatically called inside
* preViewportUpdate. That behaviour can be disabled with
* setAutoNotifyCameraChanged(false). It is recommended that you
* call notifyCameraChanged manually before updating viewports.
*
* RenderTargetListener::preViewportUpdate does not work as expected
* when compositors are involved (those inside Caelum or external).
* Compositors plug into preRenderTargetUpdate and render the scene to a
* texture BEFORE preViewportUpdate; this means that notifyCameraChanged
* will execute before the final compositor pass but after actual scene
* rendering.
*
* If notifyCameraChanged is not called correctly the most likely result
* is "flickering" when moving the camera. If you move the camera AFTER
* notifyCameraChanged then the domes will not be positioned correctly
* and will appear to lag slightly after the camera. Since updates are
* always done every frame keeping the camera still will make problems
* disappear.
*
* If you notice z-buffer issues while the camera is still update order
* is probably not the cause.
*/
class CAELUM_EXPORT CaelumSystem:
public Ogre::FrameListener,
public Ogre::RenderTargetListener
{
private:
/// Root of the Ogre engine.
Ogre::Root *mOgreRoot;
/// Scene manager.
Ogre::SceneManager *mSceneMgr;
/// Caelum scene node for camera-bound elements (most).
PrivateSceneNodePtr mCaelumCameraNode;
/// Caelum scene node for ground-bound elements (only clouds currently).
PrivateSceneNodePtr mCaelumGroundNode;
/// Cleanup requested flag.
bool mCleanup;
/// Automatically move the camera node.
bool mAutoMoveCameraNode;
/// Automatically call this->notifyCameraChanged.
bool mAutoNotifyCameraChanged;
/// Automatically attach compositors to viewports
bool mAutoAttachViewportsToComponents;
/// Automatically set the viewport colour to black.
bool mAutoViewportBackground;
/// Flag to indicate if Caelum manages standard Ogre::Scene fog.
bool mManageSceneFog;
Real mGlobalFogDensityMultiplier;
Ogre::ColourValue mGlobalFogColourMultiplier;
Real mSceneFogDensityMultiplier;
Ogre::ColourValue mSceneFogColourMultiplier;
Real mGroundFogDensityMultiplier;
Ogre::ColourValue mGroundFogColourMultiplier;
/// Flag for managing scene ambient light.
bool mManageAmbientLight;
/// Minimum ambient light; only useful if mManageAmbientLight
Ogre::ColourValue mMinimumAmbientLight;
/// If only one light source should enabled at a time.
bool mEnsureSingleLightSource;
/// Ensure only one of the light sources casts shadows.
bool mEnsureSingleShadowSource;
/// The sky gradients image (for lookups).
std::auto_ptr<Ogre::Image> mSkyGradientsImage;
/// The sun gradients image (for lookups).
std::auto_ptr<Ogre::Image> mSunColoursImage;
/// Observer Latitude (on the earth).
Ogre::Degree mObserverLatitude;
/// Observer Longitude (on the earth).
Ogre::Degree mObserverLongitude;
static const Ogre::Vector3 makeDirection (
Ogre::Degree azimuth, Ogre::Degree altitude);
// References to sub-components
std::auto_ptr<UniversalClock> mUniversalClock;
std::auto_ptr<SkyDome> mSkyDome;
std::auto_ptr<BaseSkyLight> mSun;
std::auto_ptr<Moon> mMoon;
std::auto_ptr<ImageStarfield> mImageStarfield;
std::auto_ptr<PointStarfield> mPointStarfield;
std::auto_ptr<GroundFog> mGroundFog;
std::auto_ptr<CloudSystem> mCloudSystem;
std::auto_ptr<PrecipitationController> mPrecipitationController;
std::auto_ptr<DepthComposer> mDepthComposer;
public:
typedef std::set<Ogre::Viewport*> AttachedViewportSet;
private:
AttachedViewportSet mAttachedViewports;
public:
/** Flags enumeration for caelum components.
* This is an enumeration for the components to create by default in
* Caelum's constructor. You can still pass 0 and create everything
* by hand.
*
* CaelumSystem's constructor used to take a number of bools but now
* there are too many components and this is nicer.
*
* CAELUM_COMPONENT_ members are for individual components.
* CAELUM_COMPONENTS_ are standard bitmasks.
* CAELUM_COMPONENTS_DEFAULT picks elements that don't require
* modifications to external materials (right now it excludes ground fog).
*/
enum CaelumComponent
{
CAELUM_COMPONENT_SKY_DOME = 1 << 1,
CAELUM_COMPONENT_MOON = 1 << 3,
CAELUM_COMPONENT_SUN = 1 << 4,
CAELUM_COMPONENT_IMAGE_STARFIELD = 1 << 5,
CAELUM_COMPONENT_POINT_STARFIELD = 1 << 6,
CAELUM_COMPONENT_CLOUDS = 1 << 7,
CAELUM_COMPONENT_PRECIPITATION = 1 << 8,
CAELUM_COMPONENT_SCREEN_SPACE_FOG = 1 << 9,
// This has nasty dependencies on materials.
CAELUM_COMPONENT_GROUND_FOG = 1 << (16 + 0),
// Groups
CAELUM_COMPONENTS_NONE = 0,
CAELUM_COMPONENTS_DEFAULT = 0
| CAELUM_COMPONENT_SKY_DOME
| CAELUM_COMPONENT_MOON
| CAELUM_COMPONENT_SUN
| CAELUM_COMPONENT_POINT_STARFIELD
| CAELUM_COMPONENT_CLOUDS,
CAELUM_COMPONENTS_ALL = 0
| CAELUM_COMPONENTS_DEFAULT
| CAELUM_COMPONENT_PRECIPITATION
| CAELUM_COMPONENT_SCREEN_SPACE_FOG
| CAELUM_COMPONENT_GROUND_FOG,
};
static const String DEFAULT_SKY_GRADIENTS_IMAGE;
static const String DEFAULT_SUN_COLOURS_IMAGE;
/** Constructor.
* Registers itself in the Ogre engine and initialises the system.
*
* @param root The Ogre root.
* @param scene The Ogre scene manager.
* @param componentsToCreate Default components for @see autoConfigure.
*/
CaelumSystem (
Ogre::Root *root,
Ogre::SceneManager *sceneMgr,
CaelumComponent componentsToCreate);
/** Revert everything to defaults.
*
* This function will delete all subcomponents and revert everything
* to default values (the values which are also set on construction).
*/
void clear ();
/** Create some default component with resonable default settings.
* This results in a slightly cloudy morning sky.
* This will always call clear() before creating components.
* autoConfigure (0); is equivalent to clear();
*/
void autoConfigure (
CaelumComponent componentsToCreate);
/** Destructor.
*/
~CaelumSystem ();
/** Shuts down the system and detaches itself from the Ogre engine.
*
* shutdown(true) is equivalent to deleting CaelumSystem yourself.
* shutdown(false) delays destruction to the next time caelum is called as
* a frame listener. This makes it safe to shutdown Caelum from inside
* another frame listener.
*
* @param cleanup If this is true then detach and destroy the CaelumSystem instantly.
*/
void shutdown (bool cleanup);
/** Update the whole system manually.
* You have to call this yourself if you don't register CaelumSystem
* as an ogre frame listener. Otherwise it's called automatically.
*
* @param timeSinceLastFrame: Time passed since last frame.
*/
void updateSubcomponents (Real timeSinceLastFrame);
/** Notify subcomponents of camera changes.
* This function must be called after camera changes but before
* rendering with that camera. If multiple cameras are used it must
* be called for each camera before the camera is rendered with.
*
* This function will move caelum's camera node to the camera
* position, but only if getAutoMoveCameraNode.
* It will also call CameraBoundElement::notifyCameraChanged
*/
void notifyCameraChanged(Ogre::Camera* cam);
/** Get the scene manager for this caelum system.
* This is set in the constructor. CaelumSystem can't exist without a valid scene manager.
*/
inline Ogre::SceneManager* getSceneMgr() const { return mSceneMgr; }
/// Gets root scene node for camera-bound elements
inline Ogre::SceneNode* getCaelumCameraNode(void) const { return mCaelumCameraNode.get(); }
/// Gets root scene node for ground-bound elements.
inline Ogre::SceneNode* getCaelumGroundNode(void) const { return mCaelumGroundNode.get(); }
/** If true; listen to preViewportUpdate and automatically notifyCameraChanged();
*
* This is on by default; but does not work with compositors.
*
* You must attach CaelumSystem as a RenderTargetListener manually for
* this to work; as in version 0.3.
*/
inline void setAutoNotifyCameraChanged(bool value) { mAutoNotifyCameraChanged = value; }
/// @see setAutoNotifyCameraChanged
inline bool getAutoNotifyCameraChanged() const { return mAutoNotifyCameraChanged; }
/** If true; automatically attach viewports to subcomponents.
*
* Some subcomponents use compositors and those compositors need to
* be attached to individual viewports. By default CaelumSystem will
* try take to take care of that automatically.
*
* This property allows you to disable that behaviour. If set to false
* you must call functions like
* PrecipitationController::createViewportInstance manually.
*
* @see attachViewport detachViewport
*/
inline void setAutoAttachViewportsToComponents(bool value) { mAutoAttachViewportsToComponents = value; }
/// @see setAutoAttachViewportsToComponents.
inline bool getAutoAttachViewportsToComponents() const { return mAutoAttachViewportsToComponents; }
/** If true (default); automatically move the camera node in notifyCameraChanged.
* If disable you get full control of the camera node; and in theory
* you can attach it to the scene graph however you please.
*/
inline void setAutoMoveCameraNode(bool value) { mAutoMoveCameraNode = value; }
/// @see setAutoMoveCameraNode
inline bool getAutoMoveCameraNode() { return mAutoMoveCameraNode; }
/** If true; automatically set the viewport color to black.
* Caelum's domes relies on the viewport background being black.
* There's generally no reason to disable this and it's on by default.
*/
inline void setAutoViewportBackground(bool value) { mAutoViewportBackground = value; }
/// @see setAutoViewportBackground
inline bool getAutoViewportBackground() const { return mAutoViewportBackground; }
/// Get the observer's longitude. East is positive, west is negative.
inline const Ogre::Degree getObserverLongitude () const { return mObserverLongitude; }
/// Set the observer's longitude. East is positive, west is negative.
inline void setObserverLongitude (Ogre::Degree value) { mObserverLongitude = value; }
/// Get the observer's latitude. North is positive, south is negative.
inline const Ogre::Degree getObserverLatitude () const { return mObserverLatitude; }
/// Set the observer's latitude. North is positive, south is negative.
inline void setObserverLatitude (Ogre::Degree value) { mObserverLatitude = value; }
inline LongReal getJulianDay () const { return mUniversalClock->getJulianDay (); }
inline void setJulianDay (LongReal value) { mUniversalClock->setJulianDay (value); }
inline Real getTimeScale () const { return mUniversalClock->getTimeScale (); }
inline void setTimeScale (Real value) { mUniversalClock->setTimeScale (value); }
public:
/** Attach CaelumSystem to a viewport.
* You should call this for every new viewport looking at the scene
* where CaelumSystem is created.
*
* If the viewport is already attached then nothing happens.
*
* If getAutoAttachViewportsToComponents() this will add Caelum's compositors.
*/
void attachViewport (Ogre::Viewport* rt);
/** Reverse of @see attachViewport.
* You need to call this when you destroy a viewport.
*
* If the viewport is not already attached nothing happens.
*/
void detachViewport (Ogre::Viewport* rt);
/** Check if one particular viewport is attached.
*/
bool isViewportAttached (Ogre::Viewport* vp) const;
/** Detach from all viewports.
*/
void detachAllViewports ();
/// Get a reference to the set of attached viewports.
const AttachedViewportSet& _getAttachedViewportSet () { return mAttachedViewports; }
protected:
// Do the work behind attach/detach viewport.
void attachViewportImpl (Ogre::Viewport* rt);
void detachViewportImpl (Ogre::Viewport* rt);
public:
/// Gets the universal clock.
inline UniversalClock *getUniversalClock () const { return mUniversalClock.get(); }
/// Get the current sky dome, or null if disabled.
inline SkyDome* getSkyDome () const { return mSkyDome.get (); }
/// Set the skydome, or null to disable.
void setSkyDome (SkyDome *obj);
/// Gets the current sun, or null if disabled.
inline BaseSkyLight* getSun () const { return mSun.get (); }
/// Set the sun, or null to disable.
void setSun (BaseSkyLight* obj);
/// Gets the current moon, or null if disabled.
inline Moon* getMoon () const { return mMoon.get (); }
/// Set the moon, or null to disable.
void setMoon (Moon* obj);
/// Gets the current image starfield, or null if disabled.
inline ImageStarfield* getImageStarfield () const { return mImageStarfield.get (); }
/// Set image starfield, or null to disable.
void setImageStarfield (ImageStarfield* obj);
/// Gets the current point starfield, or null if disabled.
inline PointStarfield* getPointStarfield () const { return mPointStarfield.get (); }
/// Set image starfield, or null to disable.
void setPointStarfield (PointStarfield* obj);
/// Get ground fog; if enabled.
inline GroundFog* getGroundFog () { return mGroundFog.get (); }
/// Sets ground fog system, or null to disable.
void setGroundFog (GroundFog *obj);
/// Get cloud system; or null if disabled.
inline CloudSystem* getCloudSystem () { return mCloudSystem.get (); }
/// Set cloud system; or null to disable.
void setCloudSystem (CloudSystem *obj);
/// Get precipitation controller; or null if disabled.
inline PrecipitationController* getPrecipitationController () { return mPrecipitationController.get (); }
/// Set precipitation controller; or null to disable.
void setPrecipitationController (PrecipitationController *obj);
/// Get depth composer; or null if disabled.
inline DepthComposer* getDepthComposer () { return mDepthComposer.get (); }
/// Set depth composer; or null to disable.
void setDepthComposer (DepthComposer *obj);
/** Enables/disables Caelum managing standard Ogre::Scene fog.
This makes CaelumSystem control standard Ogre::Scene fogging. It
will use EXP2 fog with density from SkyColourModel.
Fog density multipliers are used; final scene fog density is:
SceneMultiplier * GlobalMultiplier * SkyColourModel.GetFogDensity
When this is set to false it also disables all scene fog (but you
control it afterwards).
@param value New value
*/
void setManageSceneFog (bool value);
/** Tells if Caelum is managing the fog or not.
@return The value set in setManageSceneFog.
*/
bool getManageSceneFog () const;
/** Multiplier for scene fog density (default 1).
This is an additional multiplier for Ogre::Scene fog density.
This has no effect if getManageSceneFog is false.
Final scene fog density is:
SceneMultiplier * GlobalMultiplier * SkyColourModel.GetFogDensity
*/
void setSceneFogDensityMultiplier (Real value);
/** Get the value set by setSceneFogDensityMultiplier.
*/
Real getSceneFogDensityMultiplier () const;
/** Set an additional multiplier for fog colour as it comes from SkyColourModel.
* This is 0.7 by default; to be compatible with previous versions.
*/
inline void setSceneFogColourMultiplier (const Ogre::ColourValue& value) { mSceneFogColourMultiplier = value; }
/// See setSceneFogColourMultiplier.
inline const Ogre::ColourValue getSceneFogColourMultiplier () const { return mSceneFogColourMultiplier; }
/** Multiplier for ground fog density (default 1).
* This is an additional multiplier for Caelum::GroundFog DepthComposer ground fog density.
*
* Final ground fog density is:
* GroundFogMultipler * GlobalMultiplier * SkyColourModel.GetFogDensity
*/
void setGroundFogDensityMultiplier (Real value);
/** Get the value set by setGroundFogDensityMultiplier.
*/
Real getGroundFogDensityMultiplier () const;
/** Set an additional multiplier for ground fog colour as it comes from SkyColourModel.
* This is OgreColour::White by default; which has no effect.
*/
inline void setGroundFogColourMultiplier (const Ogre::ColourValue& value) { mGroundFogColourMultiplier = value; }
/// See setGroundFogColourMultiplier.
inline const Ogre::ColourValue getGroundFogColourMultiplier () const { return mGroundFogColourMultiplier; }
/** Multiplier for global fog density (default 1).
* This is an additional multiplier for fog density as received from
* SkyColourModel. There are other multipliers you can tweak for
* individual kinds of fog; but this is what you should change from
* whatever "game logic" you might have.
*/
void setGlobalFogDensityMultiplier (Real value);
/** Get the value set by setSceneFogDensityMultiplier.
*/
Real getGlobalFogDensityMultiplier () const;
/** Set an additional multiplier for fog colour.
* This will also affect stuff like clouds or precipitation. Careful!
* This is OgreColour::White by default; which has no effect.
*/
inline void setGlobalFogColourMultiplier (const Ogre::ColourValue& value) { mGlobalFogColourMultiplier = value; }
/// See setGlobalFogColourMultiplier.
inline const Ogre::ColourValue getGlobalFogColourMultiplier () const { return mGlobalFogColourMultiplier; }
/** Set this to true to have CaelumSystem manage the scene's ambient light.
* The colour and AmbientMultiplier of the sun and moon are used.
* This is false by default.
*/
inline void setManageAmbientLight (bool value) { mManageAmbientLight = value; }
/// Check if CaelumSystem is managing ambient lighting.
inline bool getManageAmbientLight () const { return mManageAmbientLight; }
/** Set the minimum value for scene ambient lighting,
* This is only used if getManageAmbientLight() is true.
* By default this value is Ogre::ColourValue::Black, so it has no effect.
*/
inline void setMinimumAmbientLight (const Ogre::ColourValue &value) { mMinimumAmbientLight = value; }
/// @see setMinimumAmbientLight
inline const Ogre::ColourValue getMinimumAmbientLight () const { return mMinimumAmbientLight; }
/** Ensure only one of caelum's light sources is active at a time (the brightest).
* This uses SkyLight::setForceDisable to disable low-intensity lightsources.
* Their contribution to ambient lighting is not affected.
* This implies a single shadow caster.
* This is disabled by default; and you can tweak light disabling by yourself.
*/
inline void setEnsureSingleLightSource (bool value) { mEnsureSingleLightSource = value; }
/// See setEnsureSingleLightSource
inline bool getEnsureSingleLightSource () const { return mEnsureSingleLightSource; }
/** Ensure only one of caelum's light sources casts shadows (the brightest).
* Disabled by default.
*/
inline void setEnsureSingleShadowSource (bool value) { mEnsureSingleShadowSource = value; }
/// See setEnsureSingleShadowSource
inline bool getEnsureSingleShadowSource () const { return mEnsureSingleShadowSource; }
/** Gets the fog colour for a certain daytime.
@param time The current time.
@param sunDir The sun direction.
@return The fog colour.
*/
Ogre::ColourValue getFogColour (Real time, const Ogre::Vector3 &sunDir);
/** Gets the fog density for a certain daytime.
@param time The current time.
@param sunDir The sun direction.
@return The fog density.
*/
Real getFogDensity (Real time, const Ogre::Vector3 &sunDir);
/** Get the colour of the sun sphere.
* This colour is used to draw the sun sphere in the sky.
* @return The colour of the sun.
*/
Ogre::ColourValue getSunSphereColour (Real time, const Ogre::Vector3 &sunDir);
/** Gets the colour of sun light.
* This color is used to illuminate the scene.
* @return The colour of the sun's light
*/
Ogre::ColourValue getSunLightColour (Real time, const Ogre::Vector3 &sunDir);
/// Gets the colour of moon's body.
Ogre::ColourValue getMoonBodyColour (const Ogre::Vector3 &moonDir);
/// Gets the colour of moon's light.
Ogre::ColourValue getMoonLightColour (const Ogre::Vector3 &moonDir);
/// Set the sun gradients image.
void setSkyGradientsImage (const Ogre::String &filename = DEFAULT_SKY_GRADIENTS_IMAGE);
/// Set the sun colours image.
/// Sun colour is taken from this image.
void setSunColoursImage (const Ogre::String &filename = DEFAULT_SUN_COLOURS_IMAGE);
/** Get the sun's direction at a certain time.
* @param jday astronomical julian day.
* @see UniversalClock for julian day calculations.
*/
const Ogre::Vector3 getSunDirection (LongReal jday);
/** Get the moon's direction at a certain time.
* @param jday astronomical julian day.
*/
const Ogre::Vector3 getMoonDirection (LongReal jday);
/** Fake function to get the phase of the moon
* @param jday Julian day
* @return the phase of the moon; ranging from 0(full moon) to 2(new moon).
* The calculations performed by this function are completely fake.
* It's a triangle wave with a period of 28.5 days.
*/
const Ogre::Real getMoonPhase (LongReal jday);
private:
/** Handle FrameListener::frameStarted to call updateSubcomponents every frame.
* If you don't register CaelumSystem as a an ogre frame listener you have to
* call updateSubcomponents yourself.
*/
virtual bool frameStarted (const Ogre::FrameEvent &e);
/** Event trigger called just before rendering a viewport in a render target Caelum is attached to.
Useful to make objects follow every camera that renders a viewport in a certain render target.
*/
virtual void preViewportUpdate (const Ogre::RenderTargetViewportEvent &e);
/** Free all subcomponents, but not CaelumSystem itself. Can be called multiple times.
* @param everything To destroy things that can't be rebuilt.
*/
void destroySubcomponents (bool everything);
public:
/** Call setQueryFlags for all subcomponents now.
*
* This is not persistent; you can adjust the query masks of
* individual objects afterwards. This also means you should call
* this only after you created all other objects.
*
* Has no effect on compositor-based stuff (precipitation will still show up).
*/
void forceSubcomponentQueryFlags (uint mask);
/** Same as @see forceSubcomponentQueryMask; but for visibility
*/
void forceSubcomponentVisibilityFlags (uint mask);
};
}
#endif // CAELUM__CAELUM_SYSTEM_H

@ -0,0 +1,112 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__CAMERA_BOUND_ELEMENT_H
#define CAELUM__CAMERA_BOUND_ELEMENT_H
#include "CaelumPrerequisites.h"
namespace Caelum
{
/** A camera-bound element.
*
* This should be used as a base class for domes which follow the camera.
* It is only meant to be used inside Caelum.
*
* By default this class work in autoradius mode; where it automatically
* resizes itself for camera near/far clipping radius. It will correctly
* handle infinite far clip planes.
*
* This is meant to be used with depth_check and depth_write off.
* Trying to place an object "as far as possible" causes precision
* troubles; and was removed in version 0.4.
*
* If far clip distance is finite the radius will be (near + far) / 2.
* If far clip distance is infinite (0) the radius will be 10 * near/
*/
class CAELUM_EXPORT CameraBoundElement
{
private:
/// Defines if the element has an automatic "far" radius or not.
bool mAutoRadius;
public:
/** Constructor. Sets auto radius to true.
*/
CameraBoundElement();
/// Virtual Destructor.
virtual ~CameraBoundElement ();
/** Notify new camera conditions.
* This method notifies that a new camera is about to be used, so
* this element can follow it or perform other operations.
* The default implementation calls setRadius if in autoRadius mode.
* @param cam The new camera.
*/
virtual void notifyCameraChanged (Ogre::Camera *cam) = 0;
/** Forces the "far" size of the element to a specific radius.
*
* If greater than zero this disables AutoRadius mode and forces a
* fixed radius. If this is negative or zero the radius is set
* automatically in notifyCameraChanged.
*
* AutoRadius is turned on by default.
*
* @param radius The positive radius of the element, or a
* negative/zero value for AutoRadius mode.
*/
void forceFarRadius (Ogre::Real radius);
/** Checks if this element is in auto-radius mode.
* While in autoradius mode the element is automatically resized fit
* between the near and far radius.
*/
bool getAutoRadius () const;
/** Re-enable auto-radius; if disabled.
* Auto-radius is on by default; but can be disabled. This function
* can turn it back on.
*/
void setAutoRadius ();
/** Camera distances multiplier for the far clipping distance.
* This threshold will be multiplied with the far clipping distance,
* if the camera doesn't use an infinite far clipping plane.
*/
static const Ogre::Real CAMERA_FAR_DISTANCE_MULTIPLIER;
/** Camera distances multiplier for the near clipping distance.
* This threshold will be multiplied with the near clipping distance,
* if the camera does use an infinite far clipping plane.
*/
static const Ogre::Real CAMERA_NEAR_DISTANCE_MULTIPLIER;
protected:
/** Abstract method to set the radius for this elements
* Derived classes should override this and resize their domes.
* The actual radius for the dome is controlled in the base class.
*/
virtual void setFarRadius (Ogre::Real radius);
};
}
#endif // CAELUM__CAMERA_BOUND_ELEMENT_H

@ -0,0 +1,89 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__CLOUD_SYSTEM_H
#define CAELUM__CLOUD_SYSTEM_H
#include "CaelumPrerequisites.h"
namespace Caelum
{
/** A cloud system is implemented by a number of cloud layers.
* Different cloud layers could implement different kinds of clouds (cirrus, stratus).
*/
class CAELUM_EXPORT CloudSystem
{
public:
CloudSystem (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *cloudRoot);
~CloudSystem();
typedef std::vector<FlatCloudLayer*> LayerVector;
private:
Ogre::SceneManager *mSceneMgr;
Ogre::SceneNode *mCloudRoot;
LayerVector mLayers;
public:
/** Direct access to the layer vector.
*/
LayerVector& getLayerVector() { return mLayers; }
/// Clears all cloud layers.
void clearLayers();
/// Create a new cloud layer with default settings at height 0.
/// @return pointer to the new layer.
FlatCloudLayer* createLayer();
/// Create a new cloud layer with default settings at a certain height.
/// @return pointer to the new layer.
FlatCloudLayer* createLayerAtHeight(Ogre::Real height);
/// Add new layer. Takes ownership of the layer.
void addLayer(FlatCloudLayer* layer);
/// Get a pointer to a certain layer.
inline FlatCloudLayer* getLayer(int index) { return mLayers[index]; }
/// Get the total number of layers.
inline int getLayerCount() { return static_cast<int> (mLayers.size ()); }
/** Update function called every frame from high above.
*/
void update (
Ogre::Real timePassed,
const Ogre::Vector3 &sunDirection,
const Ogre::ColourValue &sunLightColour,
const Ogre::ColourValue &fogColour,
const Ogre::ColourValue &sunSphereColour);
/// Similar to @see CaelumSystem::forceSubcomponentQueryFlags.
virtual void forceLayerQueryFlags (uint flags);
/// Similar to @see CaelumSystem::forceSubcomponentVisibilityFlags.
virtual void forceLayerVisibilityFlags (uint flags);
};
}
#endif // CAELUM__CLOUD_SYSTEM_H

@ -0,0 +1,280 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__DEPTH_COMPOSER_H
#define CAELUM__DEPTH_COMPOSER_H
#include "CaelumPrerequisites.h"
#include "FastGpuParamRef.h"
namespace Caelum
{
/** Compositor-based precipitation controller.
* This class will add and control precipitation controllers to viewports.
*
* Compositors clone the composing materials. This controller will
* register itself as a compositor listener and change the material in notifyMaterialSetup.
*/
class CAELUM_EXPORT DepthComposer
{
private:
Ogre::SceneManager *mSceneMgr;
void onCompositorMaterialChanged ();
const String& getCompositorName ();
protected:
inline Ogre::SceneManager* getSceneManager() const { return mSceneMgr; }
friend class DepthComposerInstance;
public:
DepthComposer(Ogre::SceneManager *sceneMgr);
virtual ~DepthComposer();
void update ();
public:
typedef std::map<Ogre::Viewport*, DepthComposerInstance*> ViewportInstanceMap;
ViewportInstanceMap mViewportInstanceMap;
public:
DepthComposerInstance* createViewportInstance(Ogre::Viewport* viewport);
void destroyViewportInstance(Ogre::Viewport* viewport);
DepthComposerInstance* getViewportInstance(Ogre::Viewport* viewport);
void destroyAllViewportInstances();
private:
bool mDebugDepthRender;
public:
/// Enables drawing the depth buffer
void setDebugDepthRender (bool value);
bool getDebugDepthRender () const { return mDebugDepthRender; }
private:
bool mSkyDomeHazeEnabled;
Ogre::Vector3 mSunDirection;
Ogre::ColourValue mHazeColour;
public:
/// Enables skydome haze.
void setSkyDomeHazeEnabled (bool value);
bool getSkyDomeHazeEnabled () const { return mSkyDomeHazeEnabled; }
void setSunDirection (const Ogre::Vector3& value) { mSunDirection = value; }
const Ogre::Vector3 getSunDirection () const { return mSunDirection; }
void setHazeColour (const Ogre::ColourValue& value) { mHazeColour = value; }
const Ogre::ColourValue getHazeColour () const { return mHazeColour; }
private:
bool mGroundFogEnabled;
Real mGroundFogDensity;
Real mGroundFogBaseLevel;
Real mGroundFogVerticalDecay;
Ogre::ColourValue mGroundFogColour;
public:
/// Enables exponential ground fog.
void setGroundFogEnabled (bool value);
bool getGroundFogEnabled () const { return mGroundFogEnabled; }
/// Sets ground fog density
void setGroundFogDensity (Real value) { mGroundFogDensity = value; }
/// Get ground fog density
Real getGroundFogDensity () const { return mGroundFogDensity; }
/// Sets ground fog level
/// At ground level fogginess is equal to GroundFogDensity
void setGroundFogBaseLevel (Real value) { mGroundFogBaseLevel = value; }
/// Get ground fog density
Real getGroundFogBaseLevel () const { return mGroundFogBaseLevel; }
/// Sets ground fog vertical decay
void setGroundFogVerticalDecay (Real value) { mGroundFogVerticalDecay = value; }
/// Get ground fog density
Real getGroundFogVerticalDecay () const { return mGroundFogVerticalDecay; }
/// Sets ground fog colour
void setGroundFogColour (const Ogre::ColourValue& value) { mGroundFogColour = value; }
/// Get ground fog colour
const Ogre::ColourValue getGroundFogColour () const { return mGroundFogColour; }
};
/** Per-viewport instance of @see DepthComposer
* This will create and control one ogre::CompositorInstance.
*/
class CAELUM_EXPORT DepthComposerInstance: private Ogre::CompositorInstance::Listener
{
private:
DepthComposer* mParent;
Ogre::Viewport* mViewport;
Ogre::CompositorInstance* mCompInst;
std::auto_ptr<DepthRenderer> mDepthRenderer;
virtual void notifyMaterialSetup(uint pass_id, Ogre::MaterialPtr &mat);
virtual void notifyMaterialRender(uint pass_id, Ogre::MaterialPtr &mat);
struct Params {
void setup(Ogre::GpuProgramParametersSharedPtr params);
Ogre::GpuProgramParametersSharedPtr fpParams;
FastGpuParamRef invViewProjMatrix;
FastGpuParamRef worldCameraPos;
FastGpuParamRef groundFogDensity;
FastGpuParamRef groundFogVerticalDecay;
FastGpuParamRef groundFogBaseLevel;
FastGpuParamRef groundFogColour;
FastGpuParamRef sunDirection;
FastGpuParamRef hazeColour;
} mParams;
protected:
/// Called from DepthComposer::update
void _update ();
void addCompositor ();
void removeCompositor ();
bool isCompositorEnabled () { return mCompInst != 0; }
friend class DepthComposer;
public:
/// Get parent DepthComposer; with all the interesting parameters.
DepthComposer* getParent() const { return mParent; }
/// Get the viewport this instance is attached to.
Ogre::Viewport* getViewport() const { return mViewport; }
/// Get compositor instance; attached to the viewport.
Ogre::CompositorInstance* getCompositorInstance() const { return mCompInst; }
/** Get the underlying depth renderer.
* Allow the user to tweak the depth renderer.
*/
Caelum::DepthRenderer* getDepthRenderer () const { return mDepthRenderer.get(); }
DepthComposerInstance(DepthComposer* parent, Ogre::Viewport* view);
virtual ~DepthComposerInstance();
};
/** Render the depth buffer to a texture.
*
* This class tries to be as generic and flexible as possible; but it
* is currently only used by the depth composer.
*/
class CAELUM_EXPORT DepthRenderer: private Ogre::RenderQueue::RenderableListener
{
private:
Ogre::Viewport* mMasterViewport;
Ogre::Viewport* mDepthRenderViewport;
Ogre::TexturePtr mDepthRenderTexture;
bool mDepthRenderingNow;
Ogre::MaterialPtr mDepthRenderMaterial;
// Override materials during all rendering.
#if OGRE_VERSION < 0x00010600
virtual bool renderableQueued(
Ogre::Renderable* rend,
Ogre::uint8 groupId,
Ogre::ushort priority,
Ogre::Technique** ppTech);
#else
virtual bool renderableQueued(
Ogre::Renderable* rend,
Ogre::uint8 groupId,
Ogre::ushort priority,
Ogre::Technique** ppTech,
Ogre::RenderQueue* pQueue);
#endif // OGRE_VERSION
inline Ogre::Material* getDepthRenderMaterial() const { return mDepthRenderMaterial.get(); }
int mMinRenderGroupId;
int mMaxRenderGroupId;
int mViewportVisibilityMask;
public:
DepthRenderer (Ogre::Viewport* viewport);
~DepthRenderer ();
inline Ogre::Viewport* getMasterViewport() { return mMasterViewport; }
inline Ogre::Texture* getDepthRenderTexture () { return mDepthRenderTexture.get(); }
inline Ogre::Viewport* getDepthRenderViewport () { return mDepthRenderViewport; }
inline Ogre::RenderTexture* getDepthRenderTarget () {
return mDepthRenderTexture->getBuffer()->getRenderTarget ();
}
/// Render the depth buffer now!
void update ();
/** Render only the render groups in a certain range.
* Call this to only render objects in certain render queue groups.
* The range is inclusive.
* This is a very primitive sort of filter.
*/
void setRenderGroupRangeFilter (int minGroup, int maxGroup);
/// @see setRenderGroupRangeFilter
int getRenderGroupRangeFilterMin () { return mMinRenderGroupId; }
int getRenderGroupRangeFilterMax () { return mMaxRenderGroupId; }
/** Disable the effects of @see setRenderGroupRangeFilter
*/
void disableRenderGroupRangeFilter ();
/** Query mask for the depth rendering viewport.
* Enforces on every update ();
*/
void setViewportVisibilityMask (uint value) { mViewportVisibilityMask = value; }
uint getViewportVisibilityMask () { return mViewportVisibilityMask; }
void disableViewportVisibilityMask () { mViewportVisibilityMask = ~0; }
public:
/** If true then use a user-supplied material scheme which outputs depth.
*
* The depth output of most materials is obvious and can be guessed most of the time.
* When that fails you can provide a custom material scheme for certain materials which
* renders the depth buffer.
*
* This is enabled by default for a scheme called CaelumDepth.
*/
inline void setUseCustomDepthScheme (bool value) { mUseCustomDepthScheme = value; }
inline bool getUseCustomDepthScheme () { return mUseCustomDepthScheme; }
/** Set the name of the custom depth scheme (default is CaelumDepth).
*/
inline void setCustomDepthSchemeName (const Ogre::String& value) { mCustomDepthSchemeName = value; }
inline const Ogre::String& getCustomDepthSchemeName () { return mCustomDepthSchemeName; }
/// Default name of the custom scheme.
static const String DEFAULT_CUSTOM_DEPTH_SCHEME_NAME;
private:
bool mUseCustomDepthScheme;
Ogre::String mCustomDepthSchemeName;
};
}
#endif // CAELUM__DEPTH_COMPOSER_H

@ -0,0 +1,143 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2009 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__FAST_GPU_PARAM_REF_H
#define CAELUM__FAST_GPU_PARAM_REF_H
#include "CaelumPrerequisites.h"
namespace Caelum
{
/** @file */
/** Controls if FastGpuParamRef checks pointer match when setting.
* This setting trades safety for performance. By default it's equal to OGRE_DEBUG_MODE.
*/
#define CAELUM_DEBUG_PARAM_REF OGRE_DEBUG_MODE
/** An optimized reference to a gpu shared parameter.
*
* Profiling shows that GpuProgramParameters::_findNamedConstantDefinition is not free.
*
* This class avoids hash lookups when updating. It's uses no additional
* memory than if you were to implement the same thing manually.
*
* You must also keep the matching Ogre::GpuProgramParametersSharedPtr
* and send it whenever you call FastGpuParamRef::set. This is required
* to save memory in release mode. Debug mode checks the pointer you
* pass to set is the same as the pointer you called bind on; but uses more memory.
*
* Also; please note that fetching gpu params from a material every frame is not free either.
*/
class CAELUM_EXPORT FastGpuParamRef
{
public:
/// Default constructor. Starts as unbound
FastGpuParamRef(): mPhysicalIndex(InvalidPhysicalIndex)
{
// mParams needs no initialization; SharedPtrs start as 0.
}
/// Create and bind.
FastGpuParamRef(Ogre::GpuProgramParametersSharedPtr paramsPtr, const Ogre::String& name);
/** Bind to a certain parameter.
*
* @param paramsPtr params to bind to. Can't be null; you must unbind explicitly.
* @param name The name of the parameter to bind.
* @param throwIfNotFound Argument to GpuProgramParameters::_findNamedConstantDefinition.
*
* If throwIfNotFound is false (the default) missing parameters are
* ignored and the param ref will remand unbound. Calling set will
* then have no effect.
*/
void bind(
Ogre::GpuProgramParametersSharedPtr paramsPtr,
const Ogre::String& name,
bool throwIfNotFound = false);
/** Unbind ParamRef.
*
* If CAELUM_DEBUG_PARAM_REF is 1 this will also release the hold
* on GpuProgramParametersSharedPtr.
*/
void unbind();
/// Return if this param ref is bound to an actual param.
inline bool isBound() const { return mPhysicalIndex != InvalidPhysicalIndex; }
/// Return the physical index. Only valid if this->isBound().
inline size_t getPhysicalIndex () const { return mPhysicalIndex; }
protected:
/** Set the value. No effect if !this->isBound()
*
* @param params Parameter pointer. Can't be null
* @param arg Argument to set.
*
* Will check params pointer matches the bound pointer if #CAELUM_DEBUG_PARAM_REF.
* Otherwise a mismatched params pointer can result in memory corruption.
*/
template<typename ArgumentT>
inline void doSet(const Ogre::GpuProgramParametersSharedPtr& params, ArgumentT arg) const {
#if CAELUM_DEBUG_PARAM_REF
assert(params.getPointer() == mParams.getPointer());
#endif
assert(!params.isNull());
if (mPhysicalIndex != InvalidPhysicalIndex) {
params->_writeRawConstant(mPhysicalIndex, arg);
}
}
template<typename ArgumentT>
inline void doSet(const Ogre::GpuProgramParametersSharedPtr& params, ArgumentT arg, size_t count) const {
#if CAELUM_DEBUG_PARAM_REF
assert(params.getPointer() == mParams.getPointer());
#endif
assert(!params.isNull());
if (mPhysicalIndex != InvalidPhysicalIndex) {
params->_writeRawConstant(mPhysicalIndex, arg, count);
}
}
public:
/// @copydoc FastGpuParamRef::doSet
inline void set(const Ogre::GpuProgramParametersSharedPtr& params, int val) const { doSet<int>(params, val); }
/// @copydoc FastGpuParamRef::doSet
inline void set(const Ogre::GpuProgramParametersSharedPtr& params, Ogre::Real val) const { doSet<Ogre::Real>(params, val); }
/// @copydoc FastGpuParamRef::doSet
inline void set(const Ogre::GpuProgramParametersSharedPtr& params, const Ogre::Vector3& val) const { doSet<const Ogre::Vector3&>(params, val); }
/// @copydoc FastGpuParamRef::doSet
inline void set(const Ogre::GpuProgramParametersSharedPtr& params, const Ogre::Vector4& val) const { doSet<const Ogre::Vector4&>(params, val); }
/// @copydoc FastGpuParamRef::doSet
inline void set(const Ogre::GpuProgramParametersSharedPtr& params, const Ogre::ColourValue& val) const { doSet<const Ogre::ColourValue&>(params, val); }
/// @copydoc FastGpuParamRef::doSet
inline void set(const Ogre::GpuProgramParametersSharedPtr& params, const Ogre::Matrix4& val) const { doSet<const Ogre::Matrix4*>(params, &val, 1); }
private:
#if CAELUM_DEBUG_PARAM_REF
Ogre::GpuProgramParametersSharedPtr mParams;
#endif
static const size_t InvalidPhysicalIndex = 0xFFFFFFFF;
size_t mPhysicalIndex;
};
}
#endif /* CAELUM__FAST_GPU_PARAM_REF_H */

@ -0,0 +1,366 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__FLAT_CLOUD_LAYER_H
#define CAELUM__FLAT_CLOUD_LAYER_H
#include "CaelumPrerequisites.h"
#include "InternalUtilities.h"
#include "PrivatePtr.h"
#include "FastGpuParamRef.h"
namespace Caelum
{
/** A flat cloud layer; drawn as a simple plane.
* Supports movement and variable cloud cover.
*
* There are significant incompatible difference between this and the
* LayeredClouds from version 0.3. This implementation of clouds is
* positioned in world space while the old implementation was a curved
* plane moving with the camera. It is not possible to perfectly simulate
* the older implementation.
*
* @note This is tighly integrated with LayeredCloud.cg and LayeredClouds.material.
*/
class CAELUM_EXPORT FlatCloudLayer
{
public:
FlatCloudLayer(
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *cloudRoot);
~FlatCloudLayer();
/** Update function called each frame from above.
* This can be reproduced with calls to other public functions.
*/
void update (
Ogre::Real timePassed,
const Ogre::Vector3 &sunDirection,
const Ogre::ColourValue &sunLightColour,
const Ogre::ColourValue &fogColour,
const Ogre::ColourValue &sunSphereColour);
/// Advance cloud animation (the time part of FlatCloudLayer::update).
void advanceAnimation (Ogre::Real timePassed);
/** Reset most tweak settings to their default values
*/
void reset ();
private:
Ogre::Vector2 mCloudSpeed;
Ogre::Vector2 mCloudMassOffset;
Ogre::Vector2 mCloudDetailOffset;
// Set texture offsets.
// Animated every frame.
void setCloudMassOffset(const Ogre::Vector2 &cloudMassOffset);
void setCloudDetailOffset(const Ogre::Vector2 &cloudDetailOffset);
public:
/** Sets cloud movement speed.
* @param cloudSpeed Cloud movement speed.
*/
void setCloudSpeed (const Ogre::Vector2 &cloudSpeed);
/** Gets cloud movement speed.
* @param cloudSpeed Cloud movement speed.
*/
const Ogre::Vector2 getCloudSpeed () const { return mCloudSpeed; }
private:
Ogre::Vector3 mSunDirection;
Ogre::ColourValue mSunLightColour;
Ogre::ColourValue mSunSphereColour;
Ogre::ColourValue mFogColour;
public:
void setSunDirection(const Ogre::Vector3 &sunDirection);
void setSunLightColour(const Ogre::ColourValue &sunLightColour);
void setSunSphereColour(const Ogre::ColourValue &sunSphereColour);
void setFogColour(const Ogre::ColourValue &fogColour);
const Ogre::Vector3 getSunDirection () const;
const Ogre::ColourValue getSunLightColour () const;
const Ogre::ColourValue getSunSphereColour () const;
const Ogre::ColourValue getFogColour () const;
private:
/// Pointer to scene manager.
Ogre::SceneManager *mSceneMgr;
// Note: objects are destroyed in reverse order of declaration.
// This means that objects must be ordered by dependency.
/// Cloned cloud material.
PrivateMaterialPtr mMaterial;
struct Params
{
void setup(Ogre::GpuProgramParametersSharedPtr fpParams, Ogre::GpuProgramParametersSharedPtr vpParams);
Ogre::GpuProgramParametersSharedPtr vpParams;
Ogre::GpuProgramParametersSharedPtr fpParams;
FastGpuParamRef cloudCoverageThreshold;
FastGpuParamRef cloudMassOffset;
FastGpuParamRef cloudDetailOffset;
FastGpuParamRef cloudMassBlend;
FastGpuParamRef vpSunDirection;
FastGpuParamRef fpSunDirection;
FastGpuParamRef sunLightColour;
FastGpuParamRef sunSphereColour;
FastGpuParamRef fogColour;
FastGpuParamRef layerHeight;
FastGpuParamRef cloudUVFactor;
FastGpuParamRef heightRedFactor;
FastGpuParamRef nearFadeDist;
FastGpuParamRef farFadeDist;
FastGpuParamRef fadeDistMeasurementVector;
} mParams;
private:
PrivateMeshPtr mMesh;
PrivateSceneNodePtr mNode;
PrivateEntityPtr mEntity;
// Mesh parameters.
bool mMeshDirty;
Real mMeshWidth, mMeshHeight;
int mMeshWidthSegments, mMeshHeightSegments;
public:
/** Regenerate the plane mesh and recreate entity.
* This automatically happens in update.
*/
void _ensureGeometry();
/** Regenerate the plane mesh and recreate entity.
* This automatically happens when mesh parameters are changed.
*/
void _invalidateGeometry();
/** Reset all mesh parameters.
*/
void setMeshParameters (
Real meshWidth, Real meshHeight,
int meshWidthSegments, int meshHeightSegments);
/// @see setMeshParameters
inline void setMeshWidth (Real value) { mMeshWidth = value; _invalidateGeometry (); }
inline void setMeshHeight (Real value) { mMeshHeight = value; _invalidateGeometry (); }
inline void setMeshWidthSegments (int value) { mMeshWidthSegments = value; _invalidateGeometry (); }
inline void setMeshHeightSegments (int value) { mMeshHeightSegments = value; _invalidateGeometry (); }
inline Real getMeshWidth () const { return mMeshWidth; }
inline Real getMeshHeight () const { return mMeshHeight; }
inline int getMeshWidthSegments () const { return mMeshWidthSegments; }
inline int getMeshHeightSegments () const { return mMeshHeightSegments; }
private:
/// Lookup used for cloud coverage, @see setCloudCoverLookup.
std::auto_ptr<Ogre::Image> mCloudCoverLookup;
/// Filename of mCloudCoverLookup
Ogre::String mCloudCoverLookupFileName;
/// Value passed to setCloudCover (before lookup).
Ogre::Real mCloudCover;
public:
/** Sets cloud cover, between 0 (completely clear) and 1 (completely covered)
* @param cloudCover Cloud cover between 0 and 1
*/
void setCloudCover (const Ogre::Real cloudCover);
/** Gets the current cloud cover.
* @return Cloud cover, between 0 and 1
*/
inline Ogre::Real getCloudCover () const { return mCloudCover; }
/** Set the image used to lookup the cloud coverage threshold.
* This image is used to calculate the cloud coverage threshold
* based on the desired cloud cover.
*
* The cloud coverage threshold is substracted from cloud intensity
* at any point; to generate fewer or more clouds. That threshold is
* not linear, a lookup is required to ensure that setCloudCover(0.1)
* will actually have 10% the clouds at setCloudCover(1).
*
* The lookup is the inverse of the sum on the histogram, and was
* calculated with a small hacky tool.
*/
void setCloudCoverLookup (const Ogre::String& fileName);
/** Get the filename of the cloud cover lookup image.
* This returns the value set by setCloudCoverLookup or an empty
* string if disabled.
*/
const Ogre::String getCloudCoverLookupFileName () const;
/** Disable any cloud cover lookup.
* @see setCloudCoverLookup.
*/
void disableCloudCoverLookup ();
private:
Ogre::Real mCloudCoverVisibilityThreshold;
protected:
/** Enforce setCloudCoverVisibilityThreshold.
*/
void _updateVisibilityThreshold ();
public:
/// Get cloud cover visiblity threshold.
/// Beneath this cloud coverage nothing is drawn anymore.
Ogre::Real getCloudCoverVisibilityThreshold () const { return mCloudCoverVisibilityThreshold; }
/** Set cloud cover visiblity threshold.
*
* Beneath this cloud coverage nothing is drawn anymore.
* Default value is very very low (0.001). All this does is save you from
* destroying/recreating layers when they're too thin to bother drawing.
*/
void setCloudCoverVisibilityThreshold (const Ogre::Real value);
private:
/// Height of this cloud layer; equal to node's y position.
Ogre::Real mHeight;
public:
/** Set the height of the cloud layer.
* @param height In world units above the cloud root node.
*/
void setHeight(Ogre::Real height);
/** Get the height of the cloud layer.
* @return height In world units above the cloud root node.
*/
Ogre::Real getHeight() const;
private:
/// Current cloud blend position; from 0 to mNoiseTextureNames.size()
Ogre::Real mCloudBlendPos;
/// Current index in the set of textures.
/// Cached to avoid setting textures every frame.
int mCurrentTextureIndex;
/// Time required to blend two cloud shapes.
Ogre::Real mCloudBlendTime;
/// Names of noise textures.
std::vector<String> mNoiseTextureNames;
public:
/** Sets the time it takes to blend two cloud shaped together, in seconds.
* This will also reset the animation at the current time.
* @param value Cloud shape blend time in seconds
*/
void setCloudBlendTime (const Ogre::Real value);
/** Gets the time it takes to blend two cloud shaped together, in seconds.
* @return Cloud shape blend time in seconds
*/
Ogre::Real getCloudBlendTime () const;
/** Set the current blending position; between noise textures.
* Integer values are used for single textures. Float values blend between two textures.
* Values outside [0, textureCount) are wrapped around.
* @param value New cloud blending position
*/
void setCloudBlendPos (const Ogre::Real value);
/// @see setCloudBlendPos
Ogre::Real getCloudBlendPos () const;
private:
Ogre::Real mCloudUVFactor;
public:
/** Cloud texture coordinates are multiplied with this.
* Higher values result in more spread-out clouds.
* Very low value result in ugly texture repeats.
*/
void setCloudUVFactor (const Ogre::Real value);
/// @see setCloudUVFactor
inline Ogre::Real getCloudUVFactor () const { return mCloudUVFactor; }
private:
Ogre::Real mHeightRedFactor;
public:
/** High-altitude clouds are tinted red in the evening.
* Higher values attenuate the effect.
*/
void setHeightRedFactor (const Ogre::Real value);
/// @see setCloudUVFactor
Ogre::Real getHeightRedFactor () const { return mHeightRedFactor; }
private:
Ogre::Real mNearFadeDist;
Ogre::Real mFarFadeDist;
Ogre::Vector3 mFadeDistMeasurementVector;
public:
/** Cloud fade distances.
*
* These are measured horizontally in meters (height is not used).
*
* The effect is a fade based on alpha blending which occurs between
* nearValue and farValue. After farValue nothing is visibile from
* this layer.
*
* Default values are 10000 and 140000
*/
void setFadeDistances (Ogre::Real nearValue, Ogre::Real farValue);
/// Set only near fade distance (see setFadeDistances).
void setNearFadeDist (const Ogre::Real value);
/// Get near fade distance (see setFadeDistances).
Ogre::Real getNearFadeDist () const { return mNearFadeDist; }
/// Set only far fade distance (see setFadeDistances).
void setFarFadeDist (const Ogre::Real value);
/// Get fade distance (see setFadeDistances).
Ogre::Real getFarFadeDist () const { return mFarFadeDist; }
/** Set on which components is the fade distance measured.
*
* Default is Vector3(0, 1, 1) which measures fade distance
* horizontally in caelum's default assumed coordinate system.
*
* If you're in a Z-up system you probably want to set this to (1, 1, 0).
*
* Fade distance is always measured relative to the camera.
*/
void setFadeDistMeasurementVector (const Ogre::Vector3& value);
/// Get the value set by setFadeDistMeasurementVector.
const Ogre::Vector3 getFadeDistMeasurementVector () const { return mFadeDistMeasurementVector; }
public:
void setQueryFlags (uint flags) { mEntity->setQueryFlags (flags); }
uint getQueryFlags () const { return mEntity->getQueryFlags (); }
void setVisibilityFlags (uint flags) { mEntity->setVisibilityFlags (flags); }
uint getVisibilityFlags () const { return mEntity->getVisibilityFlags (); }
};
}
#endif // CAELUM__FLAT_CLOUD_LAYER_H

@ -0,0 +1,202 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GROUNDFOG_H
#define GROUNDFOG_H
#include "CaelumPrerequisites.h"
#include "CameraBoundElement.h"
#include "PrivatePtr.h"
#include "FastGpuParamRef.h"
namespace Caelum
{
/** Exponential ground fog system implementation.
*
* This class controls CaelumGroundFog passes in a potentially large number
* of materials, changing shader program parameters. This class keeps a list
* of passes to control; which can be build based on pass name.
*
* This simulates a field of fog where "absorption" at a certain point is
* exp(-verticalDecay * (h - fogLevel)). This absorption is multiplicative,
* the total fog alpha is e^(-density * absorption_on_view_path).
*
* You can set verticalDecay to 0 and get standard GL_EXP fog. Don't actually
* do that though because you'll get a division by 0.
*
* @note: This is deprecated starting from Caelum 0.4. The DepthComposer class
* provides similar functionality with less intrusion on your materials.
*/
class CAELUM_EXPORT GroundFog: public CameraBoundElement
{
public:
static const Ogre::String DEFAULT_PASS_NAME;
/** Constructor.
*/
GroundFog (Ogre::SceneManager *scene,
Ogre::SceneNode *caelumRootNode,
const Ogre::String &domeMaterialName = "CaelumGroundFogDome",
const Ogre::String &domeEntityName = "CaelumGroundFogDome");
/** Virtual destructor.
*/
virtual ~GroundFog ();
/** Typedef for easier manipulation of a set of Passes.
*/
typedef std::set<Ogre::Pass *> PassSet;
/** Get the set of currently controlled passes.
* This is provided if you really want to change the set by hand.
* You should call forceUpdate after modifying this set.
*/
PassSet& getPasses();
/** Get the set of currently controlled passes.
* This is a const overload which doesn't let you modify the
* underlying collection.
*/
const PassSet& getPasses () const;
/** Find caelum fog passes to control by name.
* By default this looks for passes called "CaleumGroundFog".
* @note This calls forceUpdate()
*/
void findFogPassesByName (const Ogre::String& passName = DEFAULT_PASS_NAME);
/// Sets the fog density multiplier
void setDensity (Ogre::Real density);
/// Get the fog density multiplier
Ogre::Real getDensity () const;
/// Sets fog colour
void setColour (const Ogre::ColourValue &colour);
/// Gets fog colour
const Ogre::ColourValue getColour () const;
/// Sets the vertical fog decay constant.
void setVerticalDecay (Ogre::Real verticalDecay);
/// Get the vertical fog decay constant.
Ogre::Real getVerticalDecay () const;
/** Sets the ground level.
* At ground level 'fogginess' is equal to 1.
*/
void setGroundLevel (Ogre::Real GroundLevela);
/** Get the ground level.
*/
Ogre::Real getGroundLevel () const;
/** Forces an update of all the passes. You have to use this if you modify
* the set of passes by hand, otherwise avoid it.
*/
void forceUpdate ();
private:
/// Cached Density
Ogre::Real mDensity;
/// Cached VerticalDecay
Ogre::Real mVerticalDecay;
/// Cached GroundLevel
Ogre::Real mGroundLevel;
/// Fog colour
Ogre::ColourValue mFogColour;
private:
/// The scene to control fog in.
Ogre::SceneManager* mScene;
/// Sky dome material
PrivateMaterialPtr mDomeMaterial;
/// Sky dome node
PrivateSceneNodePtr mDomeNode;
/// Sky dome entity
PrivateEntityPtr mDomeEntity;
// Called whenever something changes to update the sky dome.
void updateSkyFogging();
protected:
/// Handle far radius.
virtual void setFarRadius (Ogre::Real radius);
public:
/// Handle camera change.
virtual void notifyCameraChanged (Ogre::Camera *cam);
void setQueryFlags (uint flags) { mDomeEntity->setQueryFlags (flags); }
uint getQueryFlags () const { return mDomeEntity->getQueryFlags (); }
void setVisibilityFlags (uint flags) { mDomeEntity->setVisibilityFlags (flags); }
uint getVisibilityFlags () const { return mDomeEntity->getVisibilityFlags (); }
private:
/// The passes to control.
PassSet mPasses;
/// Params references.
struct FogParamsBase
{
void setup(Ogre::GpuProgramParametersSharedPtr fpParams);
Ogre::GpuProgramParametersSharedPtr fpParams;
FastGpuParamRef fogDensity;
FastGpuParamRef fogColour;
FastGpuParamRef fogVerticalDecay;
FastGpuParamRef fogGroundLevel;
};
struct DomeFogParams: public FogParamsBase {
void setup(Ogre::GpuProgramParametersSharedPtr fpParams);
FastGpuParamRef cameraHeight;
} mDomeParams;
struct PassFogParams: public FogParamsBase {
PassFogParams(Ogre::GpuProgramParametersSharedPtr fpParams) { setup(fpParams); }
static inline bool lessThanByParams(const PassFogParams& a, const PassFogParams& b) {
return a.fpParams.get() <= b.fpParams.get();
}
static inline bool equalByParams(const PassFogParams& a, const PassFogParams& b) {
return a.fpParams.get() == b.fpParams.get();
}
};
typedef std::vector<PassFogParams> PassFogParamsVector;
PassFogParamsVector mPassFogParams;
/// Update mPassFogParams based on mPasses
void updatePassFogParams();
};
}
#endif //GROUNDFOG_H

@ -0,0 +1,102 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__IMAGE_STARFIELD_H
#define CAELUM__IMAGE_STARFIELD_H
#include "CaelumPrerequisites.h"
#include "CameraBoundElement.h"
#include "PrivatePtr.h"
namespace Caelum
{
/** Image-based starfield class.
* This class implements a starfield based on mapping a single large
* texture on a sphere. @see PointStarfield for a better solution.
*/
class CAELUM_EXPORT ImageStarfield : public CameraBoundElement
{
protected:
/// Reference to the dome node.
PrivateSceneNodePtr mNode;
/// Reference to the (cloned) starfield material.
PrivateMaterialPtr mStarfieldMaterial;
/// Reference to the dome entity.
PrivateEntityPtr mEntity;
/// Name of the spheric dome resource.
static const Ogre::String STARFIELD_DOME_NAME;
/// Name of the starfield material.
static const Ogre::String STARFIELD_MATERIAL_NAME;
/** Inclination of the starfield.
*/
Ogre::Degree mInclination;
public:
static const String DEFAULT_TEXTURE_NAME;
/** Constructor.
@param sceneMgr The scene manager this dome will belong to.
*/
ImageStarfield (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
const Ogre::String &textureName = DEFAULT_TEXTURE_NAME);
/** Destructor.
*/
virtual ~ImageStarfield ();
/** Sets the starfield inclination. This inclination is the angle between the starfield rotation axis and the horizon plane.
@param inc The starfield inclination in degrees. It`s equal to observer latitude taken with opposite sign.
*/
void setInclination (Ogre::Degree inc);
/** Updates the starfield position/orientation.
@param time Local time in [0, 1] range.
*/
void update (const float time);
/** Updates the starfield material.
@param mapName The new starfield texture map name.
*/
void setTexture (const Ogre::String &mapName);
public:
/// Handle camera change.
virtual void notifyCameraChanged (Ogre::Camera *cam);
protected:
/// Handle far radius.
virtual void setFarRadius (Ogre::Real radius);
public:
void setQueryFlags (uint flags) { mEntity->setQueryFlags (flags); }
uint getQueryFlags () const { return mEntity->getQueryFlags (); }
void setVisibilityFlags (uint flags) { mEntity->setVisibilityFlags (flags); }
uint getVisibilityFlags () const { return mEntity->getVisibilityFlags (); }
};
}
#endif // CAELUM__IMAGE_STARFIELD_H

@ -0,0 +1,118 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM_HEADER__PRIVATE_UTILITIES_H
#define CAELUM_HEADER__PRIVATE_UTILITIES_H
#include "CaelumPrerequisites.h"
#include "PrivatePtr.h"
namespace Caelum
{
/** Private caelum utilities
*
* This class constains various tiny utilities for caelum to use.
*/
class CAELUM_EXPORT InternalUtilities
{
public:
/** Gets the interpolated colour between two pixels from an image.
Interpolate a texture pixel by hand. (fx, fy) are in texture coordinates,
ranging [0-1] across the entire texture.
Smooth blending is only done on the x coordinate.
Wrapping is only supported on X as well.
@param fx Horizontal coordinate.
@param fy Vertical coordiate.
@param img The lookup image.
@param wrapX To wrap the x coordinate.
@return The interpolated colour.
*/
static Ogre::ColourValue getInterpolatedColour (
float fx,
float fy,
Ogre::Image *img,
bool wrapX = true);
/** Quickly format a pointer as a string; in hex
*/
static const Ogre::String pointerToString(void* pointer);
/** Creates a private clone of a material from a script.
*
* When a class wants to modify a material at runtime it must not
* modify the original material loaded from scripts. Instead it
* should create a clone and use that.
*
* This method throws a Caelum::UnsupportedException on failure.
*
* @param originalName Name of the original material.
* @param cloneName Name of the result clone.
*
* @return A pointer to an unique material.
*/
static Ogre::MaterialPtr checkLoadMaterialClone (
const Ogre::String& originalName,
const Ogre::String& cloneName);
/** Fetch a compositor by name and check it can be loaded properly
*
* This method throws a Caelum::UnsupportedException on failure.
*
* @param name Name of the compositor to check.
*
* @return A pointer to the compositor (can be ignored)
*/
static Ogre::CompositorPtr checkCompositorSupported (const Ogre::String& name);
public:
/** Enumeration of types of sky domes.
*/
enum DomeType {
DT_SKY_DOME,
DT_IMAGE_STARFIELD,
};
/** Creates a longitude-latitude sky dome.
* @note Does nothing if the sphere already exists.
* @param name The name of the mesh to be created.
* @param segments The number of sphere segments.
* @param domeType The type of dome to create.
*/
static void generateSphericDome (const Ogre::String &name, int segments, DomeType domeType);
private:
/** Fills the vertex and index buffers for a sky gradients type dome.
* @param pVertex Pointer to the vertex buffer.
* @param pIndices Pointer to the index buffer.
* @param segments Subdivision detail.
*/
static void fillGradientsDomeBuffers (float *pVertex, unsigned short *pIndices, int segments);
/** Fills the vertex and index buffers for a stardield type dome.
* @param pVertex Pointer to the vertex buffer.
* @param pIndices Pointer to the index buffer.
* @param segments Subdivision detail.
*/
static void fillStarfieldDomeBuffers (float *pVertex, unsigned short *pIndices, int segments);
};
}
#endif // CAELUM_HEADER__PRIVATE_UTILITIES_H

@ -0,0 +1,108 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__MOON_H
#define CAELUM__MOON_H
#include "CaelumPrerequisites.h"
#include "SkyLight.h"
#include "FastGpuParamRef.h"
#include "PrivatePtr.h"
namespace Caelum
{
/** Class representing the moon.
* Drawn as two billboards; one after the stars and one after the skydome.
* Drawing it before the skydome will make it invisible in daylight; and that's bad.
*/
class CAELUM_EXPORT Moon:
public BaseSkyLight
{
public:
/// Name of the moon material.
static const Ogre::String MOON_MATERIAL_NAME;
/// Name of the moon background material.
static const Ogre::String MOON_BACKGROUND_MATERIAL_NAME;
private:
/// Material for MoonBB
PrivateMaterialPtr mMoonMaterial;
/// The moon sprite.
PrivateBillboardSetPtr mMoonBB;
/// Material for mBackBB
PrivateMaterialPtr mBackMaterial;
/// The moon's background; used to block the stars.
PrivateBillboardSetPtr mBackBB;
/// The moon sprite visible angle
Ogre::Degree mAngularSize;
struct Params {
void setup(Ogre::GpuProgramParametersSharedPtr fpParams);
Ogre::GpuProgramParametersSharedPtr fpParams;
FastGpuParamRef phase;
} mParams;
public:
/** Constructor.
*/
Moon (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
const Ogre::String& moonTextureName = "moon_disc.dds",
Ogre::Degree angularSize = Ogre::Degree(3.77f));
virtual ~Moon ();
/** Updates the moon material.
@param textureName The new moon texture name.
*/
void setMoonTexture (const Ogre::String &textureName);
/** Updates the moon size.
@param moon TextureAngularSize The new moon texture angular size.
*/
void setMoonTextureAngularSize(const Ogre::Degree& moonTextureAngularSize);
/** Sets the moon sphere colour.
@param colour The colour used to draw the moon
*/
void setBodyColour (const Ogre::ColourValue &colour);
/// Set the moon's phase
void setPhase (Ogre::Real phase);
public:
/// Handle camera change.
virtual void notifyCameraChanged (Ogre::Camera *cam);
virtual void setQueryFlags (uint flags);
virtual uint getQueryFlags () const;
virtual void setVisibilityFlags (uint flags);
virtual uint getVisibilityFlags () const;
};
}
#endif // CAELUM__MOON_H

@ -0,0 +1,212 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__POINT_STARFIELD_H
#define CAELUM__POINT_STARFIELD_H
#include "CaelumPrerequisites.h"
#include "CameraBoundElement.h"
#include "PrivatePtr.h"
#include "FastGpuParamRef.h"
namespace Caelum
{
/** POD for bright star catalogue entries.
* Only J2000 position and magnitude included.
*/
struct BrightStarCatalogueEntry {
signed char rasc_hour;
signed char rasc_min;
float rasc_sec;
signed char decl_deg;
signed char decl_min;
float decl_sec;
float magn;
};
/// There are exactly 9110 stars in our version of the BSC.
const int BrightStarCatalogueSize = 9110;
/// Hardcoded bright star catalogue (BrightStarCatalogue.cpp)
extern const BrightStarCatalogueEntry BrightStarCatalogue[BrightStarCatalogueSize];
/** Point starfield class.
* An Ogre::ManualObject is used for drawing because billboards are too slow.
*
* Stars are sized in pixels; this seems to work a lot better than relative sizes.
* Stars could be made even smaller but it would require hinting (nudging pixel
* coordinates to match actual screen pixels). Points are hard.
*
* Loading a bright-star catalogue is supported but star positions are
* likely only correct relative to each other. External rotation is probably wrong.
*/
class CAELUM_EXPORT PointStarfield:
public CameraBoundElement
{
public:
/** Constructor.
* By default this loads some reasonable defaults and the
* bright star catalogue.
*/
PointStarfield (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
bool initWithCatalogue = true);
/// Destructor.
virtual ~PointStarfield ();
/// Struct representing one star inside PointStarfield.
struct Star {
Ogre::Degree RightAscension;
Ogre::Degree Declination;
Ogre::Real Magnitude;
};
/// A vector of Star
typedef std::vector<Star> StarVector;
/** Get a reference to the vector of stars.
* You can freely modify this; but you need to updateStars when you're done.
*/
inline StarVector& getStarVector () { return mStars; }
/** You must call this if you change the star vector by hand.
*/
void notifyStarVectorChanged ();
/// Clear any and all stars.
void clearAllStars ();
/** Add a bunch of random stars.
*/
void addRandomStars (int count);
/** Add one star from the bright star catalogue.
*/
void addStar (const BrightStarCatalogueEntry &entry);
/** Add stars from the bright star catalogue.
* @param count Number of stars to add (in order of brightness).
*/
void addBrightStarCatalogue (int count = BrightStarCatalogueSize);
private:
/// Cloned material
PrivateMaterialPtr mMaterial;
/// Node for the starfield
PrivateSceneNodePtr mNode;
/// Manual object for drawing.
PrivateManualObjectPtr mManualObj;
/// Star data.
std::vector<Star> mStars;
Ogre::Real mMinPixelSize, mMaxPixelSize, mMag0PixelSize;
Ogre::Real mMagnitudeScale;
Ogre::Degree mObserverLatitude, mObserverLongitude;
bool mValidGeometry;
void invalidateGeometry();
void ensureGeometry();
public:
/** Update function; called from CaelumSystem::updateSubcomponents
@param time Time of the day.
*/
void _update (float time);
/** Magnitude power scale.
* Star magnitudes are logarithming; one magnitude difference
* means a star is 2.512 times brighter.
* This property allows tweaking that value.
*/
inline void setMagnitudeScale (Ogre::Real value) { mMagnitudeScale = value; }
inline Ogre::Real getMagnitudeScale () const { return mMagnitudeScale; }
inline void setMag0PixelSize (Ogre::Real value) { mMag0PixelSize = value; }
inline Ogre::Real getMag0PixelSize () const { return mMag0PixelSize; }
inline void setMinPixelSize (Ogre::Real value) { mMinPixelSize = value; }
inline Ogre::Real getMinPixelSize () const { return mMinPixelSize; }
inline void setMaxPixelSize (Ogre::Real value) { mMaxPixelSize = value; }
inline Ogre::Real getMaxPixelSize () const { return mMaxPixelSize; }
void setObserverLatitude (Ogre::Degree value);
inline Ogre::Degree getObserverLatitude () const { return mObserverLatitude; }
void setObserverLongitude (Ogre::Degree value);
inline Ogre::Degree getObserverLongitude () const { return mObserverLongitude; }
private:
Ogre::Degree mObserverPositionRebuildDelta;
public:
/** Moving the observer position around causes a starfield rebuild.
* Default value (DEFAULT_OBSERVER_POSITION_REBUILD_DELTA) is 0.1
* degrees which is equivalent to around 170 meters on the earth.
*
* This only matters if you compute the observer position every
* frame. Caelum doesn't contain code for that.
*/
inline Ogre::Degree getObserverPositionRebuildDelta () const {
return mObserverPositionRebuildDelta;
}
inline void setObserverPositionRebuildDelta (Ogre::Degree value) {
mObserverPositionRebuildDelta = value;
}
static const Ogre::Degree DEFAULT_OBSERVER_POSITION_REBUILD_DELTA;
/// Material used to draw all the points.
static const Ogre::String STARFIELD_MATERIAL_NAME;
/// Handle camera change.
virtual void notifyCameraChanged (Ogre::Camera *cam);
protected:
/// Handle far radius.
virtual void setFarRadius (Ogre::Real radius);
public:
void setQueryFlags (uint flags) { mManualObj->setQueryFlags (flags); }
uint getQueryFlags () const { return mManualObj->getQueryFlags (); }
void setVisibilityFlags (uint flags) { mManualObj->setVisibilityFlags (flags); }
uint getVisibilityFlags () const { return mManualObj->getVisibilityFlags (); }
private:
struct Params {
void setup(Ogre::GpuProgramParametersSharedPtr vpParams);
Ogre::GpuProgramParametersSharedPtr vpParams;
FastGpuParamRef mag_scale;
FastGpuParamRef mag0_size;
FastGpuParamRef min_size;
FastGpuParamRef max_size;
FastGpuParamRef aspect_ratio;
} mParams;
};
}
#endif // CAELUM__POINT_STARFIELD_H

@ -0,0 +1,283 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__PRECIPITATION_CONTROLLER_H
#define CAELUM__PRECIPITATION_CONTROLLER_H
#include "CaelumPrerequisites.h"
#include "FastGpuParamRef.h"
namespace Caelum
{
/** Preset parameters for a certain type of precipitation.
*/
struct PrecipitationPresetParams
{
Ogre::ColourValue Colour;
Ogre::Real Speed;
Ogre::String Name;
};
/** An enumeration of the available precipitation presets.
* @see PrecipitationController::getPrecipitationPreset
*/
enum PrecipitationType
{
PRECTYPE_DRIZZLE = 0,
PRECTYPE_RAIN = 1,
PRECTYPE_SNOW = 2,
PRECTYPE_SNOWGRAINS = 3,
PRECTYPE_ICECRYSTALS = 4,
PRECTYPE_ICEPELLETS = 5,
PRECTYPE_HAIL = 6,
PRECTYPE_SMALLHAIL = 7,
PRECTYPE_CUSTOM = 8,
};
/** Compositor-based precipitation controller.
* This class will add and control precipitation controllers to viewports.
*
* Compositors clone the composing materials. This controller will
* register itself as a compositor listener and change the material in notifyMaterialSetup.
*/
class CAELUM_EXPORT PrecipitationController
{
private:
friend class PrecipitationInstance;
Ogre::SceneManager *mSceneMgr;
Ogre::Vector3 mWindSpeed;
Ogre::Real mIntensity;
Ogre::Real mSpeed;
Ogre::ColourValue mColour;
PrecipitationType mPresetType;
Ogre::String mTextureName;
Ogre::Vector3 mCameraSpeedScale;
Ogre::Vector3 mFallingDirection;
Ogre::Real mAutoDisableThreshold;
bool mHardDisableCompositor;
Ogre::ColourValue mSceneColour;
Real mInternalTime;
// Only meant for the instance ctl in auto-camera-speed mode.
Real mSecondsSinceLastFrame;
inline Real getSecondsSinceLastFrame() { return mSecondsSinceLastFrame; }
public:
/// Name of the compositor resource.
static const String COMPOSITOR_NAME;
/// Name of the compositor material.
static const String MATERIAL_NAME;
/// Check if a preset type is valid.
static bool isPresetType (PrecipitationType value);
/// Get preset parameters for a certain type of precipitation.
static const PrecipitationPresetParams& getPresetParams (PrecipitationType value);
/// Set all parameters at once.
void setParams (const PrecipitationPresetParams& params);
/// Quickly set a certain preset type of precipitation.
void setPresetType (PrecipitationType value);
/** Get the preset type.
* Will return PRECIPITATION_CUSTOM if you modify parameters manually
* after setPresetType.
*/
PrecipitationType getPresetType () const;
// Texture name, part of a preset
void setTextureName(const Ogre::String& textureName);
const Ogre::String getTextureName() const;
/// Precipitation color. Part of a preset
void setColour(const Ogre::ColourValue& color);
const Ogre::ColourValue getColour() const;
/// Precipitation speed (affects direction). Part of a preset
void setSpeed(Real value);
Real getSpeed() const;
/// Precipitation intensity.
void setIntensity(Real value);
Real getIntensity() const;
/// Wind speed and direction
void setWindSpeed(const Ogre::Vector3 &value);
const Ogre::Vector3 getWindSpeed() const;
/** The basic direction for falling precipitation.
*
* This property define the notion of a "falling down" direction.
* By default this is Vector3::NEGATIVE_UNIT_Y. You need to change
* this for a Z-up system.
*/
void setFallingDirection(const Ogre::Vector3 &value) { mFallingDirection = value; }
const Ogre::Vector3 getFallingDirection() const { return mFallingDirection; }
/// Set manual camera speed for all viewports.
void setManualCameraSpeed(const Ogre::Vector3 &value);
/// Set auto camera speed everywhere.o
void setAutoCameraSpeed();
/** Automatically disable compositors when intensity is low.
* A negative value always enable the compositor.
* @note: Ogre::CompositorInstance allocates/frees resources when
* enabling or disabling. That is expensive.
*/
inline void setAutoDisableThreshold (Real value) { mAutoDisableThreshold = value; }
inline Real getAutoDisableThreshold () const { return mAutoDisableThreshold; }
/** Automatically scale camera speed.
*
* This is multiplied per-component with camera speed; manual or
* automatic. It's most useful for automatic camera speed to control
* how much of an effect moving the camera has on rain drop directions.
*
* The components should probably be equal.
*
* Default in Ogre::Vector3::UNIT_SCALE
*/
inline void setCameraSpeedScale (const Ogre::Vector3& value) {
mCameraSpeedScale = value;
}
inline const Ogre::Vector3 getCameraSpeedScale () const {
return mCameraSpeedScale;
}
/** Set an equal camera speed scale in all dimensions.
*/
inline void setCameraSpeedScale (Ogre::Real value) {
setCameraSpeedScale(Ogre::Vector3::UNIT_SCALE * value);
}
/** Update the the precipitation controller.
* @param secondsSinceLastFrame Number of secods since the last frame.
*/
void update(Real secondsSinceLastFrame, Ogre::ColourValue colour);
PrecipitationController(
Ogre::SceneManager *sceneMgr);
~PrecipitationController();
public:
typedef std::map<Ogre::Viewport*, PrecipitationInstance*> ViewportInstanceMap;
ViewportInstanceMap mViewportInstanceMap;
public:
/// Add precipitation to a certain viewport.
PrecipitationInstance* createViewportInstance(Ogre::Viewport* viewport);
/// Remove precipitation from a certain viewport.
void destroyViewportInstance(Ogre::Viewport* viewport);
/// Get per-viewport instance, or null if not created yet.
PrecipitationInstance* getViewportInstance(Ogre::Viewport* viewport);
/// Remove from all attached viewports; clean up.
void destroyAllViewportInstances();
};
/** Per-viewport instance of precipitation.
* This will create and control an ogre::CompositorInstance.
*/
class PrecipitationInstance: private Ogre::CompositorInstance::Listener
{
private:
friend class PrecipitationController;
PrecipitationController* mParent;
Ogre::Viewport* mViewport;
Ogre::CompositorInstance* mCompInst;
Ogre::Camera* mLastCamera;
Ogre::Vector3 mLastCameraPosition;
Ogre::Vector3 mCameraSpeed;
bool mAutoCameraSpeed;
virtual void notifyMaterialSetup(uint pass_id, Ogre::MaterialPtr &mat);
virtual void notifyMaterialRender(uint pass_id, Ogre::MaterialPtr &mat);
/// Called to enforce parameters on a composing material
/// Called from notifyMaterialRender.
void _updateMaterialParams(
const Ogre::MaterialPtr& mat,
const Ogre::Camera* cam,
const Ogre::Vector3& camSpeed);
// Add remove the compositors. Do nothing if already added/removed
void createCompositor ();
void destroyCompositor ();
// Check if the compositor should be enabled
bool shouldBeEnabled () const;
/// Called from the parent's update.
void _update();
public:
inline Ogre::Viewport* getViewport() const { return mViewport; }
inline PrecipitationController* getParent() const { return mParent; }
inline Ogre::CompositorInstance* getCompositorInstance() const { return mCompInst; }
/// Check if camera speed is automatically calculated (default true).
bool getAutoCameraSpeed();
/** Set camera speed to automatic calculation.
*
* @warning: This runs into difficult precission issues. It is
* better to use setManualCameraSpeed.
*/
void setAutoCameraSpeed();
/// Set manual camera speed; disables automatic calculation.
void setManualCameraSpeed(const Ogre::Vector3& value);
/// Get current camera speed. Doesn't include CameraSpeedScale.
const Ogre::Vector3 getCameraSpeed();
PrecipitationInstance(PrecipitationController* parent, Ogre::Viewport* view);
virtual ~PrecipitationInstance();
private:
struct Params {
void setup(Ogre::GpuProgramParametersSharedPtr fpParams);
Ogre::GpuProgramParametersSharedPtr fpParams;
FastGpuParamRef precColor;
FastGpuParamRef intensity;
FastGpuParamRef dropSpeed;
FastGpuParamRef corner1;
FastGpuParamRef corner2;
FastGpuParamRef corner3;
FastGpuParamRef corner4;
FastGpuParamRef deltaX;
FastGpuParamRef deltaY;
} mParams;
};
}
#endif //CAELUM__PRECIPITATION_CONTROLLER_H

@ -0,0 +1,264 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__PRIVATE_PTR_H
#define CAELUM__PRIVATE_PTR_H
#include "CaelumPrerequisites.h"
namespace Caelum
{
/** Default traits for Caelum::PrivatePtr.
*
* This default traits class make PrivatePtr work like std::auto_ptr.
* Other Traits classes can derive from this and only customize some of
* the functions.
*
* @see PrivatePtr
*/
template<class PointedT>
struct DefaultPrivatePtrTraits
{
/// The type of the inner member to hold in PrivatePtr
typedef PointedT* InnerPointerType;
/// Return an InnerPointerType repressenting a null value.
static inline const InnerPointerType getNullValue() {
return 0;
}
/// Convert InnerPointerType to a naked PointedT.
static inline PointedT* getPointer (const InnerPointerType& inner) {
return inner;
}
/// Destroy the inner value (and set null).
static void destroy (InnerPointerType& inner)
{
delete inner;
inner = 0;
}
};
/** Template for smart pointers with strict unique ownership.
* A lot of objects in Ogre are created and destroyed through other
* "Manager" objects. Even though the memory for such objects is never
* actually leaked better lifetime control is frequently useful.
*
* PrivatePtr is very similar in behaviour to std::auto_ptr but tries
* to mimic Ogre::SharedPtr method names. Only one PrivatePtr must exist to
* a certain object at any one time. Assignment and copy construction will
* in fact pass away ownership and set the original PrivatePtr to null.
*
* This very limited functionality makes PrivatePtr very efficient; it should
* have no overhead compared to doing the same thing manually.
*
* PrivatePtr supports customization through a static traits class which
* can customize what happens when the PrivatePtr is destroyed. This makes
* it possible to use PrivatePtr classes for fine control over the lifetime
* of objects which are otherwise managed by an external class.
*
* @see DefaultPrivatePtrTraits
*/
template<class PointedT, typename TraitsT = DefaultPrivatePtrTraits<PointedT> >
class PrivatePtr
{
private:
/// Brings InnerPointerType as a type in this scope.
typedef typename TraitsT::InnerPointerType InnerPointerType;
/// Inner data member.
InnerPointerType mInner;
public:
/** Change the inner value.
* This will destroy the old value and gain ownership of the new value.
*/
void reset (const InnerPointerType& newInner = TraitsT::getNullValue()) {
if (mInner == newInner) {
return;
}
TraitsT::destroy (mInner);
mInner = newInner;
}
InnerPointerType release () {
InnerPointerType result = mInner;
mInner = TraitsT::getNullValue();
return result;
}
/** Constructor; always initialize to 0.
*/
PrivatePtr () { mInner = TraitsT::getNullValue (); }
/** Initializing constructur
*/
PrivatePtr (const InnerPointerType& inner) { mInner = inner; }
/** Non-virtual destructor (don't derive from this).
*/
~PrivatePtr () { setNull(); }
/** Copy constructor; clears right-hand-side.
*/
PrivatePtr (PrivatePtr& rhs)
{
if (&rhs != this) {
this->reset (rhs.mInner);
rhs.mInner = TraitsT::getNullValue ();
}
}
/** Assignment
*/
const PrivatePtr& operator= (PrivatePtr& rhs)
{
if (&rhs != this) {
this->reset (rhs.mInner);
rhs.mInner = TraitsT::getNullValue ();
}
return *this;
}
/// Check if this is null.
bool isNull () const { return mInner == TraitsT::getNullValue (); }
/// Set to null and destroy contents (if any).
void setNull () {
TraitsT::destroy (mInner);
assert(this->isNull());
}
PointedT* getPointer () const { return TraitsT::getPointer (mInner); }
PointedT* get () const { return getPointer (); }
PointedT* operator-> () const { return getPointer (); }
PointedT& operator* () const{ return *getPointer (); }
};
/** PrivatePtr traits for a movable object.
* This kind of pointer will remove the movable from the scene and destroy it.
*/
template<class MovableT>
struct MovableObjectPrivatePtrTraits: public DefaultPrivatePtrTraits<MovableT>
{
typedef MovableT* InnerPointerType;
static void destroy (InnerPointerType& inner)
{
if (inner != 0) {
//Ogre::LogManager::getSingletonPtr ()->logMessage (
// "PrivatePtr: Destroying movable object " + inner->getName ());
inner->_getManager ()->destroyMovableObject (inner);
inner = 0;
}
}
};
typedef PrivatePtr<Ogre::MovableObject, MovableObjectPrivatePtrTraits<Ogre::MovableObject> > PrivateMovableObjectPtr;
typedef PrivatePtr<Ogre::BillboardChain, MovableObjectPrivatePtrTraits<Ogre::BillboardChain> > PrivateBillboardChainPtr;
typedef PrivatePtr<Ogre::BillboardSet, MovableObjectPrivatePtrTraits<Ogre::BillboardSet> > PrivateBillboardSetPtr;
typedef PrivatePtr<Ogre::Entity, MovableObjectPrivatePtrTraits<Ogre::Entity> > PrivateEntityPtr;
typedef PrivatePtr<Ogre::Light, MovableObjectPrivatePtrTraits<Ogre::Light> > PrivateLightPtr;
typedef PrivatePtr<Ogre::ManualObject, MovableObjectPrivatePtrTraits<Ogre::ManualObject> > PrivateManualObjectPtr;
typedef PrivatePtr<Ogre::ParticleSystem, MovableObjectPrivatePtrTraits<Ogre::ParticleSystem> > PrivateParticleSystemPtr;
/** PrivatePtr traits for a scene node.
* Scene nodes are created and destroyed through the scene manager.
* @see PrivatePrivateSceneNodePtr
*/
struct SceneNodePrivatePtrTraits: public DefaultPrivatePtrTraits<Ogre::SceneNode>
{
static void destroy (InnerPointerType& inner)
{
if (inner) {
//Ogre::LogManager::getSingletonPtr ()->logMessage (
// "PrivatePtr: Destroying scene node " + inner->getName ());
inner->getCreator ()->destroySceneNode (inner->getName ());
inner = 0;
}
}
};
typedef PrivatePtr<Ogre::SceneNode, SceneNodePrivatePtrTraits> PrivateSceneNodePtr;
/** PrivatePtr traits for uniquely-owned resources.
*
* All ogre resources are tracked by a resource managed by name and can
* be globally referenced from multiple places. This traits class allows
* you to hold a pointer to a resource which you create and completely
* control.
*
* The best example of this is a cloned material. It is frequently useful
* to create a clone of an existing material and tweak settings for one
* particular usage. After the clone is no longer useful the material must
* be explicitly removed from the MaterialManager. Otherwise an unloaded
* resource handle is leaked.
*
* When the PrivatePtr gets out of scope the resource is removed from the
* manager. In debug mode this will also check that there are no other
* references to the destroyed resource.
*/
template<class PointedT, class InnerT, class ManagerT>
struct PrivateResourcePtrTraits
{
typedef InnerT InnerPointerType;
static const InnerT getNullValue () {
return InnerT();
}
static PointedT* getPointer (const InnerPointerType& inner) {
return inner.getPointer ();
}
static void destroy (InnerPointerType& inner) {
if (!inner.isNull ()) {
//Ogre::LogManager::getSingletonPtr ()->logMessage (
// "PrivateResourcePtrTraits: Destroying owned resource"
// " name=" + inner->getName () +
// " handle=" + Ogre::StringConverter::toString (inner->getHandle ()) );
ManagerT::getSingletonPtr ()->remove (inner->getHandle ());
assert (inner.unique () && "Resource pointer not unique after destruction");
inner.setNull();
}
}
};
typedef PrivatePtr <
Ogre::Material,
PrivateResourcePtrTraits <
Ogre::Material,
Ogre::MaterialPtr,
Ogre::MaterialManager
>
> PrivateMaterialPtr;
typedef PrivatePtr <
Ogre::Mesh,
PrivateResourcePtrTraits <
Ogre::Mesh,
Ogre::MeshPtr,
Ogre::MeshManager
>
> PrivateMeshPtr;
}
#endif // CAELUM__PRIVATE_PTR_H

@ -0,0 +1,119 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__SKYDOME_H
#define CAELUM__SKYDOME_H
#include "CaelumPrerequisites.h"
#include "CameraBoundElement.h"
#include "FastGpuParamRef.h"
#include "PrivatePtr.h"
namespace Caelum
{
/** A sky dome element.
*/
class CAELUM_EXPORT SkyDome : public CameraBoundElement
{
private:
/** Name of the spheric dome resource.
*/
static const Ogre::String SPHERIC_DOME_NAME;
/** Name of the dome material.
*/
static const Ogre::String SKY_DOME_MATERIAL_NAME;
/// Control scene node.
PrivateSceneNodePtr mNode;
/// Sky dome material.
PrivateMaterialPtr mMaterial;
/// Sky dome entity.
PrivateEntityPtr mEntity;
private:
/// True if selected technique has shaders.
bool mShadersEnabled;
/// If haze is enabled.
bool mHazeEnabled;
public:
/** Constructor
* This will setup some nice defaults.
* @param sceneMgr The scene manager where this sky dome will be created.
*/
SkyDome (Ogre::SceneManager *sceneMgr, Ogre::SceneNode *caelumRootNode);
/** Destructor
*/
virtual ~SkyDome ();
/** Sets the sun direction.
@param dir The sun light direction.
*/
void setSunDirection (const Ogre::Vector3& dir);
/// Explicit haze colour.
void setHazeColour (const Ogre::ColourValue& hazeColour);
/// Set the sky color gradients image.
void setSkyGradientsImage (const Ogre::String& gradients);
/// Set the atmosphere depthh gradient image.
void setAtmosphereDepthImage (const Ogre::String& gradients);
/** Enable or disable skydome haze. This makes the sky darker.
* By default haze is disabled.
*/
void setHazeEnabled (bool value);
/// If skydome haze is enabled.
bool getHazeEnabled () const;
void setQueryFlags (uint flags) { mEntity->setQueryFlags (flags); }
uint getQueryFlags () const { return mEntity->getQueryFlags (); }
void setVisibilityFlags (uint flags) { mEntity->setVisibilityFlags (flags); }
uint getVisibilityFlags () const { return mEntity->getVisibilityFlags (); }
public:
/// Handle camera change.
virtual void notifyCameraChanged (Ogre::Camera *cam);
protected:
/// Handle far radius.
virtual void setFarRadius (Ogre::Real radius);
private:
struct Params {
void setup(Ogre::GpuProgramParametersSharedPtr vpParams, Ogre::GpuProgramParametersSharedPtr fpParams);
Ogre::GpuProgramParametersSharedPtr vpParams;
Ogre::GpuProgramParametersSharedPtr fpParams;
FastGpuParamRef sunDirection;
FastGpuParamRef offset;
FastGpuParamRef hazeColour;
} mParams;
};
}
#endif //CAELUM__SKYDOME_H

@ -0,0 +1,175 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__SKYLIGHT_H
#define CAELUM__SKYLIGHT_H
#include "CameraBoundElement.h"
namespace Caelum
{
/** Base class for sky lights (sun and moon).
* Contains a directional light which can be automatically disabled when too dim.
*/
class CAELUM_EXPORT BaseSkyLight : public CameraBoundElement
{
protected:
/// The main directional light.
Ogre::Light *mMainLight;
/// The sun scene node.
Ogre::SceneNode *mNode;
/// Base distance of the light.
float mRadius;
/// The latest normalised sun direction.
Ogre::Vector3 mDirection;
/// Body sphere colour, as set by setBodyColour
Ogre::ColourValue mBodyColour;
/// Sun light colour, as set by setLightColour
Ogre::ColourValue mLightColour;
/// Colour multiplier for light diffuse colour.
Ogre::ColourValue mDiffuseMultiplier;
/// Colour multiplier for light specular colour.
Ogre::ColourValue mSpecularMultiplier;
/** Colour multiplier for ambient light colour.
* No effect, this value is only stored here.
*/
Ogre::ColourValue mAmbientMultiplier;
/// If the light is automatically disabled beneath mAutoDisableThreshold
bool mAutoDisableLight;
/// Threshold beneath which the light is automatically disabled.
Ogre::Real mAutoDisableThreshold;
/// If the light is always disabled. Separate from the mAutoDisable mechanism.
bool mForceDisableLight;
public:
/** Constructor.
@param sceneMgr The scene manager where the lights will be created.
@param caelumRootNode Root node to attach to. Should be bound to the camera.
*/
BaseSkyLight (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode);
/// Destructor.
virtual ~BaseSkyLight () = 0;
/** Updates skylight parameters.
* @param direction Light direction.
* @param lightColour Color for the light source
* @param bodyColour Color to draw the body of the light (whatever that is).
*/
virtual void update (
const Ogre::Vector3& direction,
const Ogre::ColourValue &lightColour,
const Ogre::ColourValue &bodyColour);
/// Retrieves the latest light direction.
const Ogre::Vector3 getLightDirection () const;
/// Set the sun direction.
virtual void setLightDirection (const Ogre::Vector3 &dir);
/// Get current body colour, as set in setBodyColour.
const Ogre::ColourValue getBodyColour () const;
/// Sets the colour to draw the light's body with.
virtual void setBodyColour (const Ogre::ColourValue &colour);
/// Get current light colour, as set in setLightColour.
const Ogre::ColourValue getLightColour () const;
/// Sets the skylight colour.
virtual void setLightColour (const Ogre::ColourValue &colour);
/// Set diffuse multiplier for light colour
void setDiffuseMultiplier (const Ogre::ColourValue &diffuse);
/// Set diffuse multiplier for light colour
const Ogre::ColourValue getDiffuseMultiplier () const;
/// Set specular multiplier for light colour
void setSpecularMultiplier (const Ogre::ColourValue &specular);
/// Set specular multiplier for light colour
const Ogre::ColourValue getSpecularMultiplier () const;
/// Set ambient multiplier for light colour
/// This value is only stored here; the SceneManager is not touched
/// However, CaelumSystem does use this value.
void setAmbientMultiplier (const Ogre::ColourValue &ambient);
/// Set ambient multiplier for light colour
const Ogre::ColourValue getAmbientMultiplier () const;
/// Direct access to the Ogre::Light.
Ogre::Light* getMainLight() const;
/// Check if the light is automatically disabled.
inline bool getAutoDisable() const { return mAutoDisableLight; }
/** Turn on and off auto-disabling of the light when too dim.
* This is off by default. If you set it to true you probably also want to
* set the autoDisableThreshold.
* The "intensity" of the light for the threshold is calculated as the plain sum of r, g and b.
*/
inline void setAutoDisable(bool value) { mAutoDisableLight = value; }
/// Get the auto-disable threshold.
inline Ogre::Real getAutoDisableThreshold() const { return mAutoDisableThreshold; }
/// Set the auto-disable threshold.
inline void setAutoDisableThreshold(Ogre::Real value) { mAutoDisableThreshold = value; }
static const Ogre::Real DEFAULT_AUTO_DISABLE_THRESHOLD;
/// Disable the light by force; without taking intensity into account.
inline void setForceDisable(bool value) { mForceDisableLight = value; }
inline bool getForceDisable() const { return mForceDisableLight; }
virtual void setQueryFlags (uint flags) = 0;
virtual uint getQueryFlags () const = 0;
virtual void setVisibilityFlags (uint flags) = 0;
virtual uint getVisibilityFlags () const = 0;
protected:
/// Handle far radius.
virtual void setFarRadius (Ogre::Real radius);
/// Temporary change main light color
void setMainLightColour(const Ogre::ColourValue &colour);
/// If the light should be enabled for a certain value.
/// This functions takes AutoDisable and such into account.
bool shouldEnableLight(const Ogre::ColourValue &colour);
};
}
#endif // CAELUM__SKYLIGHT_H

@ -0,0 +1,142 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__SUN_H
#define CAELUM__SUN_H
#include "CaelumPrerequisites.h"
#include "CameraBoundElement.h"
#include "SkyLight.h"
#include "PrivatePtr.h"
namespace Caelum
{
class BaseSkyLight;
class SphereSun;
class SpriteSun;
typedef SpriteSun Sun;
/** Class representing the sun as sphere with emissive color on it.
* @deprecated
*/
class CAELUM_EXPORT SphereSun : public BaseSkyLight
{
public:
/// Name of the sun material.
static const Ogre::String SUN_MATERIAL_NAME;
private:
/// Reference to the sun material.
PrivateMaterialPtr mSunMaterial;
/// The sun entity.
PrivateEntityPtr mSunEntity;
public:
/** Constructor.
@param sceneMgr The scene manager where the lights will be created.
*/
SphereSun (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
const Ogre::String &meshName = "sphere.mesh");
/** Destructor.
@note If a sun position model is in use, it will be deleted.
*/
virtual ~SphereSun ();
/** Sets the sun sphere colour.
@param colour The colour used to draw the sun
*/
void setBodyColour (const Ogre::ColourValue &colour);
public:
/// Handle camera change.
virtual void notifyCameraChanged (Ogre::Camera *cam);
virtual void setQueryFlags (uint flags) { mSunEntity->setQueryFlags (flags); }
virtual uint getQueryFlags () const { return mSunEntity->getQueryFlags (); }
virtual void setVisibilityFlags (uint flags) { mSunEntity->setVisibilityFlags (flags); }
virtual uint getVisibilityFlags () const { return mSunEntity->getVisibilityFlags (); }
};
/** Class representing the sun as billboard with texture on it.
*/
class CAELUM_EXPORT SpriteSun : public BaseSkyLight
{
public:
/// Name of the sun material.
static const Ogre::String SUN_MATERIAL_NAME;
protected:
/// The sun material.
PrivateMaterialPtr mSunMaterial;
/// The sun sprite / billboard
PrivateBillboardSetPtr mSunBillboardSet;
/// The sun sprite visible angle
Ogre::Degree mSunTextureAngularSize;
public:
/** Constructor.
@param sceneMgr The scene manager where the lights will be created.
@param sunTextureAngularSize 0.53f is real angular size of Sun and Moon, 3.77f is compatible with SphereSun
*/
SpriteSun (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
const Ogre::String& sunTextureName = "sun_disc.png",
const Ogre::Degree& sunTextureAngularSize = Ogre::Degree(3.77f));
/** Destructor.
@note If a sun position model is in use, it will be deleted.
*/
virtual ~SpriteSun ();
/** Updates the sun material.
@param textureName The new sun texture name.
*/
void setSunTexture (const Ogre::String &textureName);
/** Updates the sun size.
@param sunTextureAngularSize The new sun texture angular size.
*/
void setSunTextureAngularSize(const Ogre::Degree& sunTextureAngularSize);
/** Sets the sun sphere colour.
@param colour The colour used to draw the sun
*/
void setBodyColour (const Ogre::ColourValue &colour);
public:
/// Handle camera change.
virtual void notifyCameraChanged (Ogre::Camera *cam);
virtual void setQueryFlags (uint flags) { mSunBillboardSet->setQueryFlags (flags); }
virtual uint getQueryFlags () const { return mSunBillboardSet->getQueryFlags (); }
virtual void setVisibilityFlags (uint flags) { mSunBillboardSet->setVisibilityFlags (flags); }
virtual uint getVisibilityFlags () const { return mSunBillboardSet->getVisibilityFlags (); }
};
}
#endif // CAELUM__SUN_H

@ -0,0 +1,271 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CAELUM__TYPE_DESCRIPTOR_H
#define CAELUM__TYPE_DESCRIPTOR_H
#include "CaelumPrerequisites.h"
#if CAELUM_TYPE_DESCRIPTORS
#include <typeinfo>
namespace Caelum
{
class ValuePropertyDescriptor;
/** Abstract interface for a type descriptor.
* A type descriptor contains informations about the properties of
* another object. It provides access to a map of strings to
* ValuePropertyDescriptor. All methods are const.
*
* This is not a full reflection mechanism; it doesn't care about
* methods and parameters. It's just a way to access object properties
* in a uniform way.
*
* The list of properties supported by a type descriptor is fixed.
*
* The type descriptor is responsible for the lifetime of
* ValuePropertyDescriptor objects; never the user.
*/
class CAELUM_EXPORT TypeDescriptor
{
public:
virtual ~TypeDescriptor() {};
typedef std::map<String, const ValuePropertyDescriptor*> PropertyMap;
/** Get a property descriptor; or null if not available.
* @param name Name of the property to request.
* @return A pointer to a property descriptor; or null if not available.
*/
virtual const ValuePropertyDescriptor* getPropertyDescriptor (const Ogre::String& name) const = 0;
/** Get a map of all supported properties.
* Returns a complete list of all supported properties; by value.
*/
virtual const std::vector<String> getPropertyNames () const = 0;
/** Get a map of all supported properties.
* Returns a complete list of all supported properties; by value.
*/
virtual const PropertyMap getFullPropertyMap () const = 0;
};
/** Basic property descriptor interface.
*
* A property descriptor provides a uniform way to change the value of a
* simple property. The values are safely wrapped inside an Ogre::Any.
*
* This only works for simple properties which are copied by value. This
* includes floats strings and vectors but not things like Entity pointers.
*
* All public methods are const because the descriptor itself is not
* modified by these methods.
*/
class CAELUM_EXPORT ValuePropertyDescriptor
{
public:
virtual ~ValuePropertyDescriptor() {};
/** If the value of the property can be read (true means write-only).
*
* This is false for write-only properties.
* Write-only properties are generally a bad idea but they are supported.
* Scripting (with .os files) doesn't actually require reading existing values.
*/
virtual bool canGetValue () const = 0;
/// If the value of the property can be set (false means read-only).
virtual bool canSetValue () const = 0;
/** Get the value of the property packed in an Ogre::Any.
*
* @param target Object to fetch the property from. If target is
* not of the correct type behaviour is undefined.
*/
virtual const Ogre::Any getValue (const void* target) const = 0;
/** Set the value of the property packed in an Ogre::Any.
* @param target Object set the property on. If target is not of
* the correct type then behaviour is undefined.
* @param value New value of the property.
*/
virtual void setValue (void* target, const Ogre::Any& value) const = 0;
/// Get std::type_info for the type of the value.
virtual const std::type_info& getValueTypeId () const = 0;
/** Check if this class also implements TypedValuePropertyDescriptor.
*
* If this property returns true then you can static_cast this object to
* a TypedValuePropertyDescriptor<ValueT>; for the appropiate ValueT.
* The appropriate ValueT can be obtained with getValueTypeId.
*/
virtual bool implementsTypedValuePropertyDescriptor () const {
return false;
}
};
/** Variant of ValuePropertyDescriptor which allows faster typed get/set methods.
*/
template<typename ValueT>
class CAELUM_EXPORT TypedValuePropertyDescriptor: public ValuePropertyDescriptor
{
public:
/// Get the property's value.
virtual const ValueT getValueTyped (const void* target) const = 0;
/// Set the property's value.
virtual void setValueTyped (void* target, const ValueT& value) const = 0;
private:
virtual const Ogre::Any getValue (const void* target) const {
return Ogre::Any(this->getValueTyped (target));
}
virtual void setValue (void* target, const Ogre::Any& value) const {
this->setValueTyped (target, Ogre::any_cast<ValueT>(value));
}
virtual const std::type_info& getValueTypeId () const {
return typeid(ValueT);
}
virtual bool implementsTypedValuePropertyDescriptor () const {
return true;
}
};
/** ValuePropertyDescriptor implementation based on function pointers to get/set methods.
*/
template <class TargetT, typename ParamT, typename InParamT = const ParamT&, typename OutParamT = const ParamT>
class AccesorPropertyDescriptor: public TypedValuePropertyDescriptor<ParamT>
{
public:
typedef void(TargetT::*SetFunc)(InParamT);
typedef OutParamT(TargetT::*GetFunc)(void) const;
private:
GetFunc mGetFunc;
SetFunc mSetFunc;
public:
AccesorPropertyDescriptor (GetFunc getFunc, SetFunc setFunc)
{
mGetFunc = getFunc;
mSetFunc = setFunc;
}
virtual bool canGetValue () const {
return mGetFunc != 0;
}
virtual bool canSetValue () const {
return mSetFunc != 0;
}
virtual const ParamT getValueTyped(const void* target) const
{
const TargetT* typedTarget = reinterpret_cast<const TargetT*>(target);
return (typedTarget->*mGetFunc)();
}
virtual void setValueTyped(void* target, const ParamT& value) const
{
TargetT* typedTarget = reinterpret_cast<TargetT*>(target);
(typedTarget->*mSetFunc)(value);
}
};
/** Default implementation of a TypeDescriptor.
* This is a standard implementation of a type descriptor.
*
* It allows direct access to an internal PropertyMap. The user must
* manually fill the map with property descriptors; probably in an init
* method of sorts.
*/
class DefaultTypeDescriptor: public TypeDescriptor
{
public:
DefaultTypeDescriptor ();
virtual ~DefaultTypeDescriptor ();
/** Direct access to the internal property map.
* Get the property map used to implement this type descriptor.
* Once initialisation is complete the property map should no longer
* be modified.
*/
inline PropertyMap& getPropertyMap () { return mPropertyMap; }
/// Add a property. Type descriptor takes ownership.
void add (const Ogre::String& name, const ValuePropertyDescriptor* descriptor);
/// Clear the property map; delete all property descriptors.
void clear ();
/// @copydoc TypeDescriptor::getPropertyDescriptor
virtual const ValuePropertyDescriptor* getPropertyDescriptor (const Ogre::String& name) const;
/// @copydoc TypeDescriptor::getPropertyNames
virtual const std::vector<String> getPropertyNames () const;
/// @copydoc TypeDescriptor::getFullPropertyMap
virtual const PropertyMap getFullPropertyMap () const;
private:
void deleteAllPropertyDescriptors ();
PropertyMap mPropertyMap;
};
/** Standard type descriptors for caelum components.
*
* This class hold pointers to several type descriptors for classes
* inside Caelum. All the pointers are initialize in the contructor and
* properly destroyed in the destructor.
*
* The CaelumPlugin singleton contains a const instance of this class. You
* should fetch that instead of creating a new object; using
* CaelumPlugin::getTypeDescriptorData().
*/
class CAELUM_EXPORT CaelumDefaultTypeDescriptorData
{
private:
void load();
void unload();
public:
CaelumDefaultTypeDescriptorData();
~CaelumDefaultTypeDescriptorData();
DefaultTypeDescriptor* CaelumSystemTypeDescriptor;
DefaultTypeDescriptor* PointStarfieldTypeDescriptor;
DefaultTypeDescriptor* BaseSkyLightTypeDescriptor;
DefaultTypeDescriptor* GroundFogTypeDescriptor;
DefaultTypeDescriptor* PrecipitationTypeDescriptor;
DefaultTypeDescriptor* DepthComposerTypeDescriptor;
DefaultTypeDescriptor* FlatCloudLayerTypeDescriptor;
DefaultTypeDescriptor* SkyDomeTypeDescriptor;
};
}
#endif // CAELUM_TYPE_DESCRIPTORS
#endif // CAELUM__TYPE_DESCRIPTOR_H

@ -0,0 +1,111 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UNIVERSALCLOCK_H
#define UNIVERSALCLOCK_H
#include "CaelumPrerequisites.h"
namespace Caelum {
/** The system's time model.
* This class is responsible of keeping track of current astronomical time
* and syncronising with ogre time.
*
* It maintains a snapshot point: At mCurrentTime == 0 julian day was mJulianDayBase.
* At any time the julian day can be calculated from mCurrentTime and mJulianDayBase.
* This increases precission; mCurrentTime is tracked in seconds while mJulianDayBase
* uses days. It would be silly to track the current time in days.
*/
class CAELUM_EXPORT UniversalClock
{
private:
/// Astronomical julian day at mCurrentTime = 0;
LongReal mJulianDayBase;
/// Seconds since mJulianDayBase.
LongReal mCurrentTime;
/// Seconds since mJulianDayBase at last update.
LongReal mLastUpdateTime;
/// Time scale.
Ogre::Real mTimeScale;
public:
/** Number of seconds per day; exactly 60*60*24.
*/
static const LongReal SECONDS_PER_DAY;
/** Constructor.
*/
UniversalClock ();
/** Sets the time scale.
* @param scale The new time scale. If negative, time will move backwards; 2.0 means double speed...
*/
void setTimeScale (const Ogre::Real scale);
/** Gets the time scale.
* @return The current time scale. Defaults to 1.
*/
Ogre::Real getTimeScale () const;
/** Updates the clock.
* @param time The time to be added to the clock. It will beaffected by the time scale.
*/
void update (const Ogre::Real time);
/** Set the current time as a julian day.
* Set the current time as a julian day, which you build using one
* of the static getJulianDayFromXXX functions.
* Defaults to J2000 (noon january 1st)
*/
void setJulianDay(LongReal value);
/** Set the current time as a gregorian date.
* This is here as an easy to use function.
*/
void setGregorianDateTime(
int year, int month, int day,
int hour, int minute, double second);
/** Get current julian day.
*/
LongReal getJulianDay() const;
/** Get the difference in julian day between this and the last update.
* This is most likely very small and unprecise.
*/
LongReal getJulianDayDifference() const;
/** Get the current julian second (getJulianDay * SECONDS_PER_DAY)
* This is most likely very very large and unprecise.
*/
LongReal getJulianSecond() const;
/** Get the difference in seconds between this and the last update.
* This is what you want for per-frame updates.
*/
LongReal getJulianSecondDifference() const;
};
}
#endif //UNIVERSALCLOCK_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

@ -0,0 +1,141 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
// Returns (exp(x) - 1) / x; avoiding division by 0.
// lim when x -> 0 is 1.
float expdiv(float x) {
if (abs(x) < 0.0001) {
return 1;
} else {
return (exp(x) - 1) / x;
}
}
// Return fogging through a layer of fog which drops exponentially by height.
//
// Standard exp fog with constant density would return (1 - exp(-density * dist)).
// This function assumes a variable density vd = exp(-verticalDecay * h - baseLevel)
// Full computation is exp(density * dist / (h2 - h1) * int(h1, h2, exp(-verticalDecay * (h2 - h1)))).
//
// This will gracefully degrade to standard exp fog in verticalDecay is 0; without throwing NaNs.
float ExpGroundFog (
float dist, float h1, float h2,
float density, float verticalDecay, float baseLevel)
{
float deltaH = (h2 - h1);
return 1 - exp (-density * dist * exp(verticalDecay * (baseLevel - h1)) * expdiv(-verticalDecay * deltaH));
}
// Just like ExpGroundFog with h2 = positive infinity
// When h2 == negative infinity the value is always +1.
float ExpGroundFogInf (
float invSinView, float h1,
float density, float verticalDecay, float baseLevel)
{
return 1 - exp (-density * invSinView * exp(verticalDecay * (baseLevel - h1)) * (1 / verticalDecay));
}
// Entry point for GroundFog vertex program.
void GroundFog_vp
(
float4 position : POSITION,
out float4 oPosition : POSITION,
out float4 worldPos : TEXCOORD0,
uniform float4x4 worldViewProj,
uniform float4x4 world
) {
oPosition = mul(worldViewProj, position);
worldPos = mul(world, position);
}
// Entry point for GroundFog fragment program.
void GroundFog_fp
(
in float3 worldPos : TEXCOORD0,
uniform float3 camPos,
uniform float4 fogColour,
uniform float fogDensity,
uniform float fogVerticalDecay,
uniform float fogGroundLevel,
out float4 oCol : COLOR
) {
float h1 = camPos.y;
float h2 = worldPos.y;
float dist = length(camPos - worldPos);
float fog = ExpGroundFog(
dist, h1, h2,
fogDensity, fogVerticalDecay, fogGroundLevel);
oCol.rgb = fogColour.rgb;
oCol.a = fog;
}
// Entry point for GroundFogDome vertex program.
void GroundFogDome_vp
(
in float4 position : POSITION,
out float4 oPosition : POSITION,
out float3 relPosition : TEXCOORD0,
uniform float4x4 worldViewProj
) {
oPosition = mul(worldViewProj, position);
relPosition = normalize(position.xyz);
}
// Entry point for the GroundFogDome fragment program.
void GroundFogDome_fp
(
in float3 relPosition : TEXCOORD0,
uniform float cameraHeight,
uniform float4 fogColour,
uniform float fogDensity,
uniform float fogVerticalDecay,
uniform float fogGroundLevel,
out float4 oCol : COLOR
) {
// Fog magic.
float invSinView = 1 / (relPosition.y);
float h1 = cameraHeight;
float aFog;
if (fogVerticalDecay < 1e-7) {
// A value of zero of fogVerticalDecay would result in maximum (1) aFog everywhere.
// Output 0 zero instead to disable.
aFog = 0;
} else {
if (invSinView < 0) {
// Gazing into the abyss
aFog = 1;
} else {
aFog = saturate (ExpGroundFogInf (
invSinView, h1,
fogDensity, fogVerticalDecay, fogGroundLevel));
}
}
oCol.a = aFog;
oCol.rgb = fogColour.rgb;
}

@ -0,0 +1,217 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
// Global cloud textures
sampler cloud_shape1 : register(s0);
sampler cloud_shape2 : register(s1);
sampler cloud_detail : register(s2);
// Get cloud layer intensity at a certain point.
float LayeredClouds_intensity
(
in float2 pos,
float cloudMassInvScale,
float cloudDetailInvScale,
float2 cloudMassOffset,
float2 cloudDetailOffset,
float cloudMassBlend,
float cloudDetailBlend,
float cloudCoverageThreshold
)
{
// Calculate the base alpha
float2 finalMassOffset = cloudMassOffset + pos;
float aCloud = lerp(tex2D(cloud_shape1, finalMassOffset * cloudMassInvScale).r,
tex2D(cloud_shape2, finalMassOffset * cloudMassInvScale).r,
cloudMassBlend);
float aDetail = tex2D(cloud_detail, (cloudDetailOffset + pos) * cloudDetailInvScale).r;
aCloud = (aCloud + aDetail * cloudDetailBlend) / (1 + cloudDetailBlend);
return max(0, aCloud - cloudCoverageThreshold);
}
// Entry point for Cloud vertex program.
void LayeredClouds_vp
(
in float4 position : POSITION,
in float2 uv : TEXCOORD0,
uniform float4x4 worldViewProj,
uniform float4x4 worldMatrix,
uniform float3 sunDirection,
out float4 oPosition : POSITION,
out float2 oUv : TEXCOORD0,
out float3 relPosition : TEXCOORD1,
out float sunGlow : TEXCOORD2,
out float4 worldPosition : TEXCOORD3
) {
oPosition = mul(worldViewProj, position);
worldPosition = mul(worldMatrix, position);
oUv = uv;
// This is the relative position, or view direction.
relPosition = normalize (position.xyz);
// Calculate the angle between the direction of the sun and the current
// view direction. This we call "glow" and ranges from 1 next to the sun
// to -1 in the opposite direction.
sunGlow = dot (relPosition, normalize (-sunDirection));
}
float4 OldCloudColor
(
float2 uv,
float3 relPosition,
float sunGlow,
uniform float cloudMassInvScale,
uniform float cloudDetailInvScale,
uniform float2 cloudMassOffset,
uniform float2 cloudDetailOffset,
uniform float cloudMassBlend,
uniform float cloudDetailBlend,
uniform float cloudCoverageThreshold,
uniform float4 sunColour,
uniform float4 fogColour,
uniform float cloudSharpness,
uniform float cloudThickness
) {
// Initialize output.
float4 oCol = float4(1, 1, 1, 0);
// Get cloud intensity.
float intensity = LayeredClouds_intensity
(
uv,
cloudMassInvScale,
cloudDetailInvScale,
cloudMassOffset,
cloudDetailOffset,
cloudMassBlend,
cloudDetailBlend,
cloudCoverageThreshold
);
// Opacity is exponential.
float aCloud = saturate(exp(cloudSharpness * intensity) - 1);
float shine = pow(saturate(sunGlow), 8) / 4;
sunColour.rgb *= 1.5;
float3 cloudColour = fogColour.rgb * (1 - intensity / 3);
float thickness = saturate(0.8 - exp(-cloudThickness * (intensity + 0.2 - shine)));
oCol.rgb = lerp(sunColour.rgb, cloudColour.rgb, thickness);
oCol.a = aCloud;
return oCol;
}
//Converts a color from RGB to YUV color space
//the rgb color is in [0,1] [0,1] [0,1] range
//the yuv color is in [0,1] [-0.436,0.436] [-0.615,0.615] range
float3 YUVfromRGB(float3 col)
{
return float3(dot(col, float3(0.299,0.587,0.114)),
dot(col, float3(-0.14713,-0.28886,0.436)),
dot(col, float3(0.615,-0.51499,-0.10001)));
}
float3 RGBfromYUV(float3 col)
{
return float3(dot(col,float3(1,0,1.13983)),
dot(col,float3(1,-0.39465,-0.58060)),
dot(col,float3(1,2.03211,0)));
}
// Creates a color that has the intensity of col1 and the chrominance of col2
float3 MagicColorMix(float3 col1, float3 col2)
{
return saturate(RGBfromYUV(float3(YUVfromRGB(col1).x, YUVfromRGB(col2).yz)));
}
// Entry point for Cloud fragment program.
void LayeredClouds_fp
(
in float2 uv : TEXCOORD0,
in float3 relPosition : TEXCOORD1,
in float sunGlow : TEXCOORD2,
in float4 worldPosition : TEXCOORD3,
uniform float cloudMassInvScale,
uniform float cloudDetailInvScale,
uniform float2 cloudMassOffset,
uniform float2 cloudDetailOffset,
uniform float cloudMassBlend,
uniform float cloudDetailBlend,
uniform float cloudCoverageThreshold,
uniform float4 sunLightColour,
uniform float4 sunSphereColour,
uniform float4 fogColour,
uniform float4 sunDirection,
uniform float cloudSharpness,
uniform float cloudThickness,
uniform float3 camera_position,
uniform float3 fadeDistMeasurementVector,
uniform float layerHeight,
uniform float cloudUVFactor,
uniform float heightRedFactor,
uniform float nearFadeDist,
uniform float farFadeDist,
out float4 oCol : COLOR
) {
uv *= cloudUVFactor;
oCol = OldCloudColor(
uv, relPosition, sunGlow,
cloudMassInvScale, cloudDetailInvScale,
cloudMassOffset, cloudDetailOffset,
cloudMassBlend, cloudDetailBlend,
cloudCoverageThreshold,
sunLightColour,
fogColour,
cloudSharpness,
cloudThickness);
oCol.r += layerHeight / heightRedFactor;
//float dist = distance(worldPosition.xyz, camera_position.xyz);
float dist = length((worldPosition - camera_position) * fadeDistMeasurementVector);
float aMod = 1;
if (dist > nearFadeDist) {
aMod = saturate(lerp(0, 1, (farFadeDist - dist) / (farFadeDist - nearFadeDist)));
}
float alfa = oCol.a * aMod;
float3 cloudDir = normalize(
float3(worldPosition.x, layerHeight, worldPosition.y) - camera_position);
float angleDiff = saturate(dot(cloudDir, normalize(sunDirection.xyz)));
float3 lCol = lerp(oCol.rgb, MagicColorMix(oCol.rgb, sunSphereColour.rgb), angleDiff);
oCol.rgb = lerp(lCol, oCol.rgb, alfa);
oCol.a = alfa;
}

@ -0,0 +1,61 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
// Get how much of a certain point on the moon is seen (or not) because of the phase.
// uv is the rect position on moon; as seen from the earth.
// phase ranges from 0 to 2
float MoonPhaseFactor(float2 uv, float phase)
{
float alpha = 1.0;
float srefx = uv.x - 0.5;
float refx = abs(uv.x - 0.5);
float refy = abs(uv.y - 0.5);
float refxfory = sqrt(0.25 - refy * refy);
float xmin = -refxfory;
float xmax = refxfory;
float xmin1 = (xmax - xmin) * (phase / 2) + xmin;
float xmin2 = (xmax - xmin) * phase + xmin;
if (srefx < xmin1) {
alpha = 0;
} else if (srefx < xmin2 && xmin1 != xmin2) {
alpha = (srefx - xmin1) / (xmin2 - xmin1);
}
return alpha;
}
void PhaseMoonFP
(
in float2 uv: TEXCOORD0,
uniform float phase,
uniform sampler2D moonDisc: register(s0),
out float4 outcol : COLOR
)
{
outcol = tex2D(moonDisc, uv);
float alpha = MoonPhaseFactor(uv, phase);
// Get luminance from the texture.
float lum = dot(outcol.rgb, float3(0.3333, 0.3333, 0.3333));
//float lum = dot(outcol.rgb, float3(0.3, 0.59, 0.11));
outcol.a = min(outcol.a, lum * alpha);
outcol.rgb /= lum;
}

@ -0,0 +1,77 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
void StarPointVP
(
in float4 in_position : POSITION,
in float3 in_texcoord : TEXCOORD0,
uniform float4x4 worldviewproj_matrix,
// These params are in clipspace; not pixels
uniform float mag_scale,
uniform float mag0_size,
uniform float min_size,
uniform float max_size,
uniform float render_target_flipping,
// width/height
uniform float aspect_ratio,
out float2 out_texcoord : TEXCOORD0,
out float4 out_position : POSITION,
out float4 out_color : COLOR
)
{
float4 in_color = float4(1, 1, 1, 1);
out_position = mul(worldviewproj_matrix, in_position);
out_texcoord = in_texcoord.xy;
float magnitude = in_texcoord.z;
float size = exp(mag_scale * magnitude) * mag0_size;
// Fade below minSize.
float fade = saturate(size / min_size);
out_color = float4(in_color.rgb, fade * fade);
// Clamp size to range.
size = clamp(size, min_size, max_size);
// Splat the billboard on the screen.
out_position.xy +=
out_position.w *
in_texcoord.xy *
float2(size, size * aspect_ratio * render_target_flipping);
}
void StarPointFP
(
in float4 in_color : COLOR,
in float2 in_texcoord : TEXCOORD0,
out float4 out_color : COLOR
)
{
out_color = in_color;
float sqlen = dot(in_texcoord, in_texcoord);
// A gaussian bell of sorts.
out_color.a *= 1.5 * exp(-(sqlen * 8));
}

@ -0,0 +1,193 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
float bias (float b, float x)
{
return pow (x, log (b) / log (0.5));
}
float4 sunlightInscatter
(
float4 sunColour,
float absorption,
float incidenceAngleCos,
float sunlightScatteringFactor
)
{
float scatteredSunlight = bias (sunlightScatteringFactor * 0.5, incidenceAngleCos);
sunColour = sunColour * (1 - absorption) * float4 (0.9, 0.5, 0.09, 1);
return sunColour * scatteredSunlight;
}
float fogExp (float z, float density) {
return 1 - clamp (pow (2.71828, -z * density), 0, 1);
}
void SkyDomeVP
(
in float4 position : POSITION,
in float4 normal : NORMAL,
in float2 uv : TEXCOORD0,
uniform float lightAbsorption,
uniform float4x4 worldViewProj,
uniform float3 sunDirection,
out float4 oPosition : POSITION,
out float4 oCol : COLOR,
out float2 oUv : TEXCOORD0,
out float incidenceAngleCos : TEXCOORD1,
out float y : TEXCOORD2,
out float3 oNormal : TEXCOORD3
)
{
sunDirection = normalize (sunDirection);
normal = normalize (normal);
float cosine = dot (-sunDirection, normal);
incidenceAngleCos = -cosine;
y = -sunDirection.y;
oPosition = mul (worldViewProj, position);
oCol = float4 (1, 1, 1, 1);
oUv = uv;
oNormal = -normal.xyz;
}
void SkyDomeFP
(
float4 col : COLOR,
float2 uv : TEXCOORD0,
float incidenceAngleCos : TEXCOORD1,
float y : TEXCOORD2,
float3 normal : TEXCOORD3,
uniform sampler gradientsMap : register(s0),
uniform sampler1D atmRelativeDepth : register(s1),
uniform float4 hazeColour,
uniform float offset,
out float4 oCol : COLOR
)
{
float4 sunColour = float4 (3, 3, 3, 1);
#ifdef HAZE
float fogDensity = 15;
// Haze amount calculation
float invHazeHeight = 100;
float haze = fogExp (pow (clamp (1 - normal.y, 0, 1), invHazeHeight), fogDensity);
#endif // HAZE
// Pass the colour
oCol = tex2D (gradientsMap, uv + float2 (offset, 0)) * col;
// Sunlight inscatter
if (incidenceAngleCos > 0)
{
float sunlightScatteringFactor = 0.05;
float sunlightScatteringLossFactor = 0.1;
float atmLightAbsorptionFactor = 0.1;
oCol.rgb += sunlightInscatter (
sunColour,
clamp (atmLightAbsorptionFactor * (1 - tex1D (atmRelativeDepth, y).r), 0, 1),
clamp (incidenceAngleCos, 0, 1),
sunlightScatteringFactor).rgb * (1 - sunlightScatteringLossFactor);
}
#ifdef HAZE
// Haze pass
hazeColour.a = 1;
oCol = oCol * (1 - haze) + hazeColour * haze;
#endif // HAZE
}
void HazeVP
(
in float4 position : POSITION,
in float4 normal : NORMAL,
uniform float4x4 worldViewProj,
uniform float4 camPos,
uniform float3 sunDirection,
out float4 oPosition : POSITION,
out float haze : TEXCOORD0,
out float2 sunlight : TEXCOORD1
)
{
sunDirection = normalize (sunDirection);
oPosition = mul(worldViewProj, position);
haze = length (camPos - position);
sunlight.x = dot (-sunDirection, normalize (position - camPos));
sunlight.y = -sunDirection.y;
}
void HazeFP
(
in float haze : TEXCOORD0,
in float2 sunlight : TEXCOORD1,
uniform sampler1D atmRelativeDepth : register(s0),
uniform sampler2D gradientsMap : register (s1),
uniform float4 fogColour,
out float4 oCol : COLOR
)
{
float incidenceAngleCos = sunlight.x;
float y = sunlight.y;
float4 sunColour = float4 (3, 2.5, 1, 1);
// Factor determining the amount of light lost due to absorption
float atmLightAbsorptionFactor = 0.1;
float fogDensity = 15;
haze = fogExp (haze * 0.005, atmLightAbsorptionFactor);
// Haze amount calculation
float invHazeHeight = 100;
float hazeAbsorption = fogExp (pow (1 - y, invHazeHeight), fogDensity);
float4 hazeColour;
hazeColour = fogColour;
if (incidenceAngleCos > 0) {
// Factor determining the amount of scattering for the sun light
float sunlightScatteringFactor = 0.1;
// Factor determining the amount of sun light intensity lost due to scattering
float sunlightScatteringLossFactor = 0.3;
float4 sunlightInscatterColour = sunlightInscatter (
sunColour,
clamp ((1 - tex1D (atmRelativeDepth, y).r) * hazeAbsorption, 0, 1),
clamp (incidenceAngleCos, 0, 1),
sunlightScatteringFactor) * (1 - sunlightScatteringLossFactor);
hazeColour.rgb =
hazeColour.rgb * (1 - sunlightInscatterColour.a) +
sunlightInscatterColour.rgb * sunlightInscatterColour.a * haze;
}
oCol = hazeColour;
oCol.a = haze;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

@ -0,0 +1,253 @@
//
// This file is part of Caelum.
// See http://www.ogre3d.org/wiki/index.php/Caelum
//
// Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
// Caelum is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Caelum 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
#ifdef EXP_GROUND_FOG
// Returns (exp(x) - 1) / x; avoiding division by 0.
// lim when x -> 0 is 1.
float expdiv(float x) {
if (abs(x) < 0.0001) {
return 1;
} else {
return (exp(x) - 1) / x;
}
}
// Return fogging through a layer of fog which drops exponentially by height.
//
// Standard exp fog with constant density would return (1 - exp(-density * dist)).
// This function assumes a variable density vd = exp(-verticalDecay * h - baseLevel)
// Full computation is exp(density * dist / (h2 - h1) * int(h1, h2, exp(-verticalDecay * (h2 - h1)))).
//
// This will gracefully degrade to standard exp fog in verticalDecay is 0; without throwing NaNs.
float ExpGroundFog (
float dist, float h1, float h2,
float density, float verticalDecay, float baseLevel)
{
float deltaH = (h2 - h1);
return 1 - exp (-density * dist * exp(verticalDecay * (baseLevel - h1)) * expdiv(-verticalDecay * deltaH));
}
#endif // EXP_GROUND_FOG
#ifdef SKY_DOME_HAZE
float bias (float b, float x)
{
return pow (x, log (b) / log (0.5));
}
float4 sunlightInscatter
(
float4 sunColour,
float absorption,
float incidenceAngleCos,
float sunlightScatteringFactor
)
{
float scatteredSunlight = bias (sunlightScatteringFactor * 0.5, incidenceAngleCos);
sunColour = sunColour * (1 - absorption) * float4 (0.9, 0.5, 0.09, 1);
return sunColour * scatteredSunlight;
}
float fogExp (float z, float density) {
return 1 - clamp (pow (2.71828, -z * density), 0, 1);
}
uniform sampler1D atmRelativeDepth : register(HAZE_DEPTH_TEXTURE);
float4 CalcHaze
(
float3 worldPos,
float3 worldCamPos,
float3 hazeColour,
float3 sunDirection
)
{
float haze = length (worldCamPos - worldPos);
float incidenceAngleCos = dot (-sunDirection, normalize (worldPos - worldCamPos));
float y = -sunDirection.y;
float4 sunColour = float4 (3, 2.5, 1, 1);
// Factor determining the amount of light lost due to absorption
float atmLightAbsorptionFactor = 0.1;
float fogDensity = 15;
haze = fogExp (haze * 0.005, atmLightAbsorptionFactor);
// Haze amount calculation
float invHazeHeight = 100;
float hazeAbsorption = fogExp (pow (1 - y, invHazeHeight), fogDensity);
if (incidenceAngleCos > 0) {
// Factor determining the amount of scattering for the sun light
float sunlightScatteringFactor = 0.1;
// Factor determining the amount of sun light intensity lost due to scattering
float sunlightScatteringLossFactor = 0.3;
float4 sunlightInscatterColour = sunlightInscatter (
sunColour,
clamp ((1 - tex1D (atmRelativeDepth, y).r) * hazeAbsorption, 0, 1),
clamp (incidenceAngleCos, 0, 1),
sunlightScatteringFactor) * (1 - sunlightScatteringLossFactor);
hazeColour =
hazeColour * (1 - sunlightInscatterColour.a) +
sunlightInscatterColour.rgb * sunlightInscatterColour.a * haze;
}
return float4(hazeColour.rgb, haze);
}
#endif // SKY_DOME_HAZE
void MainFP
(
in float2 screenPos : TEXCOORD0,
uniform float4x4 invViewProjMatrix,
uniform float4 worldCameraPos,
#if EXP_GROUND_FOG
uniform float groundFogDensity,
uniform float groundFogVerticalDecay,
uniform float groundFogBaseLevel,
uniform float4 groundFogColour,
#endif // EXP_GROUND_FOG
#if SKY_DOME_HAZE
uniform float3 hazeColour,
uniform float3 sunDirection,
#endif // SKY_DOME_HAZE
sampler screenTexture: register(s0),
sampler depthTexture: register(s1),
out float4 outColor : COLOR
)
{
float4 inColor = tex2D(screenTexture, screenPos);
float inDepth = tex2D(depthTexture, screenPos).r;
// Build normalized device coords; after the perspective divide.
//float4 devicePos = float4(1 - screenPos.x * 2, screenPos.y * 2 - 1, inDepth, 1);
//float4 devicePos = float4(screenPos.x * 2 - 1, 1 - screenPos.y * 2, 2 * inDepth - 1, 1);
float4 devicePos = float4(screenPos.x * 2 - 1, 1 - screenPos.y * 2, inDepth, 1);
// Go back from device to world coordinates.
float4 worldPos = mul(invViewProjMatrix, devicePos);
// Now undo the perspective divide and go back to "normal" space.
worldPos /= worldPos.w;
float4 color = inColor;
#if DEBUG_DEPTH_RENDER
//color = abs(float4(inDepth, inDepth, inDepth, 1));
color = worldPos * float4(0.001, 0.01, 0.001, 1);
#endif // DEBUG_DEPTH_RENDER
#if EXP_GROUND_FOG
// Ye olde ground fog.
float h1 = worldCameraPos.y;
float h2 = worldPos.y;
float dist = length(worldCameraPos - worldPos);
float fogFactor = ExpGroundFog(
dist, h1, h2,
groundFogDensity, groundFogVerticalDecay, groundFogBaseLevel);
color = lerp(color, groundFogColour, fogFactor);
#endif // EXP_GROUND_FOG
#if SKY_DOME_HAZE
float4 hazeValue = CalcHaze (
worldPos.xyz,
worldCameraPos.xyz,
hazeColour,
sunDirection);
color.rgb = lerp(color.rgb, hazeValue.rgb, hazeValue.a);
#endif // SKY_DOME_HAZE
outColor = color;
}
void DepthRenderVP
(
float4 inPos : POSITION,
uniform float4x4 wvpMatrix,
out float4 magic : TEXCOORD0,
out float4 outPos : POSITION
)
{
// Standard transform.
outPos = mul(wvpMatrix, inPos);
// Depth buffer is z/w.
// Let the GPU lerp the components of outPos.
magic = outPos;
}
void DepthRenderFP
(
in float4 magic : TEXCOORD0,
out float4 output : COLOR
)
{
output = float4(magic.z / magic.w);
//output = float4(magic.xy / magic.w, 1, 1);
}
void DepthRenderAlphaRejectionVP
(
float4 inPos : POSITION,
float4 inTexcoord : TEXCOORD0,
uniform float4x4 wvpMatrix,
out float4 outTexcoord : TEXCOORD0,
out float4 magic : TEXCOORD1,
out float4 outPos : POSITION
)
{
// Standard transform.
outPos = mul(wvpMatrix, inPos);
// Depth buffer is z/w.
// Let the GPU lerp the components of outPos.
magic = outPos;
outTexcoord = inTexcoord;
}
void DepthRenderAlphaRejectionFP
(
in float4 texcoord : TEXCOORD0,
in float4 magic : TEXCOORD1,
sampler mainTex: register(s0),
out float4 output : COLOR
)
{
float4 texvalue = tex2D(mainTex, texcoord.xy);
// texvalue.a = sin(100 * texcoord.x) + sin(100 * texcoord.y);
output = float4(float3(magic.z / magic.w), texvalue.a);
}

@ -0,0 +1,139 @@
//
// This file is part of Caelum.
// See http://www.ogre3d.org/wiki/index.php/Caelum
//
// Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
// Caelum is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Caelum 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
compositor Caelum/DepthComposer_DebugDepthRender
{
technique
{
texture rt0 target_width target_height PF_A8R8G8B8
target rt0
{
input previous
}
target_output
{
input none
pass render_quad
{
material Caelum/DepthComposer_DebugDepthRender
input 0 rt0
}
}
}
}
compositor Caelum/DepthComposer_Dummy
{
technique
{
texture rt0 target_width target_height PF_A8R8G8B8
target rt0
{
input previous
}
target_output
{
input none
pass render_quad
{
material Caelum/DepthComposer_Dummy
input 0 rt0
}
}
}
}
compositor Caelum/DepthComposer_ExpGroundFog
{
technique
{
texture rt0 target_width target_height PF_A8R8G8B8
target rt0
{
input previous
}
target_output
{
input none
pass render_quad
{
material Caelum/DepthComposer_ExpGroundFog
input 0 rt0
}
}
}
}
compositor Caelum/DepthComposer_SkyDomeHaze
{
technique
{
texture rt0 target_width target_height PF_A8R8G8B8
target rt0
{
input previous
}
target_output
{
input none
pass render_quad
{
material Caelum/DepthComposer_SkyDomeHaze
input 0 rt0
}
}
}
}
compositor Caelum/DepthComposer_SkyDomeHaze_ExpGroundFog
{
technique
{
texture rt0 target_width target_height PF_A8R8G8B8
target rt0
{
input previous
}
target_output
{
input none
pass render_quad
{
material Caelum/DepthComposer_SkyDomeHaze_ExpGroundFog
input 0 rt0
}
}
}
}

@ -0,0 +1,302 @@
//
// This file is part of Caelum.
// See http://www.ogre3d.org/wiki/index.php/Caelum
//
// Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
// Caelum is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Caelum 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
fragment_program Caelum/DepthComposerFP_Dummy cg
{
source DepthComposer.cg
entry_point MainFP
profiles ps_3_0 arbfp1
default_params
{
}
}
fragment_program Caelum/DepthComposerFP_DebugDepthRender cg
{
source DepthComposer.cg
entry_point MainFP
profiles ps_3_0 arbfp1
compile_arguments -DDEBUG_DEPTH_RENDER=1
default_params
{
param_named invViewProjMatrix float4x4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
}
}
fragment_program Caelum/DepthComposerFP_ExpGroundFog cg
{
source DepthComposer.cg
entry_point MainFP
profiles ps_3_0 arbfp1
compile_arguments -DEXP_GROUND_FOG=1
default_params
{
param_named invViewProjMatrix float4x4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
param_named worldCameraPos float4 0 0 0 0
param_named groundFogDensity float 0.1
param_named groundFogVerticalDecay float 0.2
param_named groundFogBaseLevel float 5
param_named groundFogColour float4 1 0 1 1
}
}
fragment_program Caelum/DepthComposerFP_SkyDomeHaze cg
{
source DepthComposer.cg
entry_point MainFP
profiles ps_3_0 arbfp1
compile_arguments -DSKY_DOME_HAZE=1 -DHAZE_DEPTH_TEXTURE=s2
default_params
{
param_named invViewProjMatrix float4x4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
param_named worldCameraPos float4 0 0 0 0
param_named sunDirection float3 0 1 0
param_named hazeColour float3 0.1 0.2 0.6
}
}
fragment_program Caelum/DepthComposerFP_SkyDomeHaze_ExpGroundFog cg
{
source DepthComposer.cg
entry_point MainFP
profiles ps_3_0 arbfp1
compile_arguments -DEXP_GROUND_FOG=1 -DSKY_DOME_HAZE=1 -DHAZE_DEPTH_TEXTURE=s2
default_params
{
param_named invViewProjMatrix float4x4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
param_named worldCameraPos float4 0 0 0 0
param_named sunDirection float3 0 1 0
param_named hazeColour float3 0.1 0.2 0.6
param_named groundFogDensity float 0.1
param_named groundFogVerticalDecay float 0.2
param_named groundFogBaseLevel float 5
param_named groundFogColour float4 1 0 1 1
}
}
material Caelum/DepthRender
{
technique Default
{
pass Main
{
// This is required!
depth_write on
depth_check on
vertex_program_ref Caelum/DepthRenderVP
{
}
fragment_program_ref Caelum/DepthRenderFP
{
}
}
}
}
// Material for rendering depth of an alpha-rejection material.
//
// Unlike the regular Caelum/DepthRender this also outputs alpha from a texture.
// The shaders (VP/FP) can be trivially used in more complex materials.
material Caelum/DepthRenderAlphaRejection
{
technique Default
{
pass Main
{
depth_write on
depth_check on
vertex_program_ref Caelum/DepthRenderAlphaRejectionVP
{
}
fragment_program_ref Caelum/DepthRenderAlphaRejectionFP
{
}
alpha_rejection greater 128
texture_unit Main
{
}
}
}
}
material Caelum/DepthComposer_Dummy
{
technique Default
{
pass Main
{
vertex_program_ref Caelum/MinimalCompositorVP
{
}
fragment_program_ref Caelum/DepthComposerFP_Dummy
{
}
texture_unit Screen
{
filtering none
}
texture_unit Depth
{
filtering none
}
}
}
}
material Caelum/DepthComposer_DebugDepthRender
{
technique Default
{
pass Main
{
vertex_program_ref Caelum/MinimalCompositorVP
{
}
fragment_program_ref Caelum/DepthComposerFP_DebugDepthRender
{
}
texture_unit Screen
{
filtering none
}
texture_unit Depth
{
filtering none
}
}
}
}
material Caelum/DepthComposer_ExpGroundFog
{
technique Default
{
pass Main
{
vertex_program_ref Caelum/MinimalCompositorVP
{
}
fragment_program_ref Caelum/DepthComposerFP_ExpGroundFog
{
}
texture_unit Screen
{
filtering none
}
texture_unit Depth
{
filtering none
}
}
}
}
material Caelum/DepthComposer_SkyDomeHaze
{
technique Default
{
pass Main
{
vertex_program_ref Caelum/MinimalCompositorVP
{
}
fragment_program_ref Caelum/DepthComposerFP_SkyDomeHaze
{
}
texture_unit Screen
{
filtering none
}
texture_unit Depth
{
filtering none
}
texture_unit AtmosphereDepth
{
texture AtmosphereDepth.png 1d
tex_address_mode clamp
}
}
}
}
material Caelum/DepthComposer_SkyDomeHaze_ExpGroundFog
{
technique Default
{
pass Main
{
vertex_program_ref Caelum/MinimalCompositorVP
{
}
fragment_program_ref Caelum/DepthComposerFP_SkyDomeHaze_ExpGroundFog
{
}
texture_unit Screen
{
filtering none
}
texture_unit Depth
{
filtering none
}
texture_unit AtmosphereDepth
{
texture AtmosphereDepth.png 1d
filtering bilinear
tex_address_mode clamp
}
}
}
}

@ -0,0 +1,57 @@
//
// This file is part of Caelum.
// See http://www.ogre3d.org/wiki/index.php/Caelum
//
// Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
// Caelum is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Caelum 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
vertex_program Caelum/DepthRenderVP cg
{
source DepthComposer.cg
entry_point DepthRenderVP
profiles vs_2_0 arbvp1
default_params
{
param_named_auto wvpMatrix worldviewproj_matrix
}
}
fragment_program Caelum/DepthRenderFP cg
{
source DepthComposer.cg
entry_point DepthRenderFP
profiles ps_3_0 fp40 arbfp1
}
vertex_program Caelum/DepthRenderAlphaRejectionVP cg
{
source DepthComposer.cg
entry_point DepthRenderAlphaRejectionVP
profiles vs_2_0 arbvp1
default_params
{
param_named_auto wvpMatrix worldviewproj_matrix
}
}
fragment_program Caelum/DepthRenderAlphaRejectionFP cg
{
source DepthComposer.cg
entry_point DepthRenderAlphaRejectionFP
profiles ps_3_0 fp40 arbfp1
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -0,0 +1,71 @@
//
//This file is part of Caelum.
//See http://www.ogre3d.org/wiki/index.php/Caelum
//
//Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
//
//Caelum is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//Caelum 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 Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
// Sample base material for using CaelumGroundFog.
material CaelumGroundFogBase
{
technique Default
{
pass Main
{
fog_override true none
}
// Fog pass
pass CaelumGroundFog
{
vertex_program_ref CaelumGroundFogVP
{
}
fragment_program_ref CaelumGroundFogFP
{
}
scene_blend alpha_blend
}
}
}
material CaelumGroundFogDome
{
receive_shadows off
technique
{
pass
{
lighting off
depth_check off
depth_write off
fog_override true
scene_blend alpha_blend
cull_hardware none
vertex_program_ref CaelumGroundFogDomeVP
{
}
fragment_program_ref CaelumGroundFogDomeFP
{
}
}
}
}

@ -0,0 +1,83 @@
//
//This file is part of Caelum.
//See http://www.ogre3d.org/wiki/index.php/Caelum
//
//Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
//
//Caelum is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//Caelum 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 Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
vertex_program CaelumGroundFogVP cg
{
source CaelumGroundFog.cg
entry_point GroundFog_vp
profiles vs_2_x arbvp1 vp30
default_params
{
param_named_auto worldViewProj worldviewproj_matrix
param_named_auto world world_matrix
}
}
fragment_program CaelumGroundFogFP cg
{
source CaelumGroundFog.cg
entry_point GroundFog_fp
profiles ps_2_x arbfp1 fp30
default_params
{
param_named_auto camPos camera_position
// _auto seems wrong here, since the fog formulas are different than
// for standard exp fog.
param_named fogDensity float 0
param_named fogVerticalDecay float 0
param_named fogGroundLevel float 0
param_named fogColour float4 0 0 0 0
}
}
vertex_program CaelumGroundFogDomeVP cg
{
source CaelumGroundFog.cg
entry_point GroundFogDome_vp
profiles vs_2_0 arbvp1
default_params
{
param_named_auto worldViewProj worldviewproj_matrix
}
}
fragment_program CaelumGroundFogDomeFP cg
{
source CaelumGroundFog.cg
entry_point GroundFogDome_fp
profiles ps_2_0 arbfp1
default_params
{
// Fog parameters.
param_named fogColour float4 0 0 0 0
param_named fogDensity float 0
param_named fogVerticalDecay float 0
param_named fogGroundLevel float 0
// Send camera height. We can't send camera_position because
// the entity is always moved with the camera. Joy.
param_named cameraHeight float 0
}
}

@ -0,0 +1,44 @@
//
//This file is part of Caelum.
//See http://www.ogre3d.org/wiki/index.php/Caelum
//
//Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
//
//Caelum is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//Caelum 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 Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
vertex_program CaelumHazeVP cg
{
source CaelumSkyDome.cg
entry_point HazeVP
profiles vs_2_0 arbvp1 vp30
default_params
{
param_named_auto worldViewProj worldviewproj_matrix
param_named_auto camPos camera_position
}
}
fragment_program CaelumHazeFP cg
{
source CaelumSkyDome.cg
entry_point HazeFP
profiles ps_2_0 arbfp1 fp30
default_params
{
param_named_auto fogColour fog_colour
}
}

@ -0,0 +1,132 @@
//
//This file is part of Caelum.
//See http://www.ogre3d.org/wiki/index.php/Caelum
//
//Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
//
//Caelum is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//Caelum 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 Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
vertex_program CaelumLayeredCloudsVP cg
{
source CaelumLayeredClouds.cg
entry_point LayeredClouds_vp
profiles vs_3_0 vp40 arbvp1
default_params
{
param_named_auto worldViewProj worldviewproj_matrix
param_named_auto worldMatrix world_matrix
param_named sunDirection float3 -1 -1 0
}
}
fragment_program CaelumLayeredCloudsFP cg
{
source CaelumLayeredClouds.cg
entry_point LayeredClouds_fp
profiles ps_3_0 fp40 arbfp1
default_params
{
// Caelum sky properties
param_named sunLightColour float4 1 1 1 1
param_named sunSphereColour float4 1 1 1 1
param_named sunDirection float4 1 1 1 1
// Fog colour; used as the base cloud colour.
param_named fogColour float4 0 0 0 0
// The inverse of the cloud forms scale
param_named cloudMassInvScale float 1.2
// The inverse of the cloud details scale
param_named cloudDetailInvScale float 4.8
// Cloud mass offset
param_named cloudMassOffset float2 0 0
// Cloud details offset
param_named cloudDetailOffset float2 0.5 0.5
// Blending factor between Cloud1 and Cloud2
param_named cloudMassBlend float 0.9
// Cloud detail weight.
param_named cloudDetailBlend float 0.5
// Cloud coverage, between 0 and 1
param_named cloudCoverageThreshold float 0.9
// Cloud sharpness. Lower values result in softer clouds.
param_named cloudSharpness float 4
// Cloud thickness. Bigger values results in darker clouds.
param_named cloudThickness float 3
param_named_auto camera_position camera_position
param_named layerHeight float 0
param_named cloudUVFactor float -1
param_named heightRedFactor float -1
param_named nearFadeDist float -1
param_named farFadeDist float -1
param_named fadeDistMeasurementVector float3 0 1 1
}
}
material CaelumLayeredClouds
{
technique
{
pass
{
lighting off
depth_check on
depth_write off
scene_blend alpha_blend
fog_override true
cull_hardware none
vertex_program_ref CaelumLayeredCloudsVP
{
}
fragment_program_ref CaelumLayeredCloudsFP
{
}
texture_unit Cloud1
{
texture noise1.dds
filtering trilinear
tex_coord_set 0
}
texture_unit Cloud2
{
texture noise2.dds
filtering trilinear
tex_coord_set 1
}
texture_unit Detail
{
texture noise4.dds
tex_coord_set 2
}
}
}
}

@ -0,0 +1,39 @@
//
// This file is part of Caelum.
// See http://www.ogre3d.org/wiki/index.php/Caelum
//
// Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
// Caelum is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Caelum 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
// Fixed function does not always work.
// This is a the minimal compositor VP required.
void MinimalCompositorVP
(
in float4 in_pos : POSITION,
uniform float4x4 worldviewproj_matrix,
out float2 out_uv0 : TEXCOORD0,
out float4 out_pos : POSITION
)
{
// Use standard transform.
out_pos = mul(worldviewproj_matrix, in_pos);
// Convert to image-space
in_pos.xy = sign(in_pos.xy);
out_uv0 = (float2(in_pos.x, -in_pos.y) + 1.0f) * 0.5f;
}

@ -0,0 +1,31 @@
//
// This file is part of Caelum.
// See http://www.ogre3d.org/wiki/index.php/Caelum
//
// Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
// Caelum is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Caelum 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
vertex_program Caelum/MinimalCompositorVP cg
{
source MinimalCompositorVP.cg
entry_point MinimalCompositorVP
profiles vs_1_1 arbvp1
default_params
{
param_named_auto worldviewproj_matrix worldviewproj_matrix
}
}

@ -0,0 +1,80 @@
//
//This file is part of Caelum.
//See http://www.ogre3d.org/wiki/index.php/Caelum
//
//Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
//Caelum is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//Caelum 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 Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
vertex_program Caelum/StarPointVP cg
{
source CaelumPointStarfield.cg
entry_point StarPointVP
profiles vs_2_0 arbvp1 vp30
default_params
{
param_named_auto worldviewproj_matrix worldviewproj_matrix
param_named_auto render_target_flipping render_target_flipping
// Default parameters only here to quiet ogre.
param_named mag_scale float -1
param_named mag0_size float -1
param_named min_size float -1
param_named max_size float -1
param_named aspect_ratio float -1
}
}
fragment_program Caelum/StarPointFP cg
{
source CaelumPointStarfield.cg
entry_point StarPointFP
profiles ps_2_0 arbfp1 fp30
default_params
{
}
}
material Caelum/StarPoint
{
receive_shadows off
technique
{
pass
{
depth_check off
depth_write off
vertex_program_ref Caelum/StarPointVP
{
}
fragment_program_ref Caelum/StarPointFP
{
}
scene_blend alpha_blend
// Works with default culling:
cull_hardware clockwise
// Override Direct3D shader fog.
fog_override true none
}
}
}

@ -0,0 +1,102 @@
//
// This file is part of Caelum.
// See http://www.ogre3d.org/wiki/index.php/Caelum
//
// Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
// Caelum is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Caelum 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
sampler scene: register(s0);
sampler samplerPrec: register(s1);
uniform float intensity;
uniform float4 ambient_light_colour;
// - - corner
uniform float4 corner1;
// + - corner
uniform float4 corner2;
// - + corner
uniform float4 corner3;
// + + corner
uniform float4 corner4;
// The x and y coordinal deviations for all 3 layers of precipitation
uniform float4 deltaX;
uniform float4 deltaY;
uniform float4 precColor;
// Cartesian to cylindrical coordinates
float2 CylindricalCoordinates(float4 dir) {
float R = 0.5;
float2 res;
//cubical root is used to counteract top/bottom circle effect
dir *= R / pow(length(dir.xz), 0.33);
res.y = -dir.y;
res.x = -atan2(dir.z, dir.x);
return res;
}
// Returns alpha value of a precipitation
// view_direction is the direction vector resulting from the eye direction,wind direction and possibly other factors
float Precipitation
(
float2 cCoords,
float intensity,
float2 delta
) {
cCoords -= delta;
float4 raincol = tex2D(samplerPrec, cCoords);
return (raincol.g<intensity) ? (raincol.r) : 1;
}
//main entry point
void MainFP
(
in float2 scr_pos : TEXCOORD0,
out float4 out_colour : COLOR
) {
float4 eye = lerp (
lerp(corner1, corner3, scr_pos.y),
lerp(corner2, corner4, scr_pos.y),
scr_pos.x ) ;
float4 scenecol = tex2D(scene, scr_pos);
float2 cCoords = CylindricalCoordinates(eye);
float prec1 = Precipitation(cCoords, intensity/4, float2(deltaX.x,deltaY.x));
float prec2 = Precipitation(cCoords, intensity/4, float2(deltaX.y,deltaY.y));
float prec3 = Precipitation(cCoords, intensity/4, float2(deltaX.z,deltaY.z));
float prec = min( min (prec1, prec2), prec3);
out_colour = lerp(precColor, scenecol, prec );
}
void MainVP
(
in float4 in_pos : POSITION,
uniform float4x4 worldviewproj_matrix,
out float2 out_uv0 : TEXCOORD0,
out float4 out_pos : POSITION
)
{
// Use standard transform.
out_pos = mul(worldviewproj_matrix, in_pos);
// Convert to image-space
in_pos.xy = sign(in_pos.xy);
out_uv0 = (float2(in_pos.x, -in_pos.y) + 1.0f) * 0.5f;
}

@ -0,0 +1,44 @@
//
// This file is part of Caelum.
// See http://www.ogre3d.org/wiki/index.php/Caelum
//
// Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
// Caelum is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Caelum 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
compositor Caelum/PrecipitationCompositor
{
technique
{
texture rt0 target_width target_height PF_A8R8G8B8
target rt0
{
input previous
}
target_output
{
input none
pass render_quad
{
// Renders a fullscreen quad with a material
material Caelum/PrecipitationMaterial
input 0 rt0
}
}
}
}

@ -0,0 +1,69 @@
//
// This file is part of Caelum.
// See http://www.ogre3d.org/wiki/index.php/Caelum
//
// Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
// Caelum is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Caelum 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
fragment_program Caelum/PrecipitationFP cg
{
source Precipitation.cg
entry_point MainFP
profiles ps_3_0 fp40 arbfp1
default_params
{
}
}
vertex_program Caelum/PrecipitationVP cg
{
source Precipitation.cg
entry_point MainVP
profiles vs_3_0 vp40 arbvp1
default_params
{
param_named_auto worldviewproj_matrix worldviewproj_matrix
}
}
material Caelum/PrecipitationMaterial
{
technique Default
{
pass Main
{
vertex_program_ref Caelum/PrecipitationVP
{
}
fragment_program_ref Caelum/PrecipitationFP
{
}
texture_unit Scene
{
}
texture_unit Precipitation
{
texture precipitation_drizzle.png
filtering trilinear
}
}
}
}

@ -0,0 +1,119 @@
//
//This file is part of Caelum.
//See http://www.ogre3d.org/wiki/index.php/Caelum
//
//Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
//
//Caelum is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//Caelum 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 Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
fragment_program CaelumSkyDomeFP cg
{
source CaelumSkyDome.cg
entry_point SkyDomeFP
compile_arguments -DHAZE
profiles ps_2_0 arbfp1
default_params
{
// Caelum sky properties
param_named offset float 0
param_named hazeColour float4 0 0 0 0
}
}
fragment_program CaelumSkyDomeFP_NoHaze cg
{
source CaelumSkyDome.cg
entry_point SkyDomeFP
profiles ps_2_0 arbfp1
default_params
{
// Caelum sky properties
param_named offset float 0
}
}
vertex_program CaelumSkyDomeVP cg
{
source CaelumSkyDome.cg
entry_point SkyDomeVP
profiles vs_2_0 arbvp1
default_params
{
param_named_auto worldViewProj worldviewproj_matrix
param_named sunDirection float3 1 0 0
}
}
material CaelumSkyDomeMaterial
{
receive_shadows off
technique
{
pass
{
lighting off
depth_check off
depth_write off
scene_blend alpha_blend
fog_override true none
vertex_program_ref CaelumSkyDomeVP
{
}
fragment_program_ref CaelumSkyDomeFP
{
}
texture_unit
{
texture EarthClearSky2.png 0
tex_address_mode clamp
tex_coord_set 0
}
texture_unit
{
texture AtmosphereDepth.png 1d
tex_address_mode clamp
tex_coord_set 1
}
}
}
technique
{
pass
{
lighting off
depth_check off
depth_write off
scene_blend alpha_blend
fog_override true
texture_unit
{
texture EarthClearSky2.png 0
tex_address_mode clamp
tex_coord_set 0
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

@ -0,0 +1,42 @@
//
//This file is part of Caelum.
//See http://www.ogre3d.org/wiki/index.php/Caelum
//
//Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
//
//Caelum is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//Caelum 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 Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
material CaelumStarfieldMaterial
{
receive_shadows off
technique
{
pass
{
depth_check off
depth_write off
lighting off
fog_override true
texture_unit
{
texture Starfield.jpg 0
tex_address_mode wrap
}
}
}
}

@ -0,0 +1,58 @@
//
//This file is part of Caelum.
//See http://www.ogre3d.org/wiki/index.php/Caelum
//
//Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
//Caelum is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//Caelum 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 Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
material CaelumSphereSun
{
technique Defaulto
{
pass Main
{
depth_check off
depth_write off
fog_override true none
ambient 0 0 0
diffuse 0 0 0
}
}
}
material CaelumSpriteSun
{
receive_shadows off
technique Default
{
pass Main
{
lighting off
depth_check off
depth_write off
fog_override true none
ambient 0 0 0
diffuse 0 0 0
scene_blend src_colour one_minus_src_colour
alpha_rejection greater_equal 128
emissive vertexcolour
texture_unit Texture0
{
texture sun_disc.png 2d 0
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@ -0,0 +1,107 @@
//
//This file is part of Caelum.
//See http://www.ogre3d.org/wiki/index.php/Caelum
//
//Copyright (c) 2008 Caelum team. See Contributors.txt for details.
//
//Caelum is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//Caelum 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 Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with Caelum. If not, see <http://www.gnu.org/licenses/>.
//
fragment_program Caelum/PhaseMoonFP cg
{
source CaelumPhaseMoon.cg
entry_point PhaseMoonFP
profiles ps_2_0 arbfp1 fp30
default_params
{
param_named phase float 0.3
}
}
material Caelum/FullMoon
{
receive_shadows off
technique Default
{
pass Main
{
lighting off
depth_check off
depth_write off
fog_override true none
ambient 0 0 0
diffuse 0 0 0
scene_blend alpha_blend
emissive vertexcolour
texture_unit Texture0
{
texture moon_disc.dds 2d
}
}
}
}
material Caelum/PhaseMoon
{
receive_shadows off
technique Default
{
pass Main
{
lighting off
depth_check off
depth_write off
fog_override true none
ambient 0 0 0
diffuse 0 0 0
scene_blend alpha_blend
texture_unit MoonDisc
{
texture moon_disc.dds
}
fragment_program_ref Caelum/PhaseMoonFP
{
}
}
}
}
material Caelum/MoonBackground
{
receive_shadows off
technique Default
{
pass Main
{
// Used fixed function lighting to return black.
lighting off
depth_check off
depth_write off
fog_override true none
scene_blend alpha_blend
texture_unit MoonDisc
{
texture moon_disc.dds
colour_op_ex source1 src_manual src_diffuse 0 0 0 0
}
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -0,0 +1,349 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "Astronomy.h"
namespace Caelum
{
const LongReal Astronomy::PI = 3.1415926535897932384626433832795029L;
const LongReal Astronomy::J2000 = 2451545.0;
LongReal Astronomy::radToDeg (LongReal value)
{
return value * 180 / PI;
}
LongReal Astronomy::degToRad (LongReal value)
{
return value * PI / 180;
}
LongReal Astronomy::sinDeg (LongReal x) {
return std::sin (degToRad (x));
}
LongReal Astronomy::cosDeg (LongReal x) {
return std::cos (degToRad (x));
}
LongReal Astronomy::atan2Deg (LongReal y, LongReal x) {
return radToDeg(std::atan2 (y, x));
}
LongReal Astronomy::normalizeDegrees (LongReal value)
{
value = fmod (value, 360);
if (value < LongReal (0)) {
value += LongReal (360);
}
return value;
}
void Astronomy::convertEclipticToEquatorialRad (
LongReal lon, LongReal lat,
LongReal &rasc, LongReal &decl)
{
double ecl = Astronomy::degToRad(23.439281);
double x = cos(lon) * cos(lat);
double y = cos(ecl) * sin(lon) * cos(lat) - sin(ecl) * sin(lat);
double z = sin(ecl) * sin(lon) * cos(lat) + cos(ecl) * sin(lat);
double r = sqrt(x * x + y * y);
rasc = atan2(y, x);
decl = atan2(z, r);
}
void Astronomy::convertRectangularToSpherical (
LongReal x, LongReal y, LongReal z,
LongReal &rasc, LongReal &decl, LongReal &dist)
{
dist = sqrt (x * x + y * y + z * z);
rasc = atan2Deg (y, x);
decl = atan2Deg (z, sqrt (x * x + y * y));
}
void Astronomy::convertSphericalToRectangular (
LongReal rasc, LongReal decl, LongReal dist,
LongReal &x, LongReal &y, LongReal &z)
{
x = dist * cosDeg (rasc) * cosDeg (decl);
y = dist * sinDeg (rasc) * cosDeg (decl);
z = dist * sinDeg (decl);
}
void Astronomy::convertEquatorialToHorizontal (
LongReal jday,
LongReal longitude, LongReal latitude,
LongReal rasc, LongReal decl,
LongReal &azimuth, LongReal &altitude)
{
LongReal d = jday - 2451543.5;
LongReal w = LongReal (282.9404 + 4.70935E-5 * d);
LongReal M = LongReal (356.0470 + 0.9856002585 * d);
// Sun's mean longitude
LongReal L = w + M;
// Universal time of day in degrees.
LongReal UT = LongReal(fmod(d, 1) * 360);
LongReal hourAngle = longitude + L + LongReal (180) + UT - rasc;
LongReal x = cosDeg (hourAngle) * cosDeg (decl);
LongReal y = sinDeg (hourAngle) * cosDeg (decl);
LongReal z = sinDeg (decl);
LongReal xhor = x * sinDeg (latitude) - z * cosDeg (latitude);
LongReal yhor = y;
LongReal zhor = x * cosDeg (latitude) + z * sinDeg (latitude);
azimuth = atan2Deg (yhor, xhor) + LongReal (180);
altitude = atan2Deg (zhor, sqrt (xhor * xhor + yhor * yhor));
}
void Astronomy::getHorizontalSunPosition (
LongReal jday,
LongReal longitude, LongReal latitude,
LongReal &azimuth, LongReal &altitude)
{
// 2451544.5 == Astronomy::getJulianDayFromGregorianDateTime(2000, 1, 1, 0, 0, 0));
// 2451543.5 == Astronomy::getJulianDayFromGregorianDateTime(1999, 12, 31, 0, 0, 0));
LongReal d = jday - 2451543.5;
// Sun's Orbital elements:
// argument of perihelion
LongReal w = LongReal (282.9404 + 4.70935E-5 * d);
// eccentricity (0=circle, 0-1=ellipse, 1=parabola)
LongReal e = 0.016709 - 1.151E-9 * d;
// mean anomaly (0 at perihelion; increases uniformly with time)
LongReal M = LongReal(356.0470 + 0.9856002585 * d);
// Obliquity of the ecliptic.
//LongReal oblecl = LongReal (23.4393 - 3.563E-7 * d);
// Eccentric anomaly
LongReal E = M + radToDeg(e * sinDeg (M) * (1 + e * cosDeg (M)));
// Sun's Distance(R) and true longitude(L)
LongReal xv = cosDeg (E) - e;
LongReal yv = sinDeg (E) * sqrt (1 - e * e);
//LongReal r = sqrt (xv * xv + yv * yv);
LongReal lon = atan2Deg (yv, xv) + w;
LongReal lat = 0;
LongReal lambda = degToRad(lon);
LongReal beta = degToRad(lat);
LongReal rasc, decl;
convertEclipticToEquatorialRad (lambda, beta, rasc, decl);
rasc = radToDeg(rasc);
decl = radToDeg(decl);
// Horizontal spherical.
Astronomy::convertEquatorialToHorizontal (
jday, longitude, latitude, rasc, decl, azimuth, altitude);
}
void Astronomy::getHorizontalSunPosition (
LongReal jday,
Ogre::Degree longitude, Ogre::Degree latitude,
Ogre::Degree &azimuth, Ogre::Degree &altitude)
{
LongReal az, al;
getHorizontalSunPosition(jday, longitude.valueDegrees (), latitude.valueDegrees (), az, al);
azimuth = Ogre::Degree(az);
altitude = Ogre::Degree(al);
}
void Astronomy::getEclipticMoonPositionRad (
LongReal jday,
LongReal &lon, LongReal &lat)
{
// Julian centuries since January 1, 2000
double T = (jday - 2451545.0L) / 36525.0L;
double lprim = 3.8104L + 8399.7091L * T;
double mprim = 2.3554L + 8328.6911L * T;
double m = 6.2300L + 648.3019L * T;
double d = 5.1985L + 7771.3772L * T;
double f = 1.6280L + 8433.4663L * T;
lon = lprim
+ 0.1098L * sin(mprim)
+ 0.0222L * sin(2.0L * d - mprim)
+ 0.0115L * sin(2.0L * d)
+ 0.0037L * sin(2.0L * mprim)
- 0.0032L * sin(m)
- 0.0020L * sin(2.0L * f)
+ 0.0010L * sin(2.0L * d - 2.0L * mprim)
+ 0.0010L * sin(2.0L * d - m - mprim)
+ 0.0009L * sin(2.0L * d + mprim)
+ 0.0008L * sin(2.0L * d - m)
+ 0.0007L * sin(mprim - m)
- 0.0006L * sin(d)
- 0.0005L * sin(m + mprim);
lat =
+ 0.0895L * sin(f)
+ 0.0049L * sin(mprim + f)
+ 0.0048L * sin(mprim - f)
+ 0.0030L * sin(2.0L * d - f)
+ 0.0010L * sin(2.0L * d + f - mprim)
+ 0.0008 * sin(2.0L * d - f - mprim)
+ 0.0006L * sin(2.0L * d + f);
}
void Astronomy::getHorizontalMoonPosition (
LongReal jday,
LongReal longitude, LongReal latitude,
LongReal &azimuth, LongReal &altitude)
{
// Ecliptic spherical
LongReal lonecl, latecl;
Astronomy::getEclipticMoonPositionRad (jday, lonecl, latecl);
// Equatorial spherical
LongReal rasc, decl;
Astronomy::convertEclipticToEquatorialRad (lonecl, latecl, rasc, decl);
// Radians to degrees (all angles are in radians up to this point)
rasc = radToDeg(rasc);
decl = radToDeg(decl);
// Equatorial to horizontal
Astronomy::convertEquatorialToHorizontal (
jday, longitude, latitude, rasc, decl, azimuth, altitude);
}
void Astronomy::getHorizontalMoonPosition (
LongReal jday,
Ogre::Degree longitude, Ogre::Degree latitude,
Ogre::Degree &azimuth, Ogre::Degree &altitude)
{
LongReal az, al;
getHorizontalMoonPosition(jday, longitude.valueDegrees (), latitude.valueDegrees (), az, al);
azimuth = Ogre::Degree(az);
altitude = Ogre::Degree(al);
}
int Astronomy::getJulianDayFromGregorianDate(
int year, int month, int day)
{
// Formulas from http://en.wikipedia.org/wiki/Julian_day
// These are all integer divisions, but I'm not sure it works
// correctly for negative values.
int a = (14 - month) / 12;
int y = year + 4800 - a;
int m = month + 12 * a - 3;
return day + (153 * m + 2) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 32045;
}
LongReal Astronomy::getJulianDayFromGregorianDateTime(
int year, int month, int day,
int hour, int minute, LongReal second)
{
ScopedHighPrecissionFloatSwitch precissionSwitch;
int jdn = getJulianDayFromGregorianDate (year, month, day);
// These are NOT integer divisions.
LongReal jd = jdn + (hour - 12) / 24.0 + minute / 1440.0 + second / 86400.0;
return jd;
}
LongReal Astronomy::getJulianDayFromGregorianDateTime(
int year, int month, int day,
LongReal secondsFromMidnight)
{
int jdn = getJulianDayFromGregorianDate(year, month, day);
LongReal jd = jdn + secondsFromMidnight / 86400.0 - 0.5;
return jd;
}
void Astronomy::getGregorianDateFromJulianDay(
int julianDay, int &year, int &month, int &day)
{
// From http://en.wikipedia.org/wiki/Julian_day
int J = julianDay;
int j = J + 32044;
int g = j / 146097;
int dg = j % 146097;
int c = (dg / 36524 + 1) * 3 / 4;
int dc = dg - c * 36524;
int b = dc / 1461;
int db = dc % 1461;
int a = (db / 365 + 1) * 3 / 4;
int da = db - a * 365;
int y = g * 400 + c * 100 + b * 4 + a;
int m = (da * 5 + 308) / 153 - 2;
int d = da - (m + 4) * 153 / 5 + 122;
year = y - 4800 + (m + 2) / 12;
month = (m + 2) % 12 + 1;
day = d + 1;
}
void Astronomy::getGregorianDateTimeFromJulianDay(
LongReal julianDay, int &year, int &month, int &day,
int &hour, int &minute, LongReal &second)
{
// Integer julian days are at noon.
// static_cast<int)(floor( is more precise than Ogre::Math::IFloor.
// Yes, it does matter.
int ijd = static_cast<int>(floor(julianDay + 0.5));
getGregorianDateFromJulianDay(ijd, year, month, day);
LongReal s = (julianDay + 0.5 - ijd) * 86400.0;
hour = static_cast<int>(floor(s / 3600));
s -= hour * 3600;
minute = static_cast<int>(floor(s / 60));
s -= minute * 60;
second = s;
}
void Astronomy::getGregorianDateFromJulianDay(
LongReal julianDay, int &year, int &month, int &day)
{
int hour;
int minute;
LongReal second;
getGregorianDateTimeFromJulianDay(julianDay, year, month, day, hour, minute, second);
}
#if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) && (OGRE_COMPILER == OGRE_COMPILER_MSVC)
int Astronomy::enterHighPrecissionFloatingPointMode ()
{
int oldMode = ::_controlfp (0, 0);
::_controlfp (_PC_64, _MCW_PC);
return oldMode;
}
void Astronomy::restoreFloatingPointMode (int oldMode)
{
::_controlfp (oldMode, _MCW_PC);
}
#else
int Astronomy::enterHighPrecissionFloatingPointMode ()
{
// Meaningless
return 0xC0FFEE;
}
void Astronomy::restoreFloatingPointMode (int oldMode)
{
// Useless check.
assert(oldMode == 0xC0FFEE);
}
#endif
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,462 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "CaelumPrerequisites.h"
#if CAELUM_TYPE_DESCRIPTORS
#include "TypeDescriptor.h"
#include "CaelumSystem.h"
#include "FlatCloudLayer.h"
using namespace Ogre;
namespace Caelum
{
CaelumDefaultTypeDescriptorData::CaelumDefaultTypeDescriptorData ():
CaelumSystemTypeDescriptor(0),
PointStarfieldTypeDescriptor(0),
BaseSkyLightTypeDescriptor(0),
GroundFogTypeDescriptor(0),
PrecipitationTypeDescriptor(0),
DepthComposerTypeDescriptor(0),
FlatCloudLayerTypeDescriptor(0),
SkyDomeTypeDescriptor(0)
{
try {
load ();
} catch (...) {
unload ();
throw;
}
}
CaelumDefaultTypeDescriptorData::~CaelumDefaultTypeDescriptorData ()
{
unload ();
}
template<class T>
inline void delete_zero(T*& member) {
// Remember: delete 0 is a legal no-op.
delete member;
member = 0;
}
void CaelumDefaultTypeDescriptorData::unload ()
{
delete_zero(CaelumSystemTypeDescriptor);
delete_zero(PointStarfieldTypeDescriptor);
delete_zero(BaseSkyLightTypeDescriptor);
delete_zero(GroundFogTypeDescriptor);
delete_zero(PrecipitationTypeDescriptor);
delete_zero(DepthComposerTypeDescriptor);
delete_zero(FlatCloudLayerTypeDescriptor);
delete_zero(SkyDomeTypeDescriptor);
}
void CaelumDefaultTypeDescriptorData::load ()
{
if (!CaelumSystemTypeDescriptor)
{
std::auto_ptr<DefaultTypeDescriptor> td (new DefaultTypeDescriptor ());
// Timing settings.
td->add("time_scale",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, Real, Real, Real>(
&Caelum::CaelumSystem::getTimeScale,
&Caelum::CaelumSystem::setTimeScale));
td->add("julian_day",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, LongReal, LongReal, LongReal>(
&Caelum::CaelumSystem::getJulianDay,
&Caelum::CaelumSystem::setJulianDay));
// Latitude/longitude
td->add("latitude",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, Degree, Degree, const Degree>(
&Caelum::CaelumSystem::getObserverLatitude,
&Caelum::CaelumSystem::setObserverLatitude));
td->add("longitude",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, Degree, Degree, const Degree>(
&Caelum::CaelumSystem::getObserverLongitude,
&Caelum::CaelumSystem::setObserverLongitude));
// Fog settings.
td->add("global_fog_density_multiplier",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, Real, Real, Real>(
&Caelum::CaelumSystem::getGlobalFogDensityMultiplier,
&Caelum::CaelumSystem::setGlobalFogDensityMultiplier));
td->add("global_fog_colour_multiplier",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, ColourValue>(
&Caelum::CaelumSystem::getGlobalFogColourMultiplier,
&Caelum::CaelumSystem::setGlobalFogColourMultiplier));
td->add("manage_scene_fog",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, bool, bool, bool>(
&Caelum::CaelumSystem::getManageSceneFog,
&Caelum::CaelumSystem::setManageSceneFog));
td->add("scene_fog_density_multiplier",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, Real, Real, Real>(
&Caelum::CaelumSystem::getSceneFogDensityMultiplier,
&Caelum::CaelumSystem::setSceneFogDensityMultiplier));
td->add("scene_fog_colour_multiplier",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, ColourValue>(
&Caelum::CaelumSystem::getSceneFogColourMultiplier,
&Caelum::CaelumSystem::setSceneFogColourMultiplier));
td->add("ground_fog_density_multiplier",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, Real, Real, Real>(
&Caelum::CaelumSystem::getGroundFogDensityMultiplier,
&Caelum::CaelumSystem::setGroundFogDensityMultiplier));
td->add("ground_fog_colour_multiplier",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, ColourValue>(
&Caelum::CaelumSystem::getGroundFogColourMultiplier,
&Caelum::CaelumSystem::setGroundFogColourMultiplier));
// Lighting settings.
td->add("manage_ambient_light",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, bool, bool, bool>(
&Caelum::CaelumSystem::getManageAmbientLight,
&Caelum::CaelumSystem::setManageAmbientLight));
td->add("minimum_ambient_light",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, ColourValue>(
&Caelum::CaelumSystem::getMinimumAmbientLight,
&Caelum::CaelumSystem::setMinimumAmbientLight));
td->add("ensure_single_light_source",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, bool, bool, bool>(
&Caelum::CaelumSystem::getEnsureSingleLightSource,
&Caelum::CaelumSystem::setEnsureSingleLightSource));
td->add("ensure_single_shadow_source",
new AccesorPropertyDescriptor<Caelum::CaelumSystem, bool, bool, bool>(
&Caelum::CaelumSystem::getEnsureSingleShadowSource,
&Caelum::CaelumSystem::setEnsureSingleShadowSource));
CaelumSystemTypeDescriptor = td.release ();
}
if (!PointStarfieldTypeDescriptor)
{
std::auto_ptr<DefaultTypeDescriptor> td (new DefaultTypeDescriptor ());
td->add("magnitude_scale",
new AccesorPropertyDescriptor<Caelum::PointStarfield, Real, Real, Real>(
&Caelum::PointStarfield::getMagnitudeScale,
&Caelum::PointStarfield::setMagnitudeScale));
td->add("mag0_pixel_size",
new AccesorPropertyDescriptor<Caelum::PointStarfield, Real, Real, Real>(
&Caelum::PointStarfield::getMag0PixelSize,
&Caelum::PointStarfield::setMag0PixelSize));
td->add("min_pixel_size",
new AccesorPropertyDescriptor<Caelum::PointStarfield, Real, Real, Real>(
&Caelum::PointStarfield::getMinPixelSize,
&Caelum::PointStarfield::setMinPixelSize));
td->add("max_pixel_size",
new AccesorPropertyDescriptor<Caelum::PointStarfield, Real, Real, Real>(
&Caelum::PointStarfield::getMaxPixelSize,
&Caelum::PointStarfield::setMaxPixelSize));
td->add("latitude",
new AccesorPropertyDescriptor<Caelum::PointStarfield, Degree, Degree, Degree>(
&Caelum::PointStarfield::getObserverLatitude,
&Caelum::PointStarfield::setObserverLatitude));
td->add("longitude",
new AccesorPropertyDescriptor<Caelum::PointStarfield, Degree, Degree, Degree>(
&Caelum::PointStarfield::getObserverLongitude,
&Caelum::PointStarfield::setObserverLongitude));
td->add("observer_position_rebuild_delta",
new AccesorPropertyDescriptor<Caelum::PointStarfield, Degree, Degree, Degree>(
&Caelum::PointStarfield::getObserverPositionRebuildDelta,
&Caelum::PointStarfield::setObserverPositionRebuildDelta));
PointStarfieldTypeDescriptor = td.release ();
}
if (!BaseSkyLightTypeDescriptor)
{
std::auto_ptr<DefaultTypeDescriptor> td (new DefaultTypeDescriptor ());
td->add("ambient_multiplier",
new AccesorPropertyDescriptor<Caelum::BaseSkyLight, ColourValue>(
&Caelum::BaseSkyLight::getAmbientMultiplier,
&Caelum::BaseSkyLight::setAmbientMultiplier));
td->add("specular_multiplier",
new AccesorPropertyDescriptor<Caelum::BaseSkyLight, ColourValue>(
&Caelum::BaseSkyLight::getSpecularMultiplier,
&Caelum::BaseSkyLight::setSpecularMultiplier));
td->add("diffuse_multiplier",
new AccesorPropertyDescriptor<Caelum::BaseSkyLight, ColourValue>(
&Caelum::BaseSkyLight::getDiffuseMultiplier,
&Caelum::BaseSkyLight::setDiffuseMultiplier));
td->add("light_colour",
new AccesorPropertyDescriptor<Caelum::BaseSkyLight, ColourValue>(
&Caelum::BaseSkyLight::getLightColour,
&Caelum::BaseSkyLight::setLightColour));
td->add("body_colour",
new AccesorPropertyDescriptor<Caelum::BaseSkyLight, ColourValue>(
&Caelum::BaseSkyLight::getBodyColour,
&Caelum::BaseSkyLight::setBodyColour));
td->add("auto_disable_threshold",
new AccesorPropertyDescriptor<Caelum::BaseSkyLight, Real, Real, Real>(
&Caelum::BaseSkyLight::getAutoDisableThreshold,
&Caelum::BaseSkyLight::setAutoDisableThreshold));
td->add("auto_disable",
new AccesorPropertyDescriptor<Caelum::BaseSkyLight, bool, bool, bool>(
&Caelum::BaseSkyLight::getAutoDisable,
&Caelum::BaseSkyLight::setAutoDisable));
BaseSkyLightTypeDescriptor = td.release ();
}
if (!GroundFogTypeDescriptor)
{
std::auto_ptr<DefaultTypeDescriptor> td (new DefaultTypeDescriptor ());
td->add("density",
new AccesorPropertyDescriptor<Caelum::GroundFog, Real, Real, Real>(
&Caelum::GroundFog::getDensity,
&Caelum::GroundFog::setDensity));
td->add("vertical_decay",
new AccesorPropertyDescriptor<Caelum::GroundFog, Real, Real, Real>(
&Caelum::GroundFog::getVerticalDecay,
&Caelum::GroundFog::setVerticalDecay));
td->add("ground_level",
new AccesorPropertyDescriptor<Caelum::GroundFog, Real, Real, Real>(
&Caelum::GroundFog::getGroundLevel,
&Caelum::GroundFog::setGroundLevel));
td->add("colour",
new AccesorPropertyDescriptor<Caelum::GroundFog, ColourValue>(
&Caelum::GroundFog::getColour,
&Caelum::GroundFog::setColour));
GroundFogTypeDescriptor = td.release ();
}
if (!DepthComposerTypeDescriptor)
{
std::auto_ptr<DefaultTypeDescriptor> td (new DefaultTypeDescriptor ());
td->add("debug_depth_render",
new AccesorPropertyDescriptor<Caelum::DepthComposer, bool, bool, bool>(
&Caelum::DepthComposer::getDebugDepthRender,
&Caelum::DepthComposer::setDebugDepthRender));
// Legacy haze
td->add("haze_enabled",
new AccesorPropertyDescriptor<Caelum::DepthComposer, bool, bool, bool>(
&Caelum::DepthComposer::getSkyDomeHazeEnabled,
&Caelum::DepthComposer::setSkyDomeHazeEnabled));
td->add("haze_colour",
new AccesorPropertyDescriptor<Caelum::DepthComposer, ColourValue>(
&Caelum::DepthComposer::getHazeColour,
&Caelum::DepthComposer::setHazeColour));
td->add("haze_sun_direction",
new AccesorPropertyDescriptor<Caelum::DepthComposer, Vector3>(
&Caelum::DepthComposer::getSunDirection,
&Caelum::DepthComposer::setSunDirection));
// Ground fog
td->add("ground_fog_enabled",
new AccesorPropertyDescriptor<Caelum::DepthComposer, bool, bool, bool>(
&Caelum::DepthComposer::getGroundFogEnabled,
&Caelum::DepthComposer::setGroundFogEnabled));
td->add("ground_fog_density",
new AccesorPropertyDescriptor<Caelum::DepthComposer, Real, Real, Real>(
&Caelum::DepthComposer::getGroundFogDensity,
&Caelum::DepthComposer::setGroundFogDensity));
td->add("ground_fog_vertical_decay",
new AccesorPropertyDescriptor<Caelum::DepthComposer, Real, Real, Real>(
&Caelum::DepthComposer::getGroundFogVerticalDecay,
&Caelum::DepthComposer::setGroundFogVerticalDecay));
td->add("ground_fog_base_level",
new AccesorPropertyDescriptor<Caelum::DepthComposer, Real, Real, Real>(
&Caelum::DepthComposer::getGroundFogBaseLevel,
&Caelum::DepthComposer::setGroundFogBaseLevel));
td->add("ground_fog_colour",
new AccesorPropertyDescriptor<Caelum::DepthComposer, ColourValue>(
&Caelum::DepthComposer::getGroundFogColour,
&Caelum::DepthComposer::setGroundFogColour));
DepthComposerTypeDescriptor = td.release ();
}
if (!PrecipitationTypeDescriptor)
{
std::auto_ptr<DefaultTypeDescriptor> td (new DefaultTypeDescriptor ());
td->add("texture",
new AccesorPropertyDescriptor<Caelum::PrecipitationController, String>(
&Caelum::PrecipitationController::getTextureName,
&Caelum::PrecipitationController::setTextureName));
td->add("precipitation_colour",
new AccesorPropertyDescriptor<Caelum::PrecipitationController, ColourValue>(
&Caelum::PrecipitationController::getColour,
&Caelum::PrecipitationController::setColour));
td->add("falling_speed",
new AccesorPropertyDescriptor<Caelum::PrecipitationController, Real, Real, Real>(
&Caelum::PrecipitationController::getSpeed,
&Caelum::PrecipitationController::setSpeed));
td->add("wind_speed",
new AccesorPropertyDescriptor<Caelum::PrecipitationController, Vector3>(
&Caelum::PrecipitationController::getWindSpeed,
&Caelum::PrecipitationController::setWindSpeed));
td->add("camera_speed_scale",
new AccesorPropertyDescriptor<Caelum::PrecipitationController, Vector3>(
&Caelum::PrecipitationController::getCameraSpeedScale,
&Caelum::PrecipitationController::setCameraSpeedScale));
td->add("intensity",
new AccesorPropertyDescriptor<Caelum::PrecipitationController, Real, Real, Real>(
&Caelum::PrecipitationController::getIntensity,
&Caelum::PrecipitationController::setIntensity));
td->add("auto_disable_intensity",
new AccesorPropertyDescriptor<Caelum::PrecipitationController, Real, Real, Real>(
&Caelum::PrecipitationController::getAutoDisableThreshold,
&Caelum::PrecipitationController::setAutoDisableThreshold));
td->add("falling_direction",
new AccesorPropertyDescriptor<Caelum::PrecipitationController, Vector3>(
&Caelum::PrecipitationController::getFallingDirection,
&Caelum::PrecipitationController::setFallingDirection));
PrecipitationTypeDescriptor = td.release ();
}
if (!FlatCloudLayerTypeDescriptor)
{
std::auto_ptr<DefaultTypeDescriptor> td (new DefaultTypeDescriptor ());
// Height.
td->add("height",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getHeight,
&Caelum::FlatCloudLayer::setHeight));
// Coverage parameters.
td->add("coverage",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getCloudCover,
&Caelum::FlatCloudLayer::setCloudCover));
td->add("cloud_cover_visibility_threshold",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getCloudCoverVisibilityThreshold,
&Caelum::FlatCloudLayer::setCloudCoverVisibilityThreshold));
td->add("cloud_cover_lookup",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, String>(
&Caelum::FlatCloudLayer::getCloudCoverLookupFileName,
&Caelum::FlatCloudLayer::setCloudCoverLookup));
// Overwritten by CaelumSystem; included for completeness.
td->add("sun_direction",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Vector3>(
&Caelum::FlatCloudLayer::getSunDirection,
&Caelum::FlatCloudLayer::setSunDirection));
td->add("sun_light_colour",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, ColourValue>(
&Caelum::FlatCloudLayer::getSunLightColour,
&Caelum::FlatCloudLayer::setSunLightColour));
td->add("sun_sphere_colour",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, ColourValue>(
&Caelum::FlatCloudLayer::getSunSphereColour,
&Caelum::FlatCloudLayer::setSunSphereColour));
td->add("fog_colour",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, ColourValue>(
&Caelum::FlatCloudLayer::getFogColour,
&Caelum::FlatCloudLayer::setFogColour));
// Moving noise textures.
td->add("cloud_speed",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Vector2>(
&Caelum::FlatCloudLayer::getCloudSpeed,
&Caelum::FlatCloudLayer::setCloudSpeed));
// Blending time between noise textures.
td->add("blend_time",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getCloudBlendTime,
&Caelum::FlatCloudLayer::setCloudBlendTime));
// Mesh properties
td->add("mesh_width",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getMeshWidth,
&Caelum::FlatCloudLayer::setMeshWidth));
td->add("mesh_height",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getMeshHeight,
&Caelum::FlatCloudLayer::setMeshHeight));
td->add("mesh_width_segments",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, int, int, int>(
&Caelum::FlatCloudLayer::getMeshWidthSegments,
&Caelum::FlatCloudLayer::setMeshWidthSegments));
td->add("mesh_height_segments",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, int, int, int>(
&Caelum::FlatCloudLayer::getMeshHeightSegments,
&Caelum::FlatCloudLayer::setMeshHeightSegments));
// Misc hacks
td->add("cloud_uv_factor",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getCloudUVFactor,
&Caelum::FlatCloudLayer::setCloudUVFactor));
td->add("height_red_factor",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getHeightRedFactor,
&Caelum::FlatCloudLayer::setHeightRedFactor));
// Fading
td->add("near_fade_dist",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getNearFadeDist,
&Caelum::FlatCloudLayer::setNearFadeDist));
td->add("far_fade_dist",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Real, Real, Real>(
&Caelum::FlatCloudLayer::getFarFadeDist,
&Caelum::FlatCloudLayer::setFarFadeDist));
td->add("fade_dist_measurement_vector",
new AccesorPropertyDescriptor<Caelum::FlatCloudLayer, Vector3>(
&Caelum::FlatCloudLayer::getFadeDistMeasurementVector,
&Caelum::FlatCloudLayer::setFadeDistMeasurementVector));
FlatCloudLayerTypeDescriptor = td.release ();
}
if (!SkyDomeTypeDescriptor)
{
std::auto_ptr<DefaultTypeDescriptor> td (new DefaultTypeDescriptor ());
// SkyDome is slightly special because most properties are write-only.
// Reset by CaelumSystem every frame anyway
td->add("sun_direction",
new AccesorPropertyDescriptor<Caelum::SkyDome, Ogre::Vector3>(
0, &Caelum::SkyDome::setSunDirection));
td->add("haze_colour",
new AccesorPropertyDescriptor<Caelum::SkyDome, Ogre::ColourValue>(
0, &Caelum::SkyDome::setHazeColour));
// Different files not supported anyway
td->add("sky_gradients_image",
new AccesorPropertyDescriptor<Caelum::SkyDome, Ogre::String>(
0, &Caelum::SkyDome::setSkyGradientsImage));
td->add("atmosphere_depth_image",
new AccesorPropertyDescriptor<Caelum::SkyDome, Ogre::String>(
0, &Caelum::SkyDome::setAtmosphereDepthImage));
// This does actually make sense.
td->add("haze_enabled",
new AccesorPropertyDescriptor<Caelum::SkyDome, bool, bool, bool>(
&Caelum::SkyDome::getHazeEnabled,
&Caelum::SkyDome::setHazeEnabled));
SkyDomeTypeDescriptor = td.release ();
}
}
}
#endif // CAELUM_TYPE_DESCRIPTORS

@ -0,0 +1,162 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "CaelumPlugin.h"
template<> Caelum::CaelumPlugin* Ogre::Singleton<Caelum::CaelumPlugin>::ms_Singleton = 0;
namespace Caelum
{
CaelumPlugin* CaelumPlugin::getSingletonPtr () {
return ms_Singleton;
}
CaelumPlugin& CaelumPlugin::getSingleton () {
assert (ms_Singleton);
return *ms_Singleton;
}
extern "C" void CAELUM_EXPORT dllStartPlugin () {
assert (CaelumPlugin::getSingletonPtr () == 0);
CaelumPlugin* plugin = new CaelumPlugin();
assert (CaelumPlugin::getSingletonPtr () == plugin);
Ogre::Root::getSingleton ().installPlugin (CaelumPlugin::getSingletonPtr ());
}
extern "C" void CAELUM_EXPORT dllStopPlugin () {
assert (CaelumPlugin::getSingletonPtr () != 0);
Ogre::Root::getSingleton ().uninstallPlugin (CaelumPlugin::getSingletonPtr ());
delete CaelumPlugin::getSingletonPtr ();
assert (CaelumPlugin::getSingletonPtr () == 0);
}
#if CAELUM_SCRIPT_SUPPORT
CaelumPlugin::CaelumPlugin(): mScriptTranslatorManager(&mTypeDescriptorData)
#else
CaelumPlugin::CaelumPlugin()
#endif
{
mIsInstalled = false;
}
CaelumPlugin::~CaelumPlugin() {
}
const Ogre::String CaelumPlugin::CAELUM_PLUGIN_NAME = "Caelum";
const Ogre::String& CaelumPlugin::getName () const {
return CAELUM_PLUGIN_NAME;
}
void CaelumPlugin::install ()
{
assert(!mIsInstalled && "Already installed");
Ogre::LogManager::getSingleton ().logMessage("Caelum plugin version " +
Ogre::StringConverter::toString (CAELUM_VERSION_MAIN) + "." +
Ogre::StringConverter::toString (CAELUM_VERSION_SEC) + "." +
Ogre::StringConverter::toString (CAELUM_VERSION_TER) + " "
"installed");
#if CAELUM_SCRIPT_SUPPORT
Ogre::ScriptCompilerManager::getSingleton ().addTranslatorManager (
getScriptTranslatorManager ());
Ogre::ResourceGroupManager::getSingleton()._registerResourceManager (
getPropScriptResourceManager ()->getResourceType (),
getPropScriptResourceManager ());
getScriptTranslatorManager()->_setPropScriptResourceManager (
&mPropScriptResourceManager);
#endif // CAELUM_SCRIPT_SUPPORT
mIsInstalled = true;
}
void CaelumPlugin::initialise () {
}
void CaelumPlugin::shutdown () {
}
void CaelumPlugin::uninstall ()
{
assert(mIsInstalled && "Not installed");
#if CAELUM_SCRIPT_SUPPORT
getScriptTranslatorManager()->_setPropScriptResourceManager (0);
Ogre::ResourceGroupManager::getSingleton ()._unregisterResourceManager (
getPropScriptResourceManager ()->getResourceType ());
Ogre::ScriptCompilerManager::getSingleton ().removeTranslatorManager (
getScriptTranslatorManager ());
#endif // CAELUM_SCRIPT_SUPPORT
Ogre::LogManager::getSingleton ().logMessage("Caelum plugin uninstalled");
mIsInstalled = false;
}
#if CAELUM_SCRIPT_SUPPORT
void CaelumPlugin::loadCaelumSystemFromScript (
CaelumSystem* sys,
const Ogre::String& objectName,
const Ogre::String& groupName)
{
assert (sys);
assert (this->isInstalled () && "Must install CaelumPlugin before loading scripts");
// Fetch raw resource ptr. Attempt to support explicit resource groups currently in Ogre trunk.
#if OGRE_VERSION >= 0x00010700
Ogre::ResourcePtr res = getPropScriptResourceManager ()->getByName (objectName, groupName);
#else
Ogre::ResourcePtr res = getPropScriptResourceManager ()->getByName (objectName);
#endif
// Check a PropScriptResource was found.
PropScriptResource* propRes = static_cast<PropScriptResource*> (res.get ());
if (!propRes) {
OGRE_EXCEPT (Ogre::Exception::ERR_ITEM_NOT_FOUND,
"Could not find caelum_sky_system " + objectName,
"CaelumPlugin::loadCaelumSystemFromScript");
}
// Fetch the resource stream. Look in the actual group of the resource!
const Ogre::String& scriptFileName = propRes->getOrigin();
const Ogre::String& scriptFileGroup = propRes->getGroup();
Ogre::DataStreamPtr streamPtr = Ogre::ResourceGroupManager::getSingleton ().openResource (
scriptFileName, scriptFileGroup, false);
// Feed it into the compiler.
this->getScriptTranslatorManager()->getCaelumSystemTranslator()->setTranslationTarget (sys, objectName);
Ogre::ScriptCompilerManager::getSingleton ().parseScript (streamPtr, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
bool found = this->getScriptTranslatorManager()->getCaelumSystemTranslator()->foundTranslationTarget ();
// This shouldn't normally happen.
if (!found) {
OGRE_EXCEPT (Ogre::Exception::ERR_ITEM_NOT_FOUND,
"Could not find caelum_sky_system " + objectName + " in file " + scriptFileName + " on reparsing. "
"Perhaps information in PropScriptResourceManager is out of date?",
"CaelumPlugin::loadCaelumSystemFromScript");
}
this->getScriptTranslatorManager()->getCaelumSystemTranslator()->clearTranslationTarget ();
}
#endif // CAELUM_SCRIPT_SUPPORT
}

@ -0,0 +1,21 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"

@ -0,0 +1,643 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "CaelumPrerequisites.h"
#if CAELUM_SCRIPT_SUPPORT
#include "CaelumScriptTranslator.h"
#include "CaelumSystem.h"
#include "CaelumExceptions.h"
using namespace Ogre;
namespace Caelum
{
PropScriptResource::PropScriptResource
(
Ogre::ResourceManager* creator, const Ogre::String& name, Ogre::ResourceHandle handle,
const Ogre::String& group, bool isManual, Ogre::ManualResourceLoader* loader
):
Ogre::Resource (creator, name, handle, group, isManual, loader)
{
//Ogre::LogManager::getSingleton().logMessage(
// "PropScriptResource::PropScriptResource");
}
PropScriptResource::~PropScriptResource() {
//Ogre::LogManager::getSingleton().logMessage(
// "PropScriptResource::~PropScriptResource");
}
PropScriptResourceManager::PropScriptResourceManager() {
mLoadOrder = 1000;
mResourceType = "PropertyScript";
}
PropScriptResource* PropScriptResourceManager::createImpl(
const String& name, ResourceHandle handle, const String& group,
bool isManual, ManualResourceLoader* loader, const NameValuePairList* createParams)
{
//Ogre::LogManager::getSingleton().logMessage(
// "PropScriptResourceManager::createImpl");
return new PropScriptResource (this, name, handle, group, isManual, loader);
}
TypeDescriptorScriptTranslator::TypeDescriptorScriptTranslator (TypeDescriptor* typeDescriptor):
mTypeDescriptor(typeDescriptor)
{
}
bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
bool& value)
{
if (prop->values.empty ()) {
compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
return false;
}
if (prop->values.size () > 1) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at most 1 argument");
return false;
}
if (!Ogre::ScriptTranslator::getBoolean(prop->values.front(), &value)) {
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
prop->values.front()->getValue() + " is not a valid number");
return false;
}
return true;
}
bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
ColourValue& value)
{
if (prop->values.empty ()) {
compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
return false;
}
if (prop->values.size () > 4) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at most 4 arguments");
return false;
}
if (prop->values.size () < 3) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at least 3 arguments");
}
if (!getColour(prop->values.begin(), prop->values.end(), &value)) {
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
prop->name + " requires a colour argument");
}
return true;
}
bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
float& value)
{
if (prop->values.empty ()) {
compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
return false;
}
if (prop->values.size () > 1) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at most 1 argument");
return false;
}
if (!Ogre::ScriptTranslator::getFloat(prop->values.front(), &value)) {
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
prop->values.front()->getValue() + " is not a valid number");
return false;
}
return true;
}
bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
int& value)
{
if (prop->values.empty ()) {
compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
return false;
}
if (prop->values.size () > 1) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at most 1 argument");
return false;
}
if (!Ogre::ScriptTranslator::getInt(prop->values.front(), &value)) {
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
prop->values.front()->getValue() + " is not a valid integer");
return false;
}
return true;
}
bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
double& value)
{
if (prop->values.empty ()) {
compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
return false;
}
if (prop->values.size () > 1) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at most 1 argument");
return false;
}
// We do need a string stream here for the extra precision.
std::stringstream strStream (std::string(prop->values.front()->getValue()));
strStream >> value;
if (strStream.fail()) {
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
prop->values.front()->getValue() + " is not a valid number");
return false;
}
return true;
}
bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
Ogre::Degree& value)
{
if (prop->values.size () == 0) {
compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
return false;
}
if (prop->values.size () > 3) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at most 3 arguments");
return false;
}
// Allow 3 components.
float degMinSec[3] = { 0, 0, 0 };
int k = 0;
for (AbstractNodeList::const_iterator it = prop->values.begin(), endIt = prop->values.end(); it != endIt; ++it, ++k) {
if (!Ogre::ScriptTranslator::getFloat(*it, &degMinSec[k])) {
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
(*it)->getValue () + " is not a valid number");
return false;
}
}
value = Ogre::Degree(degMinSec[0] + degMinSec[1] / 60.0 + degMinSec[2] / 3600);
return true;
}
bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
Ogre::String& value)
{
if (prop->values.size () == 0) {
compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
return false;
}
if (prop->values.size () > 1) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at most 1 arguments");
return false;
}
if (!Ogre::ScriptTranslator::getString(prop->values.front(), &value)) {
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
prop->values.front()->getValue() + " is not a valid string");
return false;
}
return true;
}
bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
Ogre::Vector3& value)
{
if (prop->values.size () == 0) {
compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
return false;
}
if (prop->values.size () > 3) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at most 3 arguments");
return false;
}
float floats[3];
if (!Ogre::ScriptTranslator::getFloats(prop->values.begin(), prop->values.end(), floats, 3)) {
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
"incorrect vector parameters.");
return false;
}
value.x = floats[0];
value.y = floats[1];
value.z = floats[2];
return true;
}
bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
Ogre::Vector2& value)
{
if (prop->values.size () == 0) {
compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
return false;
}
if (prop->values.size () > 2) {
compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
prop->name + " must have at most 3 arguments");
return false;
}
float floats[2];
if (!Ogre::ScriptTranslator::getFloats(prop->values.begin(), prop->values.end(), floats, 2)) {
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
"incorrect vector parameters.");
return false;
}
value.x = floats[0];
value.y = floats[1];
return true;
}
template<class T>
static bool tryHandlePropertyType (
ScriptCompiler* compiler, PropertyAbstractNode* propNode,
void* targetObject, const ValuePropertyDescriptor* propDesc)
{
if (propDesc->getValueTypeId () == typeid(T)) {
T val;
if (TypeDescriptorScriptTranslator::getPropValueOrAddError (compiler, propNode, val)) {
propDesc->setValue (targetObject, Ogre::Any(val));
}
return true;
}
return false;
}
void TypeDescriptorScriptTranslator::translateProperty (
ScriptCompiler* compiler,
PropertyAbstractNode* prop,
void* targetObject,
const TypeDescriptor* typeDescriptor)
{
const ValuePropertyDescriptor* propDesc = typeDescriptor->getPropertyDescriptor (prop->name);
if (!propDesc) {
compiler->addError (ScriptCompiler::CE_UNEXPECTEDTOKEN, prop->file, prop->line,
"property \"" + prop->name + "\" not recognized; missing from type descriptor.");
return;
}
if (!propDesc->canSetValue ()) {
compiler->addError (ScriptCompiler::CE_UNEXPECTEDTOKEN, prop->file, prop->line,
"property \"" + prop->name + "\" is read-only and can't be set from a script.");
return;
}
//LogManager::getSingleton ().logMessage ("TypeDescriptorScriptTranslator::translateProperty"
// " name '" + prop->name + "'");
bool handled = false
|| tryHandlePropertyType<int> (compiler, prop, targetObject, propDesc)
|| tryHandlePropertyType<float> (compiler, prop, targetObject, propDesc)
|| tryHandlePropertyType<double> (compiler, prop, targetObject, propDesc)
|| tryHandlePropertyType<bool> (compiler, prop, targetObject, propDesc)
|| tryHandlePropertyType<Ogre::Degree> (compiler, prop, targetObject, propDesc)
|| tryHandlePropertyType<Ogre::String> (compiler, prop, targetObject, propDesc)
|| tryHandlePropertyType<Ogre::Vector3> (compiler, prop, targetObject, propDesc)
|| tryHandlePropertyType<Ogre::Vector2> (compiler, prop, targetObject, propDesc)
|| tryHandlePropertyType<Ogre::ColourValue> (compiler, prop, targetObject, propDesc);
if (!handled) {
compiler->addError (ScriptCompiler::CE_UNEXPECTEDTOKEN, prop->file, prop->line,
"property \"" + prop->name + "\" is found in type descriptor but has "
"unsupported type. Mangled typeid is '" + propDesc->getValueTypeId().name() + "'");
}
}
void TypeDescriptorScriptTranslator::translate (ScriptCompiler* compiler, const AbstractNodePtr& node)
{
//LogManager::getSingleton ().logMessage ("TypeDescriptorScriptTranslator::translate begin");
// Check type descriptor was set.
assert (getTypeDescriptor () && "Type descriptor must be set before we can translate.");
// Fetch target object.
ObjectAbstractNode *objNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
assert (!objNode->context.isEmpty ());
void* targetObject = any_cast<void*> (objNode->context);
assert (targetObject);
for (AbstractNodeList::iterator i = objNode->children.begin(); i != objNode->children.end(); ++i)
{
if ((*i)->type == ANT_PROPERTY)
{
PropertyAbstractNode *prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());
translateProperty (compiler, prop, targetObject, getTypeDescriptor());
}
else if((*i)->type == ANT_OBJECT)
{
compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, (*i)->file, (*i)->line);
}
}
//LogManager::getSingleton ().logMessage ("TypeDescriptorScriptTranslator::translate end");
}
CaelumSystemScriptTranslator::CaelumSystemScriptTranslator ():
mResourceManager(false),
mTranslationTarget(0),
mTranslationTargetFound(false),
mTypeDescriptor(0)
{
}
void CaelumSystemScriptTranslator::setTranslationTarget (CaelumSystem* target, const Ogre::String& name)
{
assert (target != 0);
this->mTranslationTarget = target;
this->mTranslationTargetName = name;
this->mTranslationTargetFound = false;
}
void CaelumSystemScriptTranslator::clearTranslationTarget () {
this->mTranslationTarget = 0;
this->mTranslationTargetName.clear();
this->mTranslationTargetFound = false;
}
void CaelumSystemScriptTranslator::translate (ScriptCompiler* compiler, const AbstractNodePtr& node)
{
//LogManager::getSingleton ().logMessage ("CaelumSystemScriptTranslator::translate begin");
ObjectAbstractNode *objNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
CaelumSystem* sys = 0;
// Check for a translation target.
if (this->getTranslationTarget ()) {
sys = this->getTranslationTarget ();
// Check for a name match.
if (this->getTranslationTargetName () != objNode->name) {
//LogManager::getSingleton ().logMessage (
// "Caelum: Skipped " + objNode->cls + " name " + objNode->name + " while loading");
return;
}
// Clear the target; this ensure that properties which are not
// mentioned are set to their default values.
// We only do this after we found a target; this ensure that if
// the target is not found it's not modified either.
sys->clear();
//LogManager::getSingleton ().logMessage (
// "Caelum: Found " + objNode->cls + " name " + objNode->name + "; filling properties.");
mTranslationTargetFound = true;
} else if (this->getResourceManager ()) {
// If we don't have a target but have a resource manager then create a resource.
//LogManager::getSingleton ().logMessage (
// "Caelum: Saved " + objNode->cls + " name " + objNode->name + " as a resource");
PropScriptResourceManager* mgr = this->getResourceManager ();
ResourcePtr resource = mgr->create (objNode->name, compiler->getResourceGroup());
resource->_notifyOrigin (objNode->file);
return;
}
objNode->context = sys;
for (AbstractNodeList::iterator i = objNode->children.begin(); i != objNode->children.end(); ++i)
{
if ((*i)->type == ANT_PROPERTY)
{
PropertyAbstractNode *prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());
// Properties implemented through type descriptor.
TypeDescriptorScriptTranslator::translateProperty(
compiler, prop,
static_cast<void*>(sys),
getTypeDescriptor ());
}
else if((*i)->type == ANT_OBJECT)
{
ObjectAbstractNode *childObjNode = reinterpret_cast<ObjectAbstractNode*>((*i).get());
//LogManager::getSingleton ().logMessage ("CaelumSystemScriptTranslator::translate child object"
// " value '" + childObjNode->getValue () + "'"
// " name '" + childObjNode->name + "'"
// " cls '" + childObjNode->cls + "'"
// " base '" + childObjNode->base + "'");
// Only allow declarations with one class token; like "moon { }"
#if OGRE_VERSION < 0x010700
if (childObjNode->name.empty () == false || childObjNode->base.empty () == false) {
#else
if (childObjNode->name.empty () == false || childObjNode->bases.size () != 0) {
#endif
compiler->addError (
ScriptCompiler::CE_FEWERPARAMETERSEXPECTED,
childObjNode->file, childObjNode->line,
"caelum_sky_system components can't have names or bases");
continue;
}
const String& className = childObjNode->cls;
try {
if (className == "sun") {
sys->setSun (new Sun (sys->getSceneMgr (), sys->getCaelumCameraNode ()));
childObjNode->context = static_cast<void*> (sys->getSun ());
} else if (className == "sky_dome") {
sys->setSkyDome (new SkyDome (sys->getSceneMgr (), sys->getCaelumCameraNode ()));
childObjNode->context = static_cast<void*>(sys->getSkyDome ());
} else if (className == "moon") {
sys->setMoon (new Moon (sys->getSceneMgr (), sys->getCaelumCameraNode ()));
childObjNode->context = static_cast<void*>(sys->getMoon ());
} else if (className == "ground_fog") {
sys->setGroundFog (new GroundFog (sys->getSceneMgr (), sys->getCaelumCameraNode ()));
childObjNode->context = static_cast<void*>(sys->getGroundFog ());
} else if (className == "depth_composer") {
sys->setDepthComposer (new DepthComposer (sys->getSceneMgr ()));
childObjNode->context = static_cast<void*>(sys->getDepthComposer ());
} else if (className == "point_starfield") {
sys->setPointStarfield (new PointStarfield (sys->getSceneMgr (), sys->getCaelumCameraNode()));
childObjNode->context = static_cast<void*>(sys->getPointStarfield ());
} else if (className == "precipitation") {
sys->setPrecipitationController (new PrecipitationController (sys->getSceneMgr ()));
childObjNode->context = static_cast<void*>(sys->getPrecipitationController ());
} else if (className == "cloud_system") {
sys->setCloudSystem (new CloudSystem (sys->getSceneMgr (), sys->getCaelumGroundNode ()));
childObjNode->context = static_cast<void*>(sys->getCloudSystem ());
} else {
LogManager::getSingleton ().logMessage ("CaelumSystemScriptTranslator::translate "
"unknown child object class '" + className + "'");
}
} catch (Caelum::UnsupportedException& ex) {
// Catch all unsupported exceptions and report them.
// This should usually happen because the proper shaders are not supported by hardware.
//
// Script parsing should still succeed.
compiler->addError (
ScriptCompiler::CE_UNSUPPORTEDBYRENDERSYSTEM,
childObjNode->file, childObjNode->line,
"Failed to create component \"" + className + "\": " + ex.getFullDescription ());
continue;
}
processNode (compiler, *i);
}
}
//LogManager::getSingleton ().logMessage ("SkySystemScriptTranslator::translate END");
}
void CloudSystemScriptTranslator::translate (ScriptCompiler* compiler, const AbstractNodePtr& node)
{
//LogManager::getSingleton ().logMessage ("SkySystemScriptTranslator::translate begin");
ObjectAbstractNode *objNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
assert (!objNode->context.isEmpty ());
void* rawTargetObject = any_cast<void*> (objNode->context);
assert (rawTargetObject);
CloudSystem* target = static_cast<CloudSystem*>(rawTargetObject);
for (AbstractNodeList::iterator i = objNode->children.begin(); i != objNode->children.end(); ++i)
{
if ((*i)->type == ANT_PROPERTY)
{
compiler->addError (
ScriptCompiler::CE_INVALIDPARAMETERS,
objNode->file, objNode->line,
"cloud_system doesn't have any properties");
}
else if((*i)->type == ANT_OBJECT)
{
ObjectAbstractNode *childObjNode = reinterpret_cast<ObjectAbstractNode*>((*i).get());
/*
LogManager::getSingleton ().logMessage ("CloudSystemScriptTranslator::translate child object"
" value '" + childObjNode->getValue () + "'"
" name '" + childObjNode->name + "'"
" cls '" + childObjNode->cls + "'"
" base '" + childObjNode->base + "'");
*/
const Ogre::String& className = childObjNode->cls;
if (className == "cloud_layer") {
// Don't allow names.
#if OGRE_VERSION < 0x010700
if (childObjNode->base.empty () == false) {
#else
if (childObjNode->bases.size () != 0) {
#endif
compiler->addError (
ScriptCompiler::CE_FEWERPARAMETERSEXPECTED,
childObjNode->file, childObjNode->line,
"cloud_layer can't have a base");
continue;
}
// Height here is irrelevant. It's silly to have it as a FlatCloudLayer ctor parameter.
target->createLayerAtHeight (0);
FlatCloudLayer* layer = target->getLayer (target->getLayerCount () - 1);
// Add the new layer as a context for the object node.
// This will eventually pass to the TypeDescriptorScriptTranslator for a cloud layer.
childObjNode->context = static_cast<void*>(layer);
} else {
LogManager::getSingleton ().logMessage ("CloudSystemScriptTranslator::translate "
"unknown child object class '" + className + "'");
}
processNode (compiler, *i);
}
}
//LogManager::getSingleton ().logMessage ("CloudSystemScriptTranslator::translate END");
}
CaelumScriptTranslatorManager::CaelumScriptTranslatorManager
(
CaelumDefaultTypeDescriptorData* typeData
):
mCaelumSystemTranslator(),
mCloudSystemTranslator(),
mFlatCloudLayerTranslator(typeData->FlatCloudLayerTypeDescriptor),
mSunTranslator(typeData->BaseSkyLightTypeDescriptor),
mMoonTranslator(typeData->BaseSkyLightTypeDescriptor),
mPointStarfieldTranslator(typeData->PointStarfieldTypeDescriptor),
mGroundFogTranslator(typeData->GroundFogTypeDescriptor),
mDepthComposerTranslator(typeData->DepthComposerTypeDescriptor),
mPrecipitationTranslator(typeData->PrecipitationTypeDescriptor),
mSkyDomeTranslator(typeData->SkyDomeTypeDescriptor)
{
mCaelumSystemTranslator.setTypeDescriptor(typeData->CaelumSystemTypeDescriptor);
// Build translator map to member translators.
mTranslatorMap.insert (std::make_pair ("caelum_sky_system", &mCaelumSystemTranslator));
mTranslatorMap.insert (std::make_pair ("cloud_system", &mCloudSystemTranslator));
mTranslatorMap.insert (std::make_pair ("cloud_layer", &mFlatCloudLayerTranslator));
mTranslatorMap.insert (std::make_pair ("sun", &mSunTranslator));
mTranslatorMap.insert (std::make_pair ("moon", &mMoonTranslator));
mTranslatorMap.insert (std::make_pair ("point_starfield", &mPointStarfieldTranslator));
mTranslatorMap.insert (std::make_pair ("ground_fog", &mGroundFogTranslator));
mTranslatorMap.insert (std::make_pair ("depth_composer", &mDepthComposerTranslator));
mTranslatorMap.insert (std::make_pair ("precipitation", &mPrecipitationTranslator));
mTranslatorMap.insert (std::make_pair ("sky_dome", &mSkyDomeTranslator));
}
size_t CaelumScriptTranslatorManager::getNumTranslators () const {
// Turns out this is never called.
assert(0 && "This method should be removed from Ogre::ScriptTranslatorManager");
return mTranslatorMap.size ();
}
void CaelumScriptTranslatorManager::_setPropScriptResourceManager (PropScriptResourceManager* mgr)
{
mCaelumSystemTranslator.setResourceManager (mgr);
}
ScriptTranslator* CaelumScriptTranslatorManager::getTranslator (const AbstractNodePtr& node)
{
//LogManager::getSingleton ().logMessage ("CaelumScriptTranslatorManager::getTranslator");
if (node->type == ANT_ATOM) {
//ObjectAbstractNode* atomNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
//LogManager::getSingleton ().logMessage ("CaelumScriptTranslatorManager::getTranslator atom node " + atomNode->getValue ());
} else if (node->type == ANT_OBJECT) {
ObjectAbstractNode* objNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
//LogManager::getSingleton ().logMessage ("CaelumScriptTranslatorManager::getTranslator object node " + objNode->getValue ());
// Pass down the context.
ScriptTranslatorMap::const_iterator it = mTranslatorMap.find(objNode->cls);
if (it != mTranslatorMap.end()) {
return it->second;
}
}
// Not found in this manager.
return 0;
}
}
#endif // CAELUM_SCRIPT_SUPPORT

@ -0,0 +1,760 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "CaelumSystem.h"
#include "CaelumExceptions.h"
#include "InternalUtilities.h"
#include "Astronomy.h"
#include "CaelumPlugin.h"
#include "FlatCloudLayer.h"
using namespace Ogre;
namespace Caelum
{
const String CaelumSystem::DEFAULT_SKY_GRADIENTS_IMAGE = "EarthClearSky2.png";
const String CaelumSystem::DEFAULT_SUN_COLOURS_IMAGE = "SunGradient.png";
CaelumSystem::CaelumSystem
(
Ogre::Root *root,
Ogre::SceneManager *sceneMgr,
CaelumComponent componentsToCreate/* = CAELUM_COMPONENTS_DEFAULT*/
):
mOgreRoot (root),
mSceneMgr (sceneMgr),
mCleanup (false)
{
LogManager::getSingleton().logMessage ("Caelum: Initialising Caelum system...");
//LogManager::getSingleton().logMessage ("Caelum: CaelumSystem* at d" +
// StringConverter::toString (reinterpret_cast<uint>(this)));
Ogre::String uniqueId = Ogre::StringConverter::toString ((size_t)this);
if (!CaelumPlugin::getSingletonPtr ()) {
LogManager::getSingleton().logMessage ("Caelum: Plugin not installed; installing now.");
new CaelumPlugin ();
CaelumPlugin::getSingletonPtr ()->install ();
CaelumPlugin::getSingletonPtr ()->initialise ();
}
mCaelumCameraNode.reset(mSceneMgr->getRootSceneNode ()->createChildSceneNode ("Caelum/CameraNode/" + uniqueId));
mCaelumGroundNode.reset(mSceneMgr->getRootSceneNode ()->createChildSceneNode ("Caelum/GroundNode/" + uniqueId));
mUniversalClock.reset(new UniversalClock ());
// If the "Caelum" resource group does not exist; create it.
// This resource group is never released; which may be bad.
// What does ogre do for it's own runtime resources?
Ogre::StringVector groups = ResourceGroupManager::getSingleton ().getResourceGroups ();
if (std::find (groups.begin(), groups.end(), Caelum::RESOURCE_GROUP_NAME) == groups.end()) {
LogManager::getSingleton ().logMessage (
"Caelum: Creating required internal resource group \'" + RESOURCE_GROUP_NAME + "\'");
ResourceGroupManager::getSingleton ().createResourceGroup (Caelum::RESOURCE_GROUP_NAME);
}
// Autoconfigure. Calls clear first to set defaults.
autoConfigure (componentsToCreate);
}
void CaelumSystem::destroySubcomponents (bool destroyEverything)
{
// Destroy sub-components
setSkyDome (0);
setSun (0);
setImageStarfield (0);
setPointStarfield (0);
setCloudSystem (0);
setPrecipitationController (0);
setDepthComposer (0);
setGroundFog (0);
setMoon (0);
mSkyGradientsImage.reset ();
mSunColoursImage.reset ();
// These things can't be rebuilt.
if (destroyEverything) {
LogManager::getSingleton ().logMessage("Caelum: Delete UniversalClock");
mUniversalClock.reset ();
mCaelumCameraNode.reset ();
mCaelumGroundNode.reset ();
}
}
CaelumSystem::~CaelumSystem () {
destroySubcomponents (true);
LogManager::getSingleton ().logMessage ("Caelum: CaelumSystem destroyed.");
}
void CaelumSystem::clear()
{
// Destroy all subcomponents first.
destroySubcomponents (false);
// Some "magical" behaviour.
mAutoMoveCameraNode = true;
mAutoNotifyCameraChanged = true;
mAutoAttachViewportsToComponents = true;
mAutoViewportBackground = true;
// Default lookups.
setSkyGradientsImage(DEFAULT_SKY_GRADIENTS_IMAGE);
setSunColoursImage(DEFAULT_SUN_COLOURS_IMAGE);
// Fog defaults.
setManageSceneFog (true);
mGlobalFogDensityMultiplier = 1;
mGlobalFogColourMultiplier = Ogre::ColourValue(1.0, 1.0, 1.0, 1.0);
mSceneFogDensityMultiplier = 1;
mSceneFogColourMultiplier = Ogre::ColourValue(0.7, 0.7, 0.7, 0.7);
mGroundFogDensityMultiplier = 1;
mGroundFogColourMultiplier = Ogre::ColourValue(1.0, 1.0, 1.0, 1.0);
// Ambient lighting.
setManageAmbientLight (true);
setMinimumAmbientLight (Ogre::ColourValue (0.1, 0.1, 0.3));
mEnsureSingleLightSource = false;
mEnsureSingleShadowSource = false;
// Observer time & position. J2000 is midday.
mObserverLatitude = Ogre::Degree(45);
mObserverLongitude = Ogre::Degree(0);
mUniversalClock->setJulianDay (Astronomy::J2000);
}
void CaelumSystem::autoConfigure
(
CaelumComponent componentsToCreate/* = CAELUM_COMPONENTS_DEFAULT*/
)
{
// Clear everything; revert to default.
clear();
if (componentsToCreate == 0) {
// Nothing to do. Don't print junk if not creating anything.
return;
}
LogManager::getSingleton ().logMessage ("Caelum: Creating caelum sub-components.");
// Init skydome
if (componentsToCreate & CAELUM_COMPONENT_SKY_DOME) {
try {
this->setSkyDome (new SkyDome (mSceneMgr, getCaelumCameraNode ()));
} catch (Caelum::UnsupportedException& ex) {
LogManager::getSingleton ().logMessage (
"Caelum: Failed to initialize skydome: " + ex.getFullDescription());
}
}
// Init sun
if (componentsToCreate & CAELUM_COMPONENT_SUN) {
try {
this->setSun (new SpriteSun (mSceneMgr, getCaelumCameraNode ()));
this->getSun ()->setAmbientMultiplier (Ogre::ColourValue (0.5, 0.5, 0.5));
this->getSun ()->setDiffuseMultiplier (Ogre::ColourValue (3, 3, 2.7));
this->getSun ()->setSpecularMultiplier (Ogre::ColourValue (5, 5, 5));
this->getSun ()->setAutoDisable (true);
this->getSun ()->setAutoDisableThreshold (0.05);
} catch (Caelum::UnsupportedException& ex) {
LogManager::getSingleton ().logMessage (
"Caelum: Failed to initialize sun: " + ex.getFullDescription());
}
}
// Init moon
if (componentsToCreate & CAELUM_COMPONENT_MOON) {
try {
this->setMoon (new Moon (mSceneMgr, getCaelumCameraNode ()));
this->getMoon ()->setAutoDisable (true);
this->getMoon ()->setAutoDisableThreshold (0.05);
} catch (Caelum::UnsupportedException& ex) {
LogManager::getSingleton ().logMessage (
"Caelum: Failed to initialize moon: " + ex.getFullDescription());
}
}
if (componentsToCreate & CAELUM_COMPONENT_IMAGE_STARFIELD) {
try {
this->setImageStarfield (new ImageStarfield (mSceneMgr, getCaelumCameraNode ()));
} catch (Caelum::UnsupportedException& ex) {
LogManager::getSingleton ().logMessage (
"Caelum: Failed to initialize the old image starfield: " + ex.getFullDescription());
}
}
if (componentsToCreate & CAELUM_COMPONENT_POINT_STARFIELD) {
try {
this->setPointStarfield (new PointStarfield (mSceneMgr, getCaelumCameraNode ()));
} catch (Caelum::UnsupportedException& ex) {
LogManager::getSingleton ().logMessage (
"Caelum: Failed to initialize starfield: " + ex.getFullDescription());
}
}
if (componentsToCreate & CAELUM_COMPONENT_GROUND_FOG) {
try {
this->setGroundFog (new GroundFog (mSceneMgr, getCaelumCameraNode ()));
} catch (Caelum::UnsupportedException& ex) {
LogManager::getSingleton ().logMessage (
"Caelum: Failed to initialize ground fog: " + ex.getFullDescription());
}
}
if (componentsToCreate & CAELUM_COMPONENT_CLOUDS) {
try {
this->setCloudSystem (new CloudSystem (mSceneMgr, getCaelumGroundNode ()));
getCloudSystem ()->createLayerAtHeight (3000);
getCloudSystem ()->getLayer (0)->setCloudCover (0.3);
} catch (Caelum::UnsupportedException& ex) {
LogManager::getSingleton ().logMessage (
"Caelum: Failed to initialize clouds: " + ex.getFullDescription());
}
}
if (componentsToCreate & CAELUM_COMPONENT_PRECIPITATION) {
try {
this->setPrecipitationController (new PrecipitationController (mSceneMgr));
} catch (Caelum::UnsupportedException& ex) {
LogManager::getSingleton ().logMessage (
"Caelum: Failed to initialize precipitation: " + ex.getFullDescription());
}
}
if (componentsToCreate & CAELUM_COMPONENT_SCREEN_SPACE_FOG) {
try {
this->setDepthComposer (new DepthComposer (mSceneMgr));
} catch (Caelum::UnsupportedException& ex) {
LogManager::getSingleton ().logMessage (
"Caelum: Failed to initialize precipitation: " + ex.getFullDescription());
}
}
LogManager::getSingleton ().logMessage ("Caelum: DONE initializing");
}
void CaelumSystem::shutdown (const bool cleanup) {
LogManager::getSingleton ().logMessage ("Caelum: Shutting down Caelum system...");
destroySubcomponents (true);
if (cleanup) {
mOgreRoot->removeFrameListener (this);
delete this;
} else {
// We'll delete later. Make sure we're registered as a frame listener, or we'd leak.
mOgreRoot->addFrameListener(this);
mCleanup = true;
}
}
void CaelumSystem::attachViewportImpl (Ogre::Viewport* vp)
{
LogManager::getSingleton().getDefaultLog ()->logMessage (
"CaelumSystem: Attached to"
" viewport " + StringConverter::toString ((long)vp) +
" render target " + vp->getTarget ()->getName ());
if (getAutoAttachViewportsToComponents ()) {
if (getPrecipitationController ()) {
getPrecipitationController ()->createViewportInstance (vp);
}
if (getDepthComposer ()) {
getDepthComposer ()->createViewportInstance (vp);
}
}
}
void CaelumSystem::detachViewportImpl (Ogre::Viewport* vp)
{
LogManager::getSingleton().getDefaultLog ()->logMessage (
"CaelumSystem: Detached from "
" viewport " + StringConverter::toString ((long)vp) +
" render target " + vp->getTarget ()->getName ());
if (getAutoAttachViewportsToComponents ()) {
if (getPrecipitationController ()) {
getPrecipitationController ()->destroyViewportInstance (vp);
}
if (getDepthComposer ()) {
getDepthComposer ()->destroyViewportInstance (vp);
}
}
}
void CaelumSystem::attachViewport (Ogre::Viewport* vp)
{
bool found = !mAttachedViewports.insert (vp).second;
if (!found) {
attachViewportImpl (vp);
}
}
void CaelumSystem::detachViewport (Ogre::Viewport* vp)
{
std::set<Viewport*>::size_type erase_result = mAttachedViewports.erase(vp);
assert(erase_result == 0 || erase_result == 1);
bool found = erase_result == 1;
if (found) {
detachViewportImpl (vp);
}
}
void CaelumSystem::detachAllViewports ()
{
std::set<Viewport*>::const_iterator it = mAttachedViewports.begin(), end = mAttachedViewports.end();
for (; it != end; ++it) {
detachViewportImpl (*it);
}
mAttachedViewports.clear();
}
bool CaelumSystem::isViewportAttached (Ogre::Viewport* vp) const {
return mAttachedViewports.find (vp) != mAttachedViewports.end();
}
void CaelumSystem::setSkyDome (SkyDome *obj) {
mSkyDome.reset (obj);
}
void CaelumSystem::setSun (BaseSkyLight* obj) {
mSun.reset (obj);
}
void CaelumSystem::setMoon (Moon* obj) {
mMoon.reset (obj);
}
void CaelumSystem::setImageStarfield (ImageStarfield* obj) {
mImageStarfield.reset (obj);
}
void CaelumSystem::setPointStarfield (PointStarfield* obj) {
mPointStarfield.reset (obj);
}
void CaelumSystem::setGroundFog (GroundFog* obj) {
mGroundFog.reset (obj);
}
void CaelumSystem::setCloudSystem (CloudSystem* obj) {
mCloudSystem.reset (obj);
}
void CaelumSystem::setPrecipitationController (PrecipitationController* newptr) {
PrecipitationController* oldptr = getPrecipitationController ();
if (oldptr == newptr) {
return;
}
// Detach old
if (getAutoAttachViewportsToComponents() && oldptr) {
std::for_each (mAttachedViewports.begin(), mAttachedViewports.end(),
std::bind1st (std::mem_fun (&PrecipitationController::destroyViewportInstance), oldptr));
}
// Attach new.
if (getAutoAttachViewportsToComponents() && newptr) {
std::for_each (mAttachedViewports.begin(), mAttachedViewports.end(),
std::bind1st (std::mem_fun (&PrecipitationController::createViewportInstance), newptr));
}
mPrecipitationController.reset(newptr);
}
void CaelumSystem::setDepthComposer (DepthComposer* ptr) {
mDepthComposer.reset(ptr);
if (getAutoAttachViewportsToComponents() && getDepthComposer ()) {
std::for_each (
mAttachedViewports.begin(), mAttachedViewports.end(),
std::bind1st (
std::mem_fun (&DepthComposer::createViewportInstance),
getDepthComposer ()));
}
}
void CaelumSystem::preViewportUpdate (const Ogre::RenderTargetViewportEvent &e) {
Ogre::Viewport *viewport = e.source;
Ogre::Camera *camera = viewport->getCamera ();
if (getAutoViewportBackground ()) {
viewport->setBackgroundColour (Ogre::ColourValue::Black);
}
if (getAutoNotifyCameraChanged ()) {
this->notifyCameraChanged (camera);
}
}
void CaelumSystem::notifyCameraChanged(Ogre::Camera* cam)
{
// Move camera node.
if (getAutoMoveCameraNode ()) {
mCaelumCameraNode->setPosition (cam->getDerivedPosition());
mCaelumCameraNode->_update (true, true);
}
if (getSkyDome ()) {
getSkyDome ()->notifyCameraChanged (cam);
}
if (getSun ()) {
getSun ()->notifyCameraChanged (cam);
}
if (getMoon ()) {
getMoon ()->notifyCameraChanged (cam);
}
if (getImageStarfield ()) {
getImageStarfield ()->notifyCameraChanged (cam);
}
if (getPointStarfield ()) {
getPointStarfield ()->notifyCameraChanged (cam);
}
if (getGroundFog ()) {
getGroundFog ()->notifyCameraChanged (cam);
}
}
bool CaelumSystem::frameStarted (const Ogre::FrameEvent &e) {
if (mCleanup) {
// Delayed destruction.
mOgreRoot->removeFrameListener (this);
delete this;
return true;
}
updateSubcomponents(e.timeSinceLastFrame);
return true;
}
void CaelumSystem::updateSubcomponents (Real timeSinceLastFrame)
{
/*
LogManager::getSingleton().getDefaultLog()->logMessage(
"CaelumSystem::updateSubcomponents: " +
StringConverter::toString (timeSinceLastFrame, 10));
*/
mUniversalClock->update (timeSinceLastFrame);
// Timing variables
LongReal julDay = mUniversalClock->getJulianDay ();
LongReal relDayTime = fmod(julDay, 1);
Real secondDiff = timeSinceLastFrame * mUniversalClock->getTimeScale ();
// Get astronomical parameters.
Ogre::Vector3 sunDir = getSunDirection(julDay);
Ogre::Vector3 moonDir = getMoonDirection(julDay);
Real moonPhase = getMoonPhase(julDay);
// Get parameters from sky colour model.
Real fogDensity = getFogDensity (relDayTime, sunDir);
Ogre::ColourValue fogColour = getFogColour (relDayTime, sunDir);
Ogre::ColourValue sunLightColour = getSunLightColour (relDayTime, sunDir);
Ogre::ColourValue sunSphereColour = getSunSphereColour (relDayTime, sunDir);
Ogre::ColourValue moonLightColour = getMoonLightColour (moonDir);
Ogre::ColourValue moonBodyColour = getMoonBodyColour (moonDir);
fogDensity *= mGlobalFogDensityMultiplier;
fogColour = fogColour * mGlobalFogColourMultiplier;
// Update image starfield
if (getImageStarfield ()) {
getImageStarfield ()->update (relDayTime);
getImageStarfield ()->setInclination (-getObserverLatitude ());
}
// Update point starfield
if (getPointStarfield ()) {
getPointStarfield ()->setObserverLatitude (getObserverLatitude ());
getPointStarfield ()->setObserverLongitude (getObserverLongitude ());
getPointStarfield ()->_update (relDayTime);
}
// Update skydome.
if (getSkyDome ()) {
getSkyDome ()->setSunDirection (sunDir);
getSkyDome ()->setHazeColour (fogColour * mSceneFogColourMultiplier);
}
// Update scene fog.
if (getManageSceneFog ()) {
mSceneMgr->setFog (Ogre::FOG_EXP2,
fogColour * mSceneFogColourMultiplier,
fogDensity * mSceneFogDensityMultiplier);
}
// Update ground fog.
if (getGroundFog ()) {
getGroundFog ()->setColour (fogColour * mGroundFogColourMultiplier);
getGroundFog ()->setDensity (fogDensity * mGroundFogDensityMultiplier);
}
// Update sun
if (getSun ()) {
mSun->update (sunDir, sunLightColour, sunSphereColour);
}
// Update moon.
if (getMoon ()) {
mMoon->update (
moonDir,
moonLightColour,
moonBodyColour);
mMoon->setPhase (moonPhase);
}
// Update clouds
if (getCloudSystem ()) {
getCloudSystem ()->update (
secondDiff, sunDir, sunLightColour, fogColour, sunSphereColour);
}
// Update precipitation
if (getPrecipitationController ()) {
getPrecipitationController ()->update (secondDiff, fogColour);
}
// Update screen space fog
if (getDepthComposer ()) {
getDepthComposer ()->update ();
getDepthComposer ()->setSunDirection (sunDir);
getDepthComposer ()->setHazeColour (fogColour);
getDepthComposer ()->setGroundFogColour (fogColour * mGroundFogColourMultiplier);
getDepthComposer ()->setGroundFogDensity (fogDensity * mGroundFogDensityMultiplier);
}
// Update ambient lighting.
if (getManageAmbientLight ()) {
Ogre::ColourValue ambient = Ogre::ColourValue::Black;
if (getMoon ()) {
ambient += getMoon ()->getLightColour () * getMoon ()->getAmbientMultiplier ();
}
if (getSun ()) {
ambient += getSun ()->getLightColour () * getSun ()->getAmbientMultiplier ();
}
ambient.r = std::max(ambient.r, mMinimumAmbientLight.r);
ambient.g = std::max(ambient.g, mMinimumAmbientLight.g);
ambient.b = std::max(ambient.b, mMinimumAmbientLight.b);
ambient.a = std::max(ambient.a, mMinimumAmbientLight.a);
// Debug ambient factos (ick).
/*
LogManager::getSingleton().logMessage (
"Sun is " + StringConverter::toString(sunLightColour) + "\n"
"Moon is " + StringConverter::toString(moonLightColour) + "\n"
"Ambient is " + StringConverter::toString(ambient) + "\n"
);
*/
mSceneMgr->setAmbientLight (ambient);
}
if (getSun() && getMoon ()) {
Ogre::Real moonBrightness = moonLightColour.r + moonLightColour.g + moonLightColour.b + moonLightColour.a;
Ogre::Real sunBrightness = sunLightColour.r + sunLightColour.g + sunLightColour.b + sunLightColour.a;
bool sunBrighterThanMoon = (sunBrightness > moonBrightness);
if (getEnsureSingleLightSource ()) {
getMoon ()->setForceDisable (sunBrighterThanMoon);
getSun ()->setForceDisable (!sunBrighterThanMoon);
}
if (getEnsureSingleShadowSource ()) {
getMoon ()->getMainLight ()->setCastShadows (!sunBrighterThanMoon);
getSun ()->getMainLight ()->setCastShadows (sunBrighterThanMoon);
}
}
}
void CaelumSystem::setManageSceneFog (bool value) {
mManageSceneFog = value;
// Prevent having some stale values around.
if (!value) {
mSceneMgr->setFog (Ogre::FOG_NONE);
}
}
bool CaelumSystem::getManageSceneFog () const {
return mManageSceneFog;
}
void CaelumSystem::setSceneFogDensityMultiplier (Real value) {
mSceneFogDensityMultiplier = value;
}
Real CaelumSystem::getSceneFogDensityMultiplier () const {
return mSceneFogDensityMultiplier;
}
void CaelumSystem::setGroundFogDensityMultiplier (Real value) {
mGroundFogDensityMultiplier = value;
}
Real CaelumSystem::getGroundFogDensityMultiplier () const {
return mGroundFogDensityMultiplier;
}
void CaelumSystem::setGlobalFogDensityMultiplier (Real value) {
mGlobalFogDensityMultiplier = value;
}
Real CaelumSystem::getGlobalFogDensityMultiplier () const {
return mGlobalFogDensityMultiplier;
}
void CaelumSystem::setSkyGradientsImage (const Ogre::String &filename) {
mSkyGradientsImage.reset(new Ogre::Image ());
mSkyGradientsImage->load (filename, RESOURCE_GROUP_NAME);
}
void CaelumSystem::setSunColoursImage (const Ogre::String &filename) {
mSunColoursImage.reset(new Ogre::Image ());
mSunColoursImage->load (filename, RESOURCE_GROUP_NAME);
}
Ogre::ColourValue CaelumSystem::getFogColour (Real time, const Ogre::Vector3 &sunDir) {
if (!mSkyGradientsImage.get()) {
return Ogre::ColourValue::Black;
}
Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, 1, mSkyGradientsImage.get(), false);
return col;
}
Real CaelumSystem::getFogDensity (Real time, const Ogre::Vector3 &sunDir)
{
if (!mSkyGradientsImage.get()) {
return 0;
}
Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, 1, mSkyGradientsImage.get(), false);
return col.a;
}
Ogre::ColourValue CaelumSystem::getSunSphereColour (Real time, const Ogre::Vector3 &sunDir)
{
if (!mSunColoursImage.get()) {
return Ogre::ColourValue::White;
}
Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y);
elevation = elevation * 2 + 0.4;
return InternalUtilities::getInterpolatedColour (elevation, 1, mSunColoursImage.get(), false);
}
Ogre::ColourValue CaelumSystem::getSunLightColour (Real time, const Ogre::Vector3 &sunDir)
{
if (!mSkyGradientsImage.get()) {
exit(-1);
return Ogre::ColourValue::White;
}
Real elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
// Hack: return averaged sky colours.
// Don't use an alpha value for lights, this can cause nasty problems.
Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, elevation, mSkyGradientsImage.get(), false);
Real val = (col.r + col.g + col.b) / 3;
col = Ogre::ColourValue(val, val, val, 1.0);
assert(Ogre::Math::RealEqual(col.a, 1));
return col;
}
Ogre::ColourValue CaelumSystem::getMoonBodyColour (const Ogre::Vector3 &moonDir) {
return Ogre::ColourValue::White;
}
Ogre::ColourValue CaelumSystem::getMoonLightColour (const Ogre::Vector3 &moonDir)
{
if (!mSkyGradientsImage.get()) {
return Ogre::ColourValue::Blue;
}
// Scaled version of getSunLightColor
Real elevation = moonDir.dotProduct (Ogre::Vector3::UNIT_Y) * 0.5 + 0.5;
Ogre::ColourValue col = InternalUtilities::getInterpolatedColour (elevation, elevation, mSkyGradientsImage.get(), false);
Real val = (col.r + col.g + col.b) / 3;
col = Ogre::ColourValue(val / 2.5f, val / 2.5f, val / 2.5f, 1.0);
assert(Ogre::Math::RealEqual(col.a, 1));
return col;
}
const Ogre::Vector3 CaelumSystem::makeDirection (
Ogre::Degree azimuth, Ogre::Degree altitude)
{
Ogre::Vector3 res;
res.z = -Ogre::Math::Cos (azimuth) * Ogre::Math::Cos (altitude); // North
res.x = Ogre::Math::Sin (azimuth) * Ogre::Math::Cos (altitude); // East
res.y = -Ogre::Math::Sin (altitude); // Zenith
return res;
}
const Ogre::Vector3 CaelumSystem::getSunDirection (LongReal jday)
{
Ogre::Degree azimuth, altitude;
{
ScopedHighPrecissionFloatSwitch precissionSwitch;
Astronomy::getHorizontalSunPosition(jday,
getObserverLongitude(), getObserverLatitude(),
azimuth, altitude);
}
Ogre::Vector3 res = makeDirection(azimuth, altitude);
return res;
}
const Ogre::Vector3 CaelumSystem::getMoonDirection (LongReal jday)
{
Ogre::Degree azimuth, altitude;
{
ScopedHighPrecissionFloatSwitch precissionSwitch;
Astronomy::getHorizontalMoonPosition(jday,
getObserverLongitude (), getObserverLatitude (),
azimuth, altitude);
}
Ogre::Vector3 res = makeDirection(azimuth, altitude);
return res;
}
const Ogre::Real CaelumSystem::getMoonPhase (LongReal jday)
{
// Calculates julian days since January 22, 2008 13:36 (full moon)
// and divides by the time between lunations (synodic month)
LongReal T = (jday - 2454488.0665L) / 29.531026L;
T = fabs(fmod(T, 1));
return -fabs(-4 * T + 2) + 2;
}
void CaelumSystem::forceSubcomponentQueryFlags (uint flags)
{
if (getSkyDome ()) getSkyDome ()->setQueryFlags (flags);
if (getSun ()) getSun ()->setQueryFlags (flags);
if (getMoon ()) getMoon ()->setQueryFlags (flags);
if (getImageStarfield ()) getImageStarfield ()->setQueryFlags (flags);
if (getPointStarfield ()) getPointStarfield ()->setQueryFlags (flags);
if (getGroundFog ()) getGroundFog ()->setQueryFlags (flags);
if (getCloudSystem ()) getCloudSystem ()->forceLayerQueryFlags (flags);
}
void CaelumSystem::forceSubcomponentVisibilityFlags (uint flags)
{
if (getSkyDome ()) getSkyDome ()->setVisibilityFlags (flags);
if (getSun ()) getSun ()->setVisibilityFlags (flags);
if (getMoon ()) getMoon ()->setVisibilityFlags (flags);
if (getImageStarfield ()) getImageStarfield ()->setVisibilityFlags (flags);
if (getPointStarfield ()) getPointStarfield ()->setVisibilityFlags (flags);
if (getGroundFog ()) getGroundFog ()->setVisibilityFlags (flags);
if (getCloudSystem ()) getCloudSystem ()->forceLayerVisibilityFlags (flags);
}
}

@ -0,0 +1,66 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "CameraBoundElement.h"
namespace Caelum
{
const Ogre::Real CameraBoundElement::CAMERA_NEAR_DISTANCE_MULTIPLIER = 10;
CameraBoundElement::CameraBoundElement():
mAutoRadius(true)
{
}
CameraBoundElement::~CameraBoundElement()
{
}
void CameraBoundElement::notifyCameraChanged (Ogre::Camera *cam) {
if (mAutoRadius) {
if (cam->getFarClipDistance () > 0) {
setFarRadius((cam->getFarClipDistance () + cam->getNearClipDistance ()) / 2);
} else {
setFarRadius(cam->getNearClipDistance () * CAMERA_NEAR_DISTANCE_MULTIPLIER);
}
}
}
void CameraBoundElement::forceFarRadius (Ogre::Real radius) {
if (radius > 0) {
mAutoRadius = false;
setFarRadius(radius);
} else {
mAutoRadius = true;
}
}
bool CameraBoundElement::getAutoRadius () const {
return mAutoRadius;
}
void CameraBoundElement::setAutoRadius () {
forceFarRadius (-1);
}
void CameraBoundElement::setFarRadius(Ogre::Real radius) {
}
}

@ -0,0 +1,95 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "CloudSystem.h"
#include "FlatCloudLayer.h"
using namespace Ogre;
namespace Caelum
{
CloudSystem::CloudSystem(
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *cloudRoot)
{
mSceneMgr = sceneMgr;
mCloudRoot = cloudRoot;
}
FlatCloudLayer* CloudSystem::createLayerAtHeight(Ogre::Real height)
{
FlatCloudLayer* layer = this->createLayer ();
layer->setHeight(height);
return layer;
}
FlatCloudLayer* CloudSystem::createLayer()
{
std::auto_ptr<FlatCloudLayer> layer(new FlatCloudLayer(mSceneMgr, mCloudRoot));
mLayers.push_back(layer.get());
return layer.release();
}
void CloudSystem::addLayer(FlatCloudLayer* layer)
{
assert(layer != NULL);
mLayers.push_back(layer);
}
void CloudSystem::clearLayers()
{
for (unsigned i = 0; i < mLayers.size(); i++)
{
delete mLayers[i];
mLayers[i] = 0;
}
}
CloudSystem::~CloudSystem()
{
clearLayers ();
}
void CloudSystem::update(
Ogre::Real timePassed,
const Ogre::Vector3 &sunDirection,
const Ogre::ColourValue &sunLightColour,
const Ogre::ColourValue &fogColour,
const Ogre::ColourValue &sunSphereColour)
{
for (uint i = 0; i < mLayers.size(); i++) {
assert(mLayers[i] != NULL);
mLayers[i]->update(timePassed, sunDirection, sunLightColour, fogColour, sunSphereColour);
}
}
void CloudSystem::forceLayerQueryFlags (uint flags) {
for (uint i = 0; i < mLayers.size(); i++) {
mLayers[i]->setQueryFlags (flags);
}
}
void CloudSystem::forceLayerVisibilityFlags (uint flags) {
for (uint i = 0; i < mLayers.size(); i++) {
mLayers[i]->setVisibilityFlags (flags);
}
}
}

@ -0,0 +1,491 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "CaelumExceptions.h"
#include "DepthComposer.h"
using namespace Ogre;
namespace Caelum
{
DepthComposer::DepthComposer
(
Ogre::SceneManager *sceneMgr
):
mSceneMgr (sceneMgr),
mDebugDepthRender (false),
mSkyDomeHazeEnabled (false),
mGroundFogEnabled (false),
mGroundFogDensity (0.1),
mGroundFogBaseLevel (5),
mGroundFogVerticalDecay (0.2),
mGroundFogColour (ColourValue::Black)
{
}
DepthComposer::~DepthComposer()
{
destroyAllViewportInstances();
}
void DepthComposer::setDebugDepthRender (bool value)
{
if (mDebugDepthRender == value) {
return;
}
mDebugDepthRender = value;
onCompositorMaterialChanged ();
}
void DepthComposer::setSkyDomeHazeEnabled (bool value)
{
if (mSkyDomeHazeEnabled == value) {
return;
}
mSkyDomeHazeEnabled = value;
onCompositorMaterialChanged ();
}
void DepthComposer::setGroundFogEnabled (bool value)
{
if (mGroundFogEnabled == value) {
return;
}
mGroundFogEnabled = value;
onCompositorMaterialChanged ();
}
const String& DepthComposer::getCompositorName ()
{
// Constant Ogre::Strings for names.
static const Ogre::String CompositorName_DebugDepthRender =
"Caelum/DepthComposer_DebugDepthRender";
static const Ogre::String CompositorName_Dummy =
"Caelum/DepthComposer_Dummy";
static const Ogre::String CompositorName_ExpGroundFog =
"Caelum/DepthComposer_ExpGroundFog";
static const Ogre::String CompositorName_SkyDomeHaze =
"Caelum/DepthComposer_SkyDomeHaze";
static const Ogre::String CompositorName_SkyDomeHaze_ExpGroundFog =
"Caelum/DepthComposer_SkyDomeHaze_ExpGroundFog";
// Should probably build materials and compositors by hand.
if (mDebugDepthRender) {
return CompositorName_DebugDepthRender;
} else if (mSkyDomeHazeEnabled == false && mGroundFogEnabled == false) {
return CompositorName_Dummy;
} else if (mSkyDomeHazeEnabled == false && mGroundFogEnabled == true) {
return CompositorName_ExpGroundFog;
} else if (mSkyDomeHazeEnabled == true && mGroundFogEnabled == false) {
return CompositorName_SkyDomeHaze;
} else if (mSkyDomeHazeEnabled == true && mGroundFogEnabled == true) {
return CompositorName_SkyDomeHaze_ExpGroundFog;
} else {
assert (0);
return CompositorName_Dummy;
}
}
void DepthComposer::onCompositorMaterialChanged ()
{
ViewportInstanceMap::const_iterator it;
ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
for (it = begin; it != end; ++it) {
it->second->removeCompositor ();
it->second->addCompositor ();
}
}
void DepthComposer::update ()
{
ViewportInstanceMap::const_iterator it;
ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
for (it = begin; it != end; ++it) {
assert(it->first == it->second->getViewport());
it->second->_update ();
}
}
DepthComposerInstance::DepthComposerInstance
(
DepthComposer* parent,
Ogre::Viewport* viewport
):
mParent(parent),
mViewport(viewport),
mCompInst(0)
{
LogManager::getSingleton().logMessage (
"Caelum::DepthComposer: Attaching screen-space fog instance"
" to viewport \'" + StringConverter::toString ((long)getViewport ()) + "\'"
" of render target \'" + getViewport()->getTarget ()->getName () + "\'");
addCompositor ();
mDepthRenderer.reset (new DepthRenderer (getViewport ()));
}
DepthComposerInstance::~DepthComposerInstance()
{
removeCompositor ();
mDepthRenderer.reset ();
LogManager::getSingleton().logMessage (
"Caelum::DepthComposer: Detached screen-space fog instance"
" from viewport \'" + StringConverter::toString ((long)getViewport ()) + "\'"
" of render target \'" + getViewport()->getTarget ()->getName () + "\'");
}
void DepthComposerInstance::addCompositor ()
{
CompositorManager* compMgr = CompositorManager::getSingletonPtr();
const String& compositorName = getParent ()->getCompositorName ();
mCompInst = compMgr->addCompositor(mViewport, compositorName);
if (!mCompInst) {
CAELUM_THROW_UNSUPPORTED_EXCEPTION (
"Can't add \'" + compositorName + "\' compositor.",
"DepthComposer");
}
assert(mCompInst);
mCompInst->setEnabled (true);
mCompInst->addListener (this);
}
void DepthComposerInstance::removeCompositor ()
{
CompositorManager* compMgr = CompositorManager::getSingletonPtr();
compMgr->removeCompositor (mViewport, mCompInst->getCompositor ()->getName ());
mCompInst = 0;
}
void DepthComposerInstance::notifyMaterialSetup(uint pass_id, Ogre::MaterialPtr &mat)
{
//LogManager::getSingleton ().logMessage (
// "Caelum::DepthComposer: Material setup");
Pass* pass = mat->getBestTechnique ()->getPass (0);
TextureUnitState *depthTus = pass->getTextureUnitState(1);
if (depthTus->getTextureName () != mDepthRenderer->getDepthRenderTexture ()->getName()) {
depthTus->setTextureName (mDepthRenderer->getDepthRenderTexture ()->getName ());
LogManager::getSingleton ().logMessage (
"Caelum::DepthComposer: Assigned depth texture in compositor material");
}
mParams.setup(pass->getFragmentProgramParameters ());
}
void DepthComposerInstance::Params::setup(Ogre::GpuProgramParametersSharedPtr fpParams)
{
this->fpParams = fpParams;
invViewProjMatrix.bind(fpParams, "invViewProjMatrix");
worldCameraPos.bind(fpParams, "worldCameraPos");
groundFogDensity.bind(fpParams, "groundFogDensity");
groundFogVerticalDecay.bind(fpParams, "groundFogVerticalDecay");
groundFogBaseLevel.bind(fpParams, "groundFogBaseLevel");
groundFogColour.bind(fpParams, "groundFogColour");
sunDirection.bind(fpParams, "sunDirection");
hazeColour.bind(fpParams, "hazeColour");
}
void DepthComposerInstance::notifyMaterialRender(uint pass_id, Ogre::MaterialPtr &mat)
{
Camera* camera = getViewport ()->getCamera ();
assert(mParams.fpParams == mat->getBestTechnique ()->getPass (0)->getFragmentProgramParameters ());
// Auto param in a compositor does not use the external camera.
// This means that sending matrices as auto_param will not work as expected.
// Do it manually instead.
Matrix4 projMatrix = camera->getProjectionMatrixWithRSDepth();
Matrix4 viewMatrix = camera->getViewMatrix();
mParams.invViewProjMatrix.set(mParams.fpParams, (projMatrix * viewMatrix).inverse());
mParams.worldCameraPos.set(mParams.fpParams, camera->getDerivedPosition ());
mParams.groundFogDensity.set(mParams.fpParams, getParent ()->getGroundFogDensity ());
mParams.groundFogVerticalDecay.set(mParams.fpParams, getParent ()->getGroundFogVerticalDecay ());
mParams.groundFogBaseLevel.set(mParams.fpParams, getParent ()->getGroundFogBaseLevel ());
mParams.groundFogColour.set(mParams.fpParams, getParent ()->getGroundFogColour ());
mParams.sunDirection.set(mParams.fpParams, getParent ()->getSunDirection ());
mParams.hazeColour.set(mParams.fpParams, getParent ()->getHazeColour ());
}
void DepthComposerInstance::_update ()
{
mDepthRenderer->update ();
}
DepthComposerInstance* DepthComposer::createViewportInstance(Ogre::Viewport* vp)
{
ViewportInstanceMap::const_iterator it = mViewportInstanceMap.find(vp);
if (it == mViewportInstanceMap.end()) {
std::auto_ptr<DepthComposerInstance> inst(new DepthComposerInstance(this, vp));
mViewportInstanceMap.insert(std::make_pair(vp, inst.get()));
// hold instance until successfully added to map.
return inst.release();
} else {
return it->second;
}
}
DepthComposerInstance* DepthComposer::getViewportInstance(Ogre::Viewport* vp) {
ViewportInstanceMap::iterator it = mViewportInstanceMap.find(vp);
if (it != mViewportInstanceMap.end()) {
return it->second;
} else {
return 0;
}
}
void DepthComposer::destroyViewportInstance(Viewport* vp)
{
ViewportInstanceMap::iterator it = mViewportInstanceMap.find(vp);
if (it != mViewportInstanceMap.end()) {
DepthComposerInstance* inst = it->second;
delete inst;
mViewportInstanceMap.erase(it);
}
}
void DepthComposer::destroyAllViewportInstances() {
ViewportInstanceMap::const_iterator it;
ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
for (it = begin; it != end; ++it) {
assert(it->first == it->second->getViewport());
delete it->second;
}
mViewportInstanceMap.clear();
}
const String DepthRenderer::DEFAULT_CUSTOM_DEPTH_SCHEME_NAME = "CaelumDepth";
DepthRenderer::DepthRenderer
(
Viewport* masterViewport
):
mMasterViewport (masterViewport),
mDepthRenderViewport (0),
mDepthRenderingNow (false),
mViewportVisibilityMask (~0),
mUseCustomDepthScheme (true),
mCustomDepthSchemeName (DEFAULT_CUSTOM_DEPTH_SCHEME_NAME)
{
disableRenderGroupRangeFilter ();
Ogre::String uniqueId = Ogre::StringConverter::toString ((size_t)this);
// Not cloned!
mDepthRenderMaterial = MaterialManager::getSingleton ().getByName ("Caelum/DepthRender");
mDepthRenderMaterial->load();
if (!mDepthRenderMaterial->getBestTechnique ()) {
CAELUM_THROW_UNSUPPORTED_EXCEPTION (
"Can't load depth render material: " +
mDepthRenderMaterial->getUnsupportedTechniquesExplanation(),
"DepthComposer");
}
TextureManager* texMgr = TextureManager::getSingletonPtr();
int width = getMasterViewport ()->getActualWidth ();
int height = getMasterViewport ()->getActualHeight ();
LogManager::getSingleton ().logMessage (
"Caelum::DepthRenderer: Creating depth render texture size " +
StringConverter::toString (width) +
"x" +
StringConverter::toString (height));
PixelFormat desiredFormat = PF_FLOAT32_R;
PixelFormat requestFormat = desiredFormat;
if (texMgr->isFormatSupported (TEX_TYPE_2D, desiredFormat, TU_RENDERTARGET)) {
LogManager::getSingleton ().logMessage (
"Caelum::DepthRenderer: RenderSystem has native support for " +
PixelUtil::getFormatName (desiredFormat));
} else if (texMgr->isEquivalentFormatSupported (TEX_TYPE_2D, desiredFormat, TU_RENDERTARGET)) {
PixelFormat equivFormat = texMgr->getNativeFormat (TEX_TYPE_2D, desiredFormat, TU_RENDERTARGET);
LogManager::getSingleton ().logMessage (
"Caelum::DepthRenderer: RenderSystem supports " +
PixelUtil::getFormatName (equivFormat) +
" instead of " +
PixelUtil::getFormatName (desiredFormat));
requestFormat = equivFormat;
} else {
CAELUM_THROW_UNSUPPORTED_EXCEPTION (
PixelUtil::getFormatName(desiredFormat) + " or equivalent not supported",
"DepthRenderer");
}
if (texMgr->isHardwareFilteringSupported (TEX_TYPE_2D, requestFormat, TU_RENDERTARGET)) {
LogManager::getSingleton ().logMessage (
"Caelum::DepthRenderer: RenderSystem supports hardware filtering for " +
PixelUtil::getFormatName (requestFormat));
} else {
LogManager::getSingleton ().logMessage (
"Caelum::DepthRenderer: RenderSystem does not support hardware filtering for " +
PixelUtil::getFormatName (requestFormat));
}
// Create depth texture.
// This depends on the size of the viewport.
mDepthRenderTexture = texMgr->createManual(
"Caelum/DepthComposer/" + uniqueId + "/DepthTexture",
Caelum::RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
width, height, 1,
0,
requestFormat,
TU_RENDERTARGET,
0);
assert(getDepthRenderTarget());
// Should be the same format
LogManager::getSingleton().logMessage (
"Caelum::DepthRenderer: Created depth render texture"
" actual format " + PixelUtil::getFormatName (getDepthRenderTexture()->getFormat ()) +
" desired format " + PixelUtil::getFormatName (getDepthRenderTexture()->getDesiredFormat ()));
// We do our updates by hand.
getDepthRenderTarget()->setAutoUpdated (false);
// Viewport for the depth rtt. Don't set camera here; it can mess Camera::getViewport();
mDepthRenderViewport = getDepthRenderTarget()->addViewport(0);
getDepthRenderViewport ()->setShadowsEnabled (false);
getDepthRenderViewport ()->setOverlaysEnabled (false);
getDepthRenderViewport ()->setClearEveryFrame (true);
// Depth buffer values range from 0 to 1 in both OpenGL and Directx; unless depth ranges are used.
// Clear to the maximum value.
getDepthRenderViewport ()->setBackgroundColour (Ogre::ColourValue (1, 1, 1, 1));
}
DepthRenderer::~DepthRenderer()
{
TextureManager* texMgr = TextureManager::getSingletonPtr();
// Destroy render texture.
if (!mDepthRenderTexture.isNull ()) {
texMgr->remove (mDepthRenderTexture->getHandle ());
mDepthRenderTexture.setNull ();
}
}
void DepthRenderer::update ()
{
Camera* camera = getMasterViewport ()->getCamera ();
Viewport* oldCameraViewport = camera->getViewport ();
SceneManager *sceneManager = camera->getSceneManager ();
assert (oldCameraViewport == getMasterViewport ());
assert (getDepthRenderViewport ()->getActualWidth () == getMasterViewport()->getActualWidth ());
assert (getDepthRenderViewport ()->getActualHeight () == getMasterViewport()->getActualHeight ());
getDepthRenderViewport ()->setVisibilityMask (mViewportVisibilityMask);
getDepthRenderViewport ()->setCamera (camera);
if (this->getUseCustomDepthScheme ()) {
getDepthRenderViewport ()->setMaterialScheme (this->getCustomDepthSchemeName ());
}
// Restore old listener after we're done.
// Hopefully this will not break horribly.
RenderQueue::RenderableListener* oldListener = sceneManager->getRenderQueue ()->getRenderableListener();
if (oldListener) {
//LogManager::getSingleton ().logMessage (
// "Caelum: Found another render queue listener. This could be bad.");
}
sceneManager->getRenderQueue ()->setRenderableListener (this);
mDepthRenderingNow = true;
//LogManager::getSingleton ().logMessage ("Caelum: Begin depth rendering");
getDepthRenderTarget ()->update ();
//LogManager::getSingleton ().logMessage ("Caelum: End depth rendering");
mDepthRenderingNow = false;
sceneManager->getRenderQueue ()->setRenderableListener (oldListener);
oldListener = 0;
// Restore the camera's viewport. Ogre compositors do the same thing.
camera->_notifyViewport (oldCameraViewport);
}
#if OGRE_VERSION < 0x00010600
bool DepthRenderer::renderableQueued(
Ogre::Renderable* rend,
Ogre::uint8 groupId,
Ogre::ushort priority,
Ogre::Technique** ppTech)
#else
bool DepthRenderer::renderableQueued(
Ogre::Renderable* rend,
Ogre::uint8 groupId,
Ogre::ushort priority,
Ogre::Technique** ppTech,
Ogre::RenderQueue* pQueue)
#endif // OGRE_VERSION
{
assert (mDepthRenderingNow);
/*
LogManager::getSingleton ().logMessage (
"Caelum: Renderable queued"
" group " + StringConverter::toString (groupId) +
" priority " + StringConverter::toString (priority));
*/
if (groupId < mMinRenderGroupId || groupId > mMaxRenderGroupId) {
return false;
}
if (this->getUseCustomDepthScheme () && (*ppTech)->getSchemeName () == this->getCustomDepthSchemeName ()) {
/*
LogManager::getSingleton().getDefaultLog()->logMessage (
"Custom scheme with tech " + (*ppTech)->getName () +
" passCount " + StringConverter::toString ((*ppTech)->getNumPasses ()) +
" vp " + (*ppTech)->getPass (0)->getVertexProgramName () +
" fp " + (*ppTech)->getPass (0)->getFragmentProgramName ());
*/
return true;
}
// Get depth material
Material* depthMaterial = getDepthRenderMaterial ();
Technique* tech = depthMaterial->getBestTechnique ();
// Replace ALL techniques.
*ppTech = tech;
return true;
}
void DepthRenderer::setRenderGroupRangeFilter (int minGroup, int maxGroup)
{
mMinRenderGroupId = minGroup;
mMaxRenderGroupId = maxGroup;
}
void DepthRenderer::disableRenderGroupRangeFilter()
{
setRenderGroupRangeFilter(Ogre::RENDER_QUEUE_BACKGROUND, Ogre::RENDER_QUEUE_MAX);
}
}

@ -0,0 +1,59 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2009 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "FastGpuParamRef.h"
using namespace Ogre;
namespace Caelum
{
FastGpuParamRef::FastGpuParamRef(Ogre::GpuProgramParametersSharedPtr paramsPtr, const Ogre::String& name)
{
this->bind(paramsPtr, name);
}
void FastGpuParamRef::bind(
Ogre::GpuProgramParametersSharedPtr params,
const Ogre::String& name,
bool throwIfNotFound/* = false*/)
{
assert(!params.isNull());
#if CAELUM_DEBUG_PARAM_REF
mParams = params;
#endif
const GpuConstantDefinition* def = params->_findNamedConstantDefinition(name, throwIfNotFound);
if (def) {
mPhysicalIndex = def->physicalIndex;
assert(this->isBound());
} else {
mPhysicalIndex = InvalidPhysicalIndex;
assert(!this->isBound());
}
}
void FastGpuParamRef::unbind() {
#if CAELUM_DEBUG_PARAM_REF
mParams.setNull();
#endif
mPhysicalIndex = InvalidPhysicalIndex;
assert(!this->isBound());
}
}

@ -0,0 +1,384 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "FlatCloudLayer.h"
#include "CaelumExceptions.h"
#include "InternalUtilities.h"
namespace Caelum
{
FlatCloudLayer::FlatCloudLayer(
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *cloudRoot)
{
Ogre::String uniqueSuffix = InternalUtilities::pointerToString(this);
// Clone material
mMaterial.reset(InternalUtilities::checkLoadMaterialClone ("CaelumLayeredClouds", "Caelum/FlatCloudLayer/Material" + uniqueSuffix));
mParams.setup(
mMaterial->getTechnique(0)->getPass(0)->getVertexProgramParameters(),
mMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters());
// Create the scene node.
mSceneMgr = sceneMgr;
mNode.reset(cloudRoot->createChildSceneNode());
mNode->setPosition(Ogre::Vector3(0, 0, 0));
// Noise texture names are fixed.
mNoiseTextureNames.clear();
mNoiseTextureNames.push_back("noise1.dds");
mNoiseTextureNames.push_back("noise2.dds");
mNoiseTextureNames.push_back("noise3.dds");
mNoiseTextureNames.push_back("noise4.dds");
// Invalid; will reset on first opportunity.
mCurrentTextureIndex = -1;
// By default height is 0; the user is expected to change this.
setHeight(0);
// Reset parameters. This is relied upon to initialize most fields.
this->reset();
// Ensure geometry; don't wait for first update.
this->_ensureGeometry();
}
FlatCloudLayer::~FlatCloudLayer()
{
mSceneMgr = 0;
// Rely on PrivatePtr for everything interesting.
}
void FlatCloudLayer::_invalidateGeometry () {
mMeshDirty = true;
}
void FlatCloudLayer::_ensureGeometry ()
{
if (!mMeshDirty) {
return;
}
// Generate unique names based on pointer.
Ogre::String uniqueId = Ogre::StringConverter::toString((size_t)this);
Ogre::String planeMeshName = "Caelum/FlatCloudLayer/Plane/" + uniqueId;
Ogre::String entityName = "Caelum/FlatCloudLayer/Entity/" + uniqueId;
// Cleanup first. Entity references mesh so it must be destroyed first.
mEntity.reset();
mMesh.reset();
/*
Ogre::LogManager::getSingleton().logMessage(
"Creating cloud layer mesh " +
Ogre::StringConverter::toString(mMeshWidthSegments) + "x" +
Ogre::StringConverter::toString(mMeshHeightSegments) + " segments");
*/
// Recreate mesh.
Ogre::Plane meshPlane(
Ogre::Vector3(1, 1, 0),
Ogre::Vector3(1, 1, 1),
Ogre::Vector3(0, 1, 1));
mMesh.reset(Ogre::MeshManager::getSingleton().createPlane(
planeMeshName, Caelum::RESOURCE_GROUP_NAME, meshPlane,
mMeshWidth, mMeshHeight,
mMeshWidthSegments, mMeshHeightSegments,
false, 1,
1.0f, 1.0f,
Ogre::Vector3::UNIT_X));
// Recreate entity.
mEntity.reset(mSceneMgr->createEntity(entityName, mMesh->getName()));
mEntity->setMaterialName(mMaterial->getName());
// Reattach entity.
mNode->attachObject(mEntity.get());
// Mark done.
mMeshDirty = false;
}
void FlatCloudLayer::setMeshParameters (
Real meshWidth, Real meshHeight,
int meshWidthSegments, int meshHeightSegments)
{
bool invalidate =
(mMeshWidthSegments != meshWidthSegments) ||
(mMeshHeightSegments != meshHeightSegments) ||
(abs(mMeshWidth - meshWidth) > 0.001) ||
(abs(mMeshHeight - meshHeight) > 0.001);
mMeshWidth = meshWidth;
mMeshHeight = meshHeight;
mMeshWidthSegments = meshWidthSegments;
mMeshHeightSegments = meshHeightSegments;
if (invalidate) {
_invalidateGeometry();
}
}
void FlatCloudLayer::reset()
{
_invalidateGeometry ();
setMeshParameters(10000000, 10000000, 10, 10);
assert (mCloudCoverLookup.get() == 0);
setCloudCoverLookup ("CloudCoverLookup.png");
setCloudCover (0.3);
setCloudCoverVisibilityThreshold (0.001);
setCloudMassOffset (Ogre::Vector2(0, 0));
setCloudDetailOffset (Ogre::Vector2(0, 0));
setCloudBlendTime (3600 * 24);
setCloudBlendPos (0.5);
setCloudSpeed (Ogre::Vector2(0.000005, -0.000009));
setCloudUVFactor (150);
setHeightRedFactor (100000);
setFadeDistances (10000, 140000);
setFadeDistMeasurementVector (Ogre::Vector3(0, 1, 1));
setSunDirection (Ogre::Vector3::UNIT_Y);
setFogColour (Ogre::ColourValue::Black);
setSunLightColour (Ogre::ColourValue::White);
setSunSphereColour (Ogre::ColourValue::White);
}
void FlatCloudLayer::update (
Ogre::Real timePassed,
const Ogre::Vector3 &sunDirection,
const Ogre::ColourValue &sunLightColour,
const Ogre::ColourValue &fogColour,
const Ogre::ColourValue &sunSphereColour)
{
// Advance animation
advanceAnimation (timePassed);
// Set parameters.
setSunDirection (sunDirection);
setSunLightColour (sunLightColour);
setSunSphereColour (sunSphereColour);
setFogColour (fogColour);
this->_ensureGeometry();
this->_updateVisibilityThreshold();
}
void FlatCloudLayer::_updateVisibilityThreshold ()
{
if (!mEntity.isNull()) {
mEntity->setVisible (getCloudCover () > this->getCloudCoverVisibilityThreshold ());
}
}
void FlatCloudLayer::advanceAnimation (Ogre::Real timePassed)
{
// Move clouds.
setCloudMassOffset(mCloudMassOffset + timePassed * mCloudSpeed);
setCloudDetailOffset(mCloudDetailOffset - timePassed * mCloudSpeed);
// Animate cloud blending.
setCloudBlendPos (getCloudBlendPos () + timePassed / mCloudBlendTime);
}
void FlatCloudLayer::Params::setup(Ogre::GpuProgramParametersSharedPtr vpParams, Ogre::GpuProgramParametersSharedPtr fpParams)
{
this->vpParams = vpParams;
this->fpParams = fpParams;
cloudCoverageThreshold.bind(fpParams, "cloudCoverageThreshold");
cloudMassOffset.bind(fpParams, "cloudMassOffset");
cloudDetailOffset.bind(fpParams, "cloudDetailOffset");
cloudMassBlend.bind(fpParams, "cloudMassBlend");
vpSunDirection.bind(vpParams, "sunDirection");
fpSunDirection.bind(fpParams, "sunDirection");
sunLightColour.bind(fpParams, "sunLightColour");
sunSphereColour.bind(fpParams, "sunSphereColour");
fogColour.bind(fpParams, "fogColour");
layerHeight.bind(fpParams, "layerHeight");
cloudUVFactor.bind(fpParams, "cloudUVFactor");
heightRedFactor.bind(fpParams, "heightRedFactor");
nearFadeDist.bind(fpParams, "nearFadeDist");
farFadeDist.bind(fpParams, "farFadeDist");
fadeDistMeasurementVector.bind(fpParams, "fadeDistMeasurementVector");
}
void FlatCloudLayer::setCloudCoverLookup (const Ogre::String& fileName) {
mCloudCoverLookup.reset(0);
mCloudCoverLookup.reset(new Ogre::Image());
mCloudCoverLookup->load(fileName, RESOURCE_GROUP_NAME);
mCloudCoverLookupFileName = fileName;
}
void FlatCloudLayer::disableCloudCoverLookup () {
mCloudCoverLookup.reset (0);
mCloudCoverLookupFileName.clear ();
}
const Ogre::String FlatCloudLayer::getCloudCoverLookupFileName () const {
return mCloudCoverLookupFileName;
}
void FlatCloudLayer::setCloudCoverVisibilityThreshold(const Ogre::Real value) {
mCloudCoverVisibilityThreshold = value;
_updateVisibilityThreshold();
}
void FlatCloudLayer::setCloudCover(const Ogre::Real cloudCover) {
mCloudCover = cloudCover;
float cloudCoverageThreshold = 0;
if (mCloudCoverLookup.get() != 0) {
cloudCoverageThreshold = InternalUtilities::getInterpolatedColour(cloudCover, 1, mCloudCoverLookup.get(), false).r;
} else {
cloudCoverageThreshold = 1 - cloudCover;
}
mParams.cloudCoverageThreshold.set(mParams.fpParams, cloudCoverageThreshold);
_updateVisibilityThreshold();
}
void FlatCloudLayer::setCloudMassOffset(const Ogre::Vector2 &cloudMassOffset) {
mCloudMassOffset = cloudMassOffset;
mParams.cloudMassOffset.set(mParams.fpParams, Ogre::Vector3(cloudMassOffset.x,cloudMassOffset.y,0));
}
void FlatCloudLayer::setCloudDetailOffset(const Ogre::Vector2 &cloudDetailOffset) {
mCloudDetailOffset = cloudDetailOffset;
mParams.cloudDetailOffset.set(mParams.fpParams, Ogre::Vector3(cloudDetailOffset.x,cloudDetailOffset.y,0));
}
void FlatCloudLayer::setCloudBlendTime(const Ogre::Real value) {
mCloudBlendTime = value;
}
Ogre::Real FlatCloudLayer::getCloudBlendTime () const {
return mCloudBlendTime;
}
void FlatCloudLayer::setCloudBlendPos (const Ogre::Real value)
{
mCloudBlendPos = value;
int textureCount = static_cast<int>(mNoiseTextureNames.size());
// Convert to int and bring to [0, textureCount)
int currentTextureIndex = static_cast<int>(floor(mCloudBlendPos));
currentTextureIndex = ((currentTextureIndex % textureCount) + textureCount) % textureCount;
assert(0 <= currentTextureIndex);
assert(currentTextureIndex < textureCount);
// Check if we have to change textures.
if (currentTextureIndex != mCurrentTextureIndex) {
String texture1 = mNoiseTextureNames[currentTextureIndex];
String texture2 = mNoiseTextureNames[(currentTextureIndex + 1) % textureCount];
//Ogre::LogManager::getSingleton ().logMessage (
// "Caelum: Switching cloud layer textures to " + texture1 + " and " + texture2);
Ogre::Pass* pass = mMaterial->getBestTechnique()->getPass(0);
pass->getTextureUnitState(0)->setTextureName(texture1);
pass->getTextureUnitState(1)->setTextureName(texture2);
mCurrentTextureIndex = currentTextureIndex;
}
Ogre::Real cloudMassBlend = fmod(mCloudBlendPos, 1);
mParams.cloudMassBlend.set(mParams.fpParams, cloudMassBlend);
}
Ogre::Real FlatCloudLayer::getCloudBlendPos () const {
return mCloudBlendPos;
}
void FlatCloudLayer::setCloudSpeed (const Ogre::Vector2 &cloudSpeed) {
mCloudSpeed = cloudSpeed;
}
void FlatCloudLayer::setSunDirection (const Ogre::Vector3 &sunDirection) {
mSunDirection = sunDirection;
mParams.vpSunDirection.set(mParams.vpParams, sunDirection);
mParams.fpSunDirection.set(mParams.fpParams, sunDirection);
}
void FlatCloudLayer::setSunLightColour (const Ogre::ColourValue &sunLightColour) {
mParams.sunLightColour.set(mParams.fpParams, mSunLightColour = sunLightColour);
}
void FlatCloudLayer::setSunSphereColour (const Ogre::ColourValue &sunSphereColour) {
mParams.sunSphereColour.set(mParams.fpParams, mSunSphereColour = sunSphereColour);
}
void FlatCloudLayer::setFogColour (const Ogre::ColourValue &fogColour) {
mParams.fogColour.set(mParams.fpParams, mFogColour = fogColour);
}
const Ogre::Vector3 FlatCloudLayer::getSunDirection () const {
return mSunDirection;
}
const Ogre::ColourValue FlatCloudLayer::getSunLightColour () const {
return mSunLightColour;
}
const Ogre::ColourValue FlatCloudLayer::getSunSphereColour () const {
return mSunSphereColour;
}
const Ogre::ColourValue FlatCloudLayer::getFogColour () const {
return mFogColour;
}
void FlatCloudLayer::setHeight(Ogre::Real height) {
mNode->setPosition(Ogre::Vector3(0, height, 0));
mHeight = height;
mParams.layerHeight.set(mParams.fpParams, mHeight);
}
Ogre::Real FlatCloudLayer::getHeight() const {
return mHeight;
}
void FlatCloudLayer::setCloudUVFactor (const Ogre::Real value) {
mParams.cloudUVFactor.set(mParams.fpParams, mCloudUVFactor = value);
}
void FlatCloudLayer::setHeightRedFactor (const Ogre::Real value) {
mParams.heightRedFactor.set(mParams.fpParams, mHeightRedFactor = value);
}
void FlatCloudLayer::setFadeDistances (const Ogre::Real nearValue, const Ogre::Real farValue) {
setNearFadeDist (nearValue);
setFarFadeDist (farValue);
}
void FlatCloudLayer::setNearFadeDist (const Ogre::Real value) {
mParams.nearFadeDist.set(mParams.fpParams, mNearFadeDist = value);
}
void FlatCloudLayer::setFarFadeDist (const Ogre::Real value) {
mParams.farFadeDist.set(mParams.fpParams, mFarFadeDist = value);
}
void FlatCloudLayer::setFadeDistMeasurementVector (const Ogre::Vector3& value) {
mParams.fadeDistMeasurementVector.set(mParams.fpParams, mFadeDistMeasurementVector = value);
}
}

@ -0,0 +1,216 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "GroundFog.h"
#include "CaelumExceptions.h"
#include "InternalUtilities.h"
namespace Caelum
{
const Ogre::String GroundFog::DEFAULT_PASS_NAME = "CaelumGroundFog";
GroundFog::GroundFog(
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
const Ogre::String &domeMaterialName,
const Ogre::String &domeEntityName):
mScene(sceneMgr)
{
Ogre::String uniqueSuffix = InternalUtilities::pointerToString (this);
mDomeMaterial.reset(InternalUtilities::checkLoadMaterialClone (domeMaterialName, domeMaterialName + uniqueSuffix));
mDomeParams.setup(mDomeMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters());
// Create dome entity, using a prefab sphere.
// The prefab sphere has a radius of 50 units.
// If this changes in future version of ogre this might break.
mDomeEntity.reset (mScene->createEntity (domeEntityName, Ogre::SceneManager::PT_SPHERE));
mDomeEntity->setMaterialName (mDomeMaterial->getName ());
mDomeEntity->setCastShadows (false);
mDomeEntity->setRenderQueueGroup (CAELUM_RENDER_QUEUE_GROUND_FOG);
sceneMgr->getRenderQueue()->getQueueGroup(CAELUM_RENDER_QUEUE_GROUND_FOG)->setShadowsEnabled(false);
// Create dome node
mDomeNode.reset (caelumRootNode->createChildSceneNode ());
mDomeNode->attachObject (mDomeEntity.get());
// Initialize default fog parameters
mDensity = 0.1;
mVerticalDecay = 0.2;
mGroundLevel = 5;
mFogColour = Ogre::ColourValue::Black;
forceUpdate();
}
GroundFog::~GroundFog() {
// Disable passes.
setDensity(0);
}
GroundFog::PassSet& GroundFog::getPasses() {
return mPasses;
}
const GroundFog::PassSet& GroundFog::getPasses() const {
return mPasses;
}
void GroundFog::findFogPassesByName (const Ogre::String& passName) {
Ogre::MaterialManager *matManager = Ogre::MaterialManager::getSingletonPtr();
Ogre::MaterialManager::ResourceMapIterator matIt = matManager->getResourceIterator();
while (matIt.hasMoreElements()) {
Ogre::MaterialPtr mat = matIt.getNext();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements()) {
Ogre::Technique *tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements()) {
Ogre::Pass *pass = passIt.getNext();
if (pass->getName() == passName) {
mPasses.insert(pass);
}
}
}
}
forceUpdate();
}
void GroundFog::setDensity (Ogre::Real density) {
if (Ogre::Math::Abs(mDensity - density) > 0.000001) {
for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
it->fogDensity.set(it->fpParams, density);
}
mDensity = density;
}
updateSkyFogging();
}
Ogre::Real GroundFog::getDensity () const {
return mDensity;
}
void GroundFog::setColour (const Ogre::ColourValue &colour) {
bool different =
Ogre::Math::Abs(mFogColour.r - colour.r) > 0.001 ||
Ogre::Math::Abs(mFogColour.g - colour.g) > 0.001 ||
Ogre::Math::Abs(mFogColour.b - colour.b) > 0.001 ||
Ogre::Math::Abs(mFogColour.a - colour.a) > 0.001;
if (different) {
for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
it->fogColour.set(it->fpParams, colour);
}
mFogColour = colour;
}
updateSkyFogging();
}
const Ogre::ColourValue GroundFog::getColour () const {
return mFogColour;
}
void GroundFog::setVerticalDecay (Ogre::Real verticalDecay) {
if (Ogre::Math::Abs(mVerticalDecay - verticalDecay) > 0.000001) {
for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
it->fogVerticalDecay.set(it->fpParams, verticalDecay);
}
mVerticalDecay = verticalDecay;
}
updateSkyFogging();
}
Ogre::Real GroundFog::getVerticalDecay () const {
return mVerticalDecay;
}
void GroundFog::setGroundLevel (Ogre::Real groundLevel) {
if (Ogre::Math::Abs(mGroundLevel - groundLevel) > 0.000001) {
for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
it->fogGroundLevel.set(it->fpParams, groundLevel);
}
mGroundLevel = groundLevel;
}
updateSkyFogging();
}
Ogre::Real GroundFog::getGroundLevel () const {
return mGroundLevel;
}
void GroundFog::updateSkyFogging() {
mDomeParams.fogDensity.set(mDomeParams.fpParams, mDensity);
mDomeParams.fogVerticalDecay.set(mDomeParams.fpParams, mVerticalDecay);
mDomeParams.fogGroundLevel.set(mDomeParams.fpParams, mGroundLevel);
mDomeParams.fogColour.set(mDomeParams.fpParams, mFogColour);
}
void GroundFog::forceUpdate ()
{
updatePassFogParams();
for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
const PassFogParams& params = *it;
params.fogDensity.set(params.fpParams, mDensity);
params.fogVerticalDecay.set(params.fpParams, mVerticalDecay);
params.fogGroundLevel.set(params.fpParams, mGroundLevel);
params.fogColour.set(params.fpParams, mFogColour);
}
updateSkyFogging();
}
void GroundFog::updatePassFogParams ()
{
mPassFogParams.clear();
for (PassSet::const_iterator it = mPasses.begin(), end = mPasses.end(); it != end; ++it) {
mPassFogParams.push_back(PassFogParams((*it)->getFragmentProgramParameters()));
}
std::sort(mPassFogParams.begin(), mPassFogParams.end(), PassFogParams::lessThanByParams);
std::unique(mPassFogParams.begin(), mPassFogParams.end(), PassFogParams::equalByParams);
}
void GroundFog::FogParamsBase::setup(Ogre::GpuProgramParametersSharedPtr fpParams) {
this->fpParams = fpParams;
fogDensity.bind(fpParams, "fogDensity");
fogVerticalDecay.bind(fpParams, "fogVerticalDecay");
fogGroundLevel.bind(fpParams, "fogGroundLevel");
fogColour.bind(fpParams, "fogColour");
}
void GroundFog::DomeFogParams::setup(Ogre::GpuProgramParametersSharedPtr fpParams) {
FogParamsBase::setup(fpParams);
cameraHeight.bind(fpParams, "cameraHeight");
}
void GroundFog::notifyCameraChanged (Ogre::Camera *cam)
{
CameraBoundElement::notifyCameraChanged (cam);
// Send camera height to shader.
float cameraHeight = cam->getDerivedPosition().dotProduct(mDomeNode->_getDerivedOrientation() * Ogre::Vector3::UNIT_Y);
mDomeParams.cameraHeight.set(mDomeParams.fpParams, cameraHeight);
}
void GroundFog::setFarRadius (Ogre::Real radius)
{
CameraBoundElement::setFarRadius(radius);
// Adjust for radius 50.
mDomeNode->setScale(Ogre::Vector3::UNIT_SCALE * radius / 50.0);
}
}

@ -0,0 +1,87 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "ImageStarfield.h"
#include "InternalUtilities.h"
namespace Caelum
{
const Ogre::String ImageStarfield::STARFIELD_DOME_NAME = "CaelumStarfieldDome";
const Ogre::String ImageStarfield::STARFIELD_MATERIAL_NAME = "CaelumStarfieldMaterial";
const Ogre::String ImageStarfield::DEFAULT_TEXTURE_NAME = "Starfield.jpg";
ImageStarfield::ImageStarfield
(
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
const Ogre::String &textureName/* = DEFAULT_TEXUTRE_NAME*/
)
{
mInclination = Ogre::Degree (0);
String uniqueSuffix = "/" + InternalUtilities::pointerToString (this);
mStarfieldMaterial.reset (InternalUtilities::checkLoadMaterialClone (STARFIELD_MATERIAL_NAME, STARFIELD_MATERIAL_NAME + uniqueSuffix));
setTexture (textureName);
sceneMgr->getRenderQueue ()->getQueueGroup (CAELUM_RENDER_QUEUE_STARFIELD)->setShadowsEnabled (false);
InternalUtilities::generateSphericDome (STARFIELD_DOME_NAME, 32, InternalUtilities::DT_IMAGE_STARFIELD);
mEntity.reset(sceneMgr->createEntity ("Caelum/StarfieldDome" + uniqueSuffix, STARFIELD_DOME_NAME));
mEntity->setMaterialName (mStarfieldMaterial->getName());
mEntity->setRenderQueueGroup (CAELUM_RENDER_QUEUE_STARFIELD);
mEntity->setCastShadows (false);
mNode.reset (caelumRootNode->createChildSceneNode ());
mNode->attachObject (mEntity.get ());
}
ImageStarfield::~ImageStarfield ()
{
}
void ImageStarfield::notifyCameraChanged (Ogre::Camera *cam) {
CameraBoundElement::notifyCameraChanged (cam);
}
void ImageStarfield::setFarRadius (Ogre::Real radius) {
CameraBoundElement::setFarRadius(radius);
mNode->setScale (Ogre::Vector3::UNIT_SCALE * radius);
}
void ImageStarfield::setInclination (Ogre::Degree inc) {
mInclination = inc;
}
void ImageStarfield::update (const float time) {
Ogre::Quaternion orientation = Ogre::Quaternion::IDENTITY;
orientation = orientation * Ogre::Quaternion (Ogre::Radian (mInclination + Ogre::Degree (90)), Ogre::Vector3::UNIT_X);
orientation = orientation * Ogre::Quaternion (Ogre::Radian (-time * 2 * Ogre::Math::PI), Ogre::Vector3::UNIT_Y);
mNode->setOrientation (orientation);
}
void ImageStarfield::setTexture (const Ogre::String &mapName) {
// Update the starfield material
mStarfieldMaterial->getBestTechnique ()->getPass (0)->getTextureUnitState (0)->setTextureName (mapName);
}
}

@ -0,0 +1,328 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "CaelumExceptions.h"
#include "InternalUtilities.h"
#include "PrivatePtr.h"
namespace Caelum
{
Ogre::ColourValue InternalUtilities::getInterpolatedColour (
float fx, float fy, Ogre::Image *img, bool wrapX)
{
// Don't -> all the time, and avoid unsigned warnings
int imgWidth = static_cast<int>(img->getWidth ());
int imgHeight = static_cast<int>(img->getHeight ());
// Calculate pixel y coord.
int py = Ogre::Math::IFloor(Ogre::Math::Abs (fy) * (imgHeight - 1));
// Snap to py image bounds.
py = std::max(0, std::min(py, imgHeight - 1));
// Get the two closest pixels on x.
// px1 and px2 are the closest integer pixels to px.
float px = fx * (img->getWidth () - 1);
int px1, px2;
px1 = Ogre::Math::IFloor(px);
px2 = Ogre::Math::ICeil(px);
if (wrapX) {
// Wrap x coords. The funny addition ensures that it does
// "the right thing" for negative values.
px1 = (px1 % imgWidth + imgWidth) % imgWidth;
px2 = (px2 % imgWidth + imgWidth) % imgWidth;
} else {
px1 = std::max(0, std::min(px1, imgWidth - 1));
px2 = std::max(0, std::min(px2, imgWidth - 1));
}
// Calculate the interpolated pixel
Ogre::ColourValue c1, c2, cf;
c1 = img->getColourAt (px1, py, 0);
c2 = img->getColourAt (px2, py, 0);
// Blend the two pixels together.
// diff is the weight between pixel 1 and pixel 2.
float diff = px - px1;
cf = c1 * (1 - diff) + c2 * diff;
return cf;
}
const Ogre::String InternalUtilities::pointerToString (void* pointer)
{
std::stringstream stream;
stream.width(2 * sizeof(void *));
stream.fill('0');
stream.unsetf(std::ios::dec);
stream.setf(std::ios::hex);
stream.setf(std::ios::uppercase);
stream << reinterpret_cast<ptrdiff_t>(pointer);
return stream.str();
}
Ogre::MaterialPtr InternalUtilities::checkLoadMaterialClone (
const Ogre::String& originalName,
const Ogre::String& cloneName)
{
Ogre::MaterialPtr scriptMaterial = Ogre::MaterialManager::getSingletonPtr()->getByName(originalName);
if (scriptMaterial.isNull()) {
CAELUM_THROW_UNSUPPORTED_EXCEPTION (
"Can't find material \"" + originalName + "\"",
"Caelum");
}
// Create clone
Caelum::PrivateMaterialPtr clonedMaterial (scriptMaterial->clone (cloneName));
// Test clone loads and there is at least on supported technique
clonedMaterial->load ();
if (clonedMaterial->getBestTechnique () == 0) {
CAELUM_THROW_UNSUPPORTED_EXCEPTION (
"Can't load material \"" + originalName + "\": " + clonedMaterial->getUnsupportedTechniquesExplanation(),
"Caelum");
}
return clonedMaterial.release();
}
Ogre::CompositorPtr InternalUtilities::checkCompositorSupported (const Ogre::String& name)
{
Ogre::CompositorPtr comp = Ogre::CompositorManager::getSingletonPtr()->getByName(name);
if (comp.isNull()) {
CAELUM_THROW_UNSUPPORTED_EXCEPTION (
"Can't find compositor \"" + name + "\"",
"Caelum");
}
// Check the compositor is supported after loading.
comp->load ();
if (comp->getNumSupportedTechniques () == 0) {
CAELUM_THROW_UNSUPPORTED_EXCEPTION (
"Can't load compositor \"" + name + "\"",
"Caelum");
}
return comp;
}
void InternalUtilities::generateSphericDome (const Ogre::String &name, int segments, DomeType type)
{
// Return now if already exists
if (Ogre::MeshManager::getSingleton ().resourceExists (name)) {
return;
}
Ogre::LogManager::getSingleton ().logMessage (
"Caelum: Creating " + name + " sphere mesh resource...");
// Use the mesh manager to create the mesh
Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton ().createManual (name, RESOURCE_GROUP_NAME);
// Create a submesh
Ogre::SubMesh *sub = msh->createSubMesh ();
// Create the shared vertex data
Ogre::VertexData *vertexData = new Ogre::VertexData ();
msh->sharedVertexData = vertexData;
// Define the vertices' format
Ogre::VertexDeclaration *vertexDecl = vertexData->vertexDeclaration;
size_t currOffset = 0;
// Position
vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT3);
// Normal
vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT3);
// Texture coordinates
vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT2);
// Allocate the vertex buffer
switch (type) {
case DT_SKY_DOME:
vertexData->vertexCount = segments * (segments - 1) + 2;
break;
case DT_IMAGE_STARFIELD:
vertexData->vertexCount = (segments + 1) * (segments + 1);
break;
};
Ogre::HardwareVertexBufferSharedPtr vBuf = Ogre::HardwareBufferManager::getSingleton ().createVertexBuffer (vertexDecl->getVertexSize (0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
Ogre::VertexBufferBinding *binding = vertexData->vertexBufferBinding;
binding->setBinding (0, vBuf);
float *pVertex = static_cast<float *>(vBuf->lock (Ogre::HardwareBuffer::HBL_DISCARD));
// Allocate the index buffer
switch (type) {
case DT_SKY_DOME:
sub->indexData->indexCount = 2 * segments * (segments - 1) * 3;
break;
case DT_IMAGE_STARFIELD:
sub->indexData->indexCount = 2 * (segments - 1) * segments * 3;
break;
};
sub->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton ().createIndexBuffer (Ogre::HardwareIndexBuffer::IT_16BIT, sub->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
Ogre::HardwareIndexBufferSharedPtr iBuf = sub->indexData->indexBuffer;
unsigned short *pIndices = static_cast<unsigned short *>(iBuf->lock (Ogre::HardwareBuffer::HBL_DISCARD));
// Fill the buffers
switch (type) {
case DT_SKY_DOME:
fillGradientsDomeBuffers (pVertex, pIndices, segments);
break;
case DT_IMAGE_STARFIELD:
fillStarfieldDomeBuffers (pVertex, pIndices, segments);
break;
};
// Close the vertex buffer
vBuf->unlock ();
// Close the index buffer
iBuf->unlock ();
// Finishing it...
sub->useSharedVertices = true;
msh->_setBounds (Ogre::AxisAlignedBox (-1, -1, -1, 1, 1, 1), false);
msh->_setBoundingSphereRadius (1);
msh->load ();
Ogre::LogManager::getSingleton ().logMessage (
"Caelum: generateSphericDome DONE");
}
void InternalUtilities::fillGradientsDomeBuffers (float *pVertex, unsigned short *pIndices, int segments)
{
const float deltaLatitude = Ogre::Math::PI / (float )segments;
const float deltaLongitude = Ogre::Math::PI * 2.0 / (float )segments;
// Generate the rings
for (int i = 1; i < segments; i++) {
float r0 = Ogre::Math::Sin (Ogre::Radian (i * deltaLatitude));
float y0 = Ogre::Math::Cos (Ogre::Radian (i * deltaLatitude));
for (int j = 0; j < segments; j++) {
float x0 = r0 * Ogre::Math::Sin (Ogre::Radian (j * deltaLongitude));
float z0 = r0 * Ogre::Math::Cos (Ogre::Radian (j * deltaLongitude));
*pVertex++ = x0;
*pVertex++ = y0;
*pVertex++ = z0;
*pVertex++ = -x0;
*pVertex++ = -y0;
*pVertex++ = -z0;
*pVertex++ = 0;
*pVertex++ = 1 - y0;
}
}
// Generate the "north pole"
*pVertex++ = 0; // Position
*pVertex++ = 1;
*pVertex++ = 0;
*pVertex++ = 0; // Normal
*pVertex++ = -1;
*pVertex++ = 0;
*pVertex++ = 0; // UV
*pVertex++ = 0;
// Generate the "south pole"
*pVertex++ = 0; // Position
*pVertex++ = -1;
*pVertex++ = 0;
*pVertex++ = 0; // Normal
*pVertex++ = 1;
*pVertex++ = 0;
*pVertex++ = 0; // UV
*pVertex++ = 2;
// Generate the mid segments
for (int i = 0; i < segments - 2; i++) {
for (int j = 0; j < segments; j++) {
*pIndices++ = segments * i + j;
*pIndices++ = segments * i + (j + 1) % segments;
*pIndices++ = segments * (i + 1) + (j + 1) % segments;
*pIndices++ = segments * i + j;
*pIndices++ = segments * (i + 1) + (j + 1) % segments;
*pIndices++ = segments * (i + 1) + j;
}
}
// Generate the upper cap
for (int i = 0; i < segments; i++) {
*pIndices++ = segments * (segments - 1);
*pIndices++ = (i + 1) % segments;
*pIndices++ = i;
}
// Generate the lower cap
for (int i = 0; i < segments; i++) {
*pIndices++ = segments * (segments - 1) + 1;
*pIndices++ = segments * (segments - 2) + i;
*pIndices++ = segments * (segments - 2) + (i + 1) % segments;
}
}
void InternalUtilities::fillStarfieldDomeBuffers (float *pVertex, unsigned short *pIndices, int segments)
{
const float deltaLatitude = Ogre::Math::PI / (float )segments;
const float deltaLongitude = Ogre::Math::PI * 2.0 / (float )segments;
// Generate the rings
for (int i = 0; i <= segments; i++) {
float r0 = Ogre::Math::Sin (Ogre::Radian (i * deltaLatitude));
float y0 = Ogre::Math::Cos (Ogre::Radian (i * deltaLatitude));
for (int j = 0; j <= segments; j++) {
float x0 = r0 * Ogre::Math::Sin (Ogre::Radian (j * deltaLongitude));
float z0 = r0 * Ogre::Math::Cos (Ogre::Radian (j * deltaLongitude));
*pVertex++ = x0;
*pVertex++ = y0;
*pVertex++ = z0;
*pVertex++ = -x0;
*pVertex++ = -y0;
*pVertex++ = -z0;
*pVertex++ = (float )j / (float )segments;
*pVertex++ = 1 - (y0 * 0.5 + 0.5);
}
}
// Generate the mid segments
int vRowSize = segments + 1;
for (int i = 1; i < segments; i++) {
for (int j = 0; j < segments; j++) {
int baseIdx = vRowSize * i + j;
*pIndices++ = baseIdx;
*pIndices++ = baseIdx + 1;
*pIndices++ = baseIdx + vRowSize + 1;
*pIndices++ = baseIdx + 1;
*pIndices++ = baseIdx;
*pIndices++ = baseIdx - vRowSize;
}
}
}
}

@ -0,0 +1,140 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "CaelumExceptions.h"
#include "InternalUtilities.h"
#include "Moon.h"
#include <memory>
namespace Caelum
{
const Ogre::String Moon::MOON_MATERIAL_NAME = "Caelum/PhaseMoon";
const Ogre::String Moon::MOON_BACKGROUND_MATERIAL_NAME = "Caelum/MoonBackground";
Moon::Moon (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
const Ogre::String& moonTextureName,
Ogre::Degree angularSize
):
BaseSkyLight(sceneMgr, caelumRootNode),
mAngularSize(angularSize)
{
Ogre::String uniqueSuffix = "/" + InternalUtilities::pointerToString(this);
// Clone materials
mMoonMaterial.reset(InternalUtilities::checkLoadMaterialClone(MOON_MATERIAL_NAME, MOON_MATERIAL_NAME + uniqueSuffix));
mBackMaterial.reset(InternalUtilities::checkLoadMaterialClone(MOON_BACKGROUND_MATERIAL_NAME, MOON_BACKGROUND_MATERIAL_NAME + uniqueSuffix));
assert (!mMoonMaterial.isNull ());
assert (mMoonMaterial->getTechnique (0));
assert (mMoonMaterial->getTechnique (0)->getPass (0));
assert (mMoonMaterial->getTechnique (0)->getPass( 0)->hasFragmentProgram ());
mParams.setup(mMoonMaterial->getBestTechnique ()->getPass (0)->getFragmentProgramParameters ());
setMoonTexture(moonTextureName);
mMoonBB.reset(sceneMgr->createBillboardSet("Caelum/Moon/MoonBB" + uniqueSuffix, 1));
mMoonBB->setMaterialName (mMoonMaterial->getName());
mMoonBB->setCastShadows (false);
mMoonBB->setRenderQueueGroup (CAELUM_RENDER_QUEUE_MOON);
mMoonBB->setDefaultDimensions (1.0f, 1.0f);
mMoonBB->createBillboard (Ogre::Vector3::ZERO);
mBackBB.reset(sceneMgr->createBillboardSet("Caelum/Moon/BackBB" + uniqueSuffix, 1));
mBackBB->setMaterialName (mBackMaterial->getName());
mBackBB->setCastShadows (false);
mBackBB->setRenderQueueGroup (CAELUM_RENDER_QUEUE_MOON_BACKGROUND);
mBackBB->setDefaultDimensions (1.0f, 1.0f);
mBackBB->createBillboard (Ogre::Vector3::ZERO);
mNode->attachObject (mMoonBB.get());
mNode->attachObject (mBackBB.get());
}
Moon::~Moon () {
}
void Moon::setBodyColour (const Ogre::ColourValue &colour) {
BaseSkyLight::setBodyColour(colour);
// Set moon material colour.
mMoonBB->getBillboard(0)->setColour(colour);
}
void Moon::setMoonTexture (const Ogre::String &textureName)
{
// Update the moon material
assert(mMoonMaterial->getBestTechnique ());
assert(mMoonMaterial->getBestTechnique ()->getPass (0));
assert(mMoonMaterial->getBestTechnique ()->getPass (0)->getTextureUnitState (0));
mMoonMaterial->getBestTechnique ()->getPass (0)->getTextureUnitState (0)->setTextureName (textureName);
mBackMaterial->getBestTechnique ()->getPass (0)->getTextureUnitState (0)->setTextureName (textureName);
}
void Moon::setMoonTextureAngularSize(const Ogre::Degree& moonTextureAngularSize){
mAngularSize = moonTextureAngularSize;
}
void Moon::notifyCameraChanged (Ogre::Camera *cam) {
// This calls setFarRadius
BaseSkyLight::notifyCameraChanged(cam);
// Set moon position.
Ogre::Real moonDistance = mRadius - mRadius * Ogre::Math::Tan(mAngularSize);
mNode->setPosition(-mDirection * moonDistance);
// Set moon scaling in [1.0 ~ 1.2] range
float factor = 1.2f - mBodyColour.b * 0.2f;
float scale = factor * moonDistance * Ogre::Math::Tan(mAngularSize);
mNode->setScale (Ogre::Vector3::UNIT_SCALE * scale);
}
void Moon::Params::setup(Ogre::GpuProgramParametersSharedPtr fpParams)
{
this->fpParams = fpParams;
this->phase.bind(fpParams, "phase");
}
void Moon::setPhase (Ogre::Real phase) {
mParams.phase.set(mParams.fpParams, phase);
}
void Moon::setQueryFlags (uint flags) {
mMoonBB->setQueryFlags (flags);
mBackBB->setQueryFlags (flags);
}
uint Moon::getQueryFlags () const {
assert (mMoonBB->getQueryFlags () == mBackBB->getQueryFlags ());
return mMoonBB->getQueryFlags ();
}
void Moon::setVisibilityFlags (uint flags) {
mMoonBB->setVisibilityFlags (flags);
mBackBB->setVisibilityFlags (flags);
}
uint Moon::getVisibilityFlags () const {
assert (mMoonBB->getVisibilityFlags () == mBackBB->getVisibilityFlags ());
return mMoonBB->getVisibilityFlags ();
}
}

@ -0,0 +1,292 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "PointStarfield.h"
#include "CaelumExceptions.h"
#include "Astronomy.h"
#include "InternalUtilities.h"
using namespace Ogre;
namespace Caelum
{
const Ogre::String PointStarfield::STARFIELD_MATERIAL_NAME = "Caelum/StarPoint";
const Ogre::Degree PointStarfield::DEFAULT_OBSERVER_POSITION_REBUILD_DELTA = Ogre::Degree(0.1);
PointStarfield::PointStarfield (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
bool initWithCatalogue)
{
mMag0PixelSize = 16;
mMinPixelSize = 4;
mMaxPixelSize = 6;
mMagnitudeScale = Math::Pow(100, 0.2);
mObserverLatitude = 45;
mObserverLongitude = 0;
mObserverPositionRebuildDelta = DEFAULT_OBSERVER_POSITION_REBUILD_DELTA;
String uniqueSuffix = "/" + InternalUtilities::pointerToString(this);
// Load material.
mMaterial.reset(InternalUtilities::checkLoadMaterialClone(
STARFIELD_MATERIAL_NAME,
STARFIELD_MATERIAL_NAME + uniqueSuffix));
mParams.setup(mMaterial->getTechnique(0)->getPass(0)->getVertexProgramParameters());
// We use a separate data source.
Ogre::String objName = "Caelum/PointStarfield" + uniqueSuffix;
mManualObj.reset (sceneMgr->createManualObject (objName));
mManualObj->setDynamic(false);
mManualObj->setRenderQueueGroup (CAELUM_RENDER_QUEUE_STARFIELD);
sceneMgr->getRenderQueue()->getQueueGroup(CAELUM_RENDER_QUEUE_STARFIELD)->setShadowsEnabled (false);
mManualObj->setCastShadows(false);
mNode.reset (caelumRootNode->createChildSceneNode ());
mNode->attachObject (mManualObj.getPointer ());
if (initWithCatalogue) {
addBrightStarCatalogue ();
}
}
PointStarfield::~PointStarfield ()
{
}
void PointStarfield::notifyStarVectorChanged () {
invalidateGeometry ();
}
void PointStarfield::clearAllStars () {
mStars.clear();
notifyStarVectorChanged ();
}
Real randReal () {
return rand() / static_cast<float>(RAND_MAX);
}
Real randReal (Real min, Real max) {
Real f = randReal ();
return min * (1 - f) + max * f;
}
void PointStarfield::addRandomStars (int count)
{
for (int i = 0; i < count; ++i) {
// Generate a vector inside a sphere
Ogre::Vector3 pos;
do {
pos.x = randReal(-1, 1);
pos.y = randReal(-1, 1);
pos.z = randReal(-1, 1);
} while (pos.squaredLength () >= 1);
// Convert to rasc/decl angles.
LongReal rasc, decl, dist;
Astronomy::convertRectangularToSpherical(
pos.x, pos.y, pos.z,
rasc, decl, dist);
Star s;
s.RightAscension = Ogre::Degree (rasc);
s.Declination = Ogre::Degree (decl);
// This distribution is wrong.
s.Magnitude = 6 * pos.squaredLength () + 1.5;
mStars.push_back(s);
}
notifyStarVectorChanged ();
}
void PointStarfield::addStar (const BrightStarCatalogueEntry &entry) {
Star s;
s.RightAscension = Ogre::Degree(360 / 24.0f * (
Math::Abs(entry.rasc_hour) +
entry.rasc_min / 60.0f +
entry.rasc_sec / 3600.0f));
s.Declination = Ogre::Degree(Math::Sign(entry.decl_deg) * (
Math::Abs(entry.decl_deg) +
entry.decl_min / 60.0f +
entry.decl_sec / 3600.0f));
s.Magnitude = entry.magn;
mStars.push_back(s);
notifyStarVectorChanged ();
}
void PointStarfield::addBrightStarCatalogue (int count) {
assert(count >= 0);
if (count < BrightStarCatalogueSize) {
// Only sort if we don't add everything.
// It would be lovely if the catalogue was already sorted.
std::vector<std::pair<Real, int> > vec;
vec.reserve(BrightStarCatalogueSize);
for (int i = 0; i < BrightStarCatalogueSize; ++i) {
vec.push_back(std::make_pair(BrightStarCatalogue[i].magn, i));
}
sort(vec.begin(), vec.end());
for (int i = 0; i < count; ++i) {
addStar(BrightStarCatalogue[vec[i].second]);
}
} else {
assert(count == BrightStarCatalogueSize);
for (int i = 0; i < BrightStarCatalogueSize; ++i) {
addStar(BrightStarCatalogue[i]);
}
}
notifyStarVectorChanged ();
}
void PointStarfield::invalidateGeometry () {
mValidGeometry = false;
}
void PointStarfield::ensureGeometry ()
{
if (mValidGeometry) {
return;
}
//Ogre::LogManager::getSingleton ().logMessage ("Caelum: Recomputing starfield geometry.");
size_t starCount = mStars.size();
mManualObj->clear();
mManualObj->estimateVertexCount(6 * starCount);
mManualObj->begin(mMaterial->getName (), Ogre::RenderOperation::OT_TRIANGLE_LIST);
for (uint i = 0; i < starCount; ++i)
{
const Star& star = mStars[i];
// Determine position at J2000
LongReal azm, alt;
Astronomy::convertEquatorialToHorizontal(
Astronomy::J2000,
mObserverLatitude.valueDegrees(),
mObserverLongitude.valueDegrees(),
star.RightAscension.valueDegrees(), star.Declination.valueDegrees(),
azm, alt);
Ogre::Vector3 pos;
pos.z = -Math::Cos (Ogre::Degree(azm)) * Math::Cos (Ogre::Degree(alt));
pos.x = Math::Sin (Ogre::Degree(azm)) * Math::Cos (Ogre::Degree(alt));
pos.y = -Math::Sin (Ogre::Degree(alt));
//mManualObj->colour (Ogre::ColourValue::White);
mManualObj->position (pos);
mManualObj->textureCoord (+1, -1, star.Magnitude);
mManualObj->position (pos);
mManualObj->textureCoord (+1, +1, star.Magnitude);
mManualObj->position (pos);
mManualObj->textureCoord (-1, -1, star.Magnitude);
mManualObj->position (pos);
mManualObj->textureCoord (-1, -1, star.Magnitude);
mManualObj->position (pos);
mManualObj->textureCoord (+1, +1, star.Magnitude);
mManualObj->position (pos);
mManualObj->textureCoord (-1, +1, star.Magnitude);
}
mManualObj->end();
// Set infinite bounds on the starfield.
AxisAlignedBox box;
box.setInfinite ();
mManualObj->setBoundingBox (box);
mValidGeometry = true;
}
void PointStarfield::Params::setup(Ogre::GpuProgramParametersSharedPtr vpParams)
{
this->vpParams = vpParams;
this->mag_scale.bind(vpParams, "mag_scale");
this->mag0_size.bind(vpParams, "mag0_size");
this->min_size.bind(vpParams, "min_size");
this->max_size.bind(vpParams, "max_size");
this->aspect_ratio.bind(vpParams, "aspect_ratio");
}
void PointStarfield::notifyCameraChanged (Ogre::Camera *cam) {
CameraBoundElement::notifyCameraChanged (cam);
// Shader params are changed for every camera.
Pass* pass = mMaterial->getBestTechnique ()->getPass (0);
GpuProgramParametersSharedPtr fpParams = pass->getFragmentProgramParameters ();
GpuProgramParametersSharedPtr vpParams = pass->getVertexProgramParameters ();
int height = cam->getViewport ()-> getActualHeight ();
int width = cam->getViewport ()-> getActualWidth ();
Real pixFactor = 1.0f / width;
Real magScale = -Math::Log (mMagnitudeScale) / 2;
Real mag0Size = mMag0PixelSize * pixFactor;
Real minSize = mMinPixelSize * pixFactor;
Real maxSize = mMaxPixelSize * pixFactor;
Real aspectRatio = static_cast<Real>(width) / height;
// These params are relative to the size of the screen.
mParams.mag_scale.set(mParams.vpParams, magScale);
mParams.mag0_size.set(mParams.vpParams, mag0Size);
mParams.min_size.set(mParams.vpParams, minSize);
mParams.max_size.set(mParams.vpParams, maxSize);
mParams.aspect_ratio.set(mParams.vpParams, aspectRatio);
}
void PointStarfield::setFarRadius (Ogre::Real radius) {
CameraBoundElement::setFarRadius(radius);
mNode->setScale (Ogre::Vector3::UNIT_SCALE * radius);
}
void PointStarfield::_update (const float time) {
// This is probably wrong.
Ogre::Quaternion orientation = Ogre::Quaternion::IDENTITY;
orientation = orientation * Ogre::Quaternion (Ogre::Radian (-mObserverLatitude + Ogre::Degree (90)), Ogre::Vector3::UNIT_X);
orientation = orientation * Ogre::Quaternion (Ogre::Radian (-time * 2 * Ogre::Math::PI), Ogre::Vector3::UNIT_Y);
mNode->setOrientation (orientation);
ensureGeometry ();
}
void PointStarfield::setObserverLatitude (Ogre::Degree value)
{
if (!Math::RealEqual (
mObserverLatitude.valueDegrees (),
value.valueDegrees (),
this->getObserverPositionRebuildDelta ().valueDegrees ()))
{
mObserverLatitude = value;
invalidateGeometry ();
}
}
void PointStarfield::setObserverLongitude (Ogre::Degree value)
{
if (!Math::RealEqual (
mObserverLongitude.valueDegrees (),
value.valueDegrees (),
this->getObserverPositionRebuildDelta ().valueDegrees ()))
{
mObserverLongitude = value;
invalidateGeometry ();
}
}
}

@ -0,0 +1,392 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "PrecipitationController.h"
#include "InternalUtilities.h"
using namespace Ogre;
namespace Caelum
{
const String PrecipitationController::COMPOSITOR_NAME = "Caelum/PrecipitationCompositor";
const String PrecipitationController::MATERIAL_NAME = "Caelum/PrecipitationMaterial";
const PrecipitationPresetParams PrecipitationPresets[] = {
{ Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.95, "precipitation_drizzle.png" },
{ Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.85, "precipitation_rain.png" },
{ Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.12, "precipitation_snow.png" },
{ Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.33, "precipitation_snowgrains.png" },
{ Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.70, "precipitation_icecrystals.png" },
{ Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.78, "precipitation_icepellets.png" },
{ Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.74, "precipitation_hail.png" },
{ Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.70, "precipitation_smallhail.png" }
};
PrecipitationController::PrecipitationController(
Ogre::SceneManager *sceneMgr)
{
Ogre::String uniqueId = Ogre::StringConverter::toString((size_t)this);
mSceneMgr = sceneMgr;
setAutoDisableThreshold (0.001);
mCameraSpeedScale = Ogre::Vector3::UNIT_SCALE;
setIntensity (0);
setWindSpeed (Ogre::Vector3(0, 0, 0));
mInternalTime = 0;
mSecondsSinceLastFrame = 0;
mFallingDirection = Ogre::Vector3::NEGATIVE_UNIT_Y;
setPresetType (PRECTYPE_RAIN);
update (0, Ogre::ColourValue(0, 0, 0, 0));
InternalUtilities::checkCompositorSupported(COMPOSITOR_NAME);
}
PrecipitationController::~PrecipitationController () {
destroyAllViewportInstances ();
}
void PrecipitationController::setTextureName (const Ogre::String& textureName) {
mPresetType = PRECTYPE_CUSTOM;
mTextureName = textureName;
}
const Ogre::String PrecipitationController::getTextureName () const {
return mTextureName;
}
void PrecipitationController::setSpeed (Real speed) {
mPresetType = PRECTYPE_CUSTOM;
mSpeed = speed;
}
Real PrecipitationController::getSpeed () const {
return mSpeed;
}
void PrecipitationController::setColour (const Ogre::ColourValue& color) {
mPresetType = PRECTYPE_CUSTOM;
mColour = color;
}
const Ogre::ColourValue PrecipitationController::getColour () const {
return mColour;
}
bool PrecipitationController::isPresetType (PrecipitationType type) {
return PRECTYPE_DRIZZLE <= type && type <= PRECTYPE_SMALLHAIL;
}
const PrecipitationPresetParams& PrecipitationController::getPresetParams (PrecipitationType type) {
assert(isPresetType(type));
return PrecipitationPresets[type];
}
void PrecipitationController::setParams (const PrecipitationPresetParams& params) {
setColour (params.Colour);
setSpeed (params.Speed);
setTextureName (params.Name);
}
void PrecipitationController::setPresetType (PrecipitationType type) {
setParams (getPresetParams (type));
mPresetType = type;
}
PrecipitationType PrecipitationController::getPresetType () const {
return mPresetType;
}
void PrecipitationController::setWindSpeed (const Ogre::Vector3& value) {
mWindSpeed = value;
}
const Ogre::Vector3 PrecipitationController::getWindSpeed () const {
return mWindSpeed;
}
void PrecipitationController::setIntensity (Real intensity) {
mIntensity = intensity;
}
Real PrecipitationController::getIntensity () const {
return mIntensity;
}
void PrecipitationController::update (Real secondsSinceLastFrame, Ogre::ColourValue colour) {
mSecondsSinceLastFrame = secondsSinceLastFrame;
mInternalTime += mSecondsSinceLastFrame;
mSceneColour = colour;
ViewportInstanceMap::const_iterator it;
ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin ();
ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end ();
for (it = begin; it != end; ++it) {
it->second->_update ();
}
}
void PrecipitationController::setManualCameraSpeed (const Ogre::Vector3& value) {
ViewportInstanceMap::const_iterator it;
ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
for (it = begin; it != end; ++it) {
it->second->setManualCameraSpeed(value);
}
}
void PrecipitationController::setAutoCameraSpeed() {
ViewportInstanceMap::const_iterator it;
ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
for (it = begin; it != end; ++it) {
it->second->setAutoCameraSpeed();
}
}
PrecipitationInstance::PrecipitationInstance
(
PrecipitationController* parent,
Ogre::Viewport* viewport
):
mParent(parent),
mViewport(viewport),
mCompInst(0),
mLastCamera(0),
mLastCameraPosition(Vector3::ZERO),
mCameraSpeed(Vector3::ZERO),
mAutoCameraSpeed(true)
{
createCompositor ();
}
PrecipitationInstance::~PrecipitationInstance ()
{
destroyCompositor();
}
void PrecipitationInstance::createCompositor ()
{
// Check if nothing to do.
if (mCompInst) {
return;
}
Ogre::CompositorManager* compMgr = Ogre::CompositorManager::getSingletonPtr();
// Create the precipitation compositor.
mCompInst = compMgr->addCompositor(mViewport, PrecipitationController::COMPOSITOR_NAME);
assert(mCompInst);
mCompInst->setEnabled (false);
mCompInst->addListener (this);
}
void PrecipitationInstance::destroyCompositor ()
{
// Check if nothing to do.
if (mCompInst == 0) {
return;
}
Ogre::CompositorManager* compMgr = Ogre::CompositorManager::getSingletonPtr();
// Remove the precipitation compositor.
mCompInst->removeListener (this);
compMgr->removeCompositor(mViewport, PrecipitationController::COMPOSITOR_NAME);
mCompInst = 0;
}
void PrecipitationInstance::notifyMaterialSetup(uint pass_id, Ogre::MaterialPtr &mat)
{
mParams.setup(mat->getTechnique (0)->getPass (0)->getFragmentProgramParameters ());
}
void PrecipitationInstance::Params::setup(Ogre::GpuProgramParametersSharedPtr fpParams)
{
this->fpParams = fpParams;
this->precColor.bind(fpParams, "precColor");
this->intensity.bind(fpParams, "intensity");
this->dropSpeed.bind(fpParams, "dropSpeed");
this->corner1.bind(fpParams, "corner1");
this->corner2.bind(fpParams, "corner2");
this->corner3.bind(fpParams, "corner3");
this->corner4.bind(fpParams, "corner4");
this->deltaX.bind(fpParams, "deltaX");
this->deltaY.bind(fpParams, "deltaY");
}
void PrecipitationInstance::notifyMaterialRender(uint pass_id, Ogre::MaterialPtr &mat)
{
if (mAutoCameraSpeed) {
Ogre::Camera* cam = mViewport->getCamera();
Ogre::Vector3 camPos = cam->getDerivedPosition();
if (cam != mLastCamera) {
mCameraSpeed = Ogre::Vector3::ZERO;
} else {
Real timeDiff = mParent->getSecondsSinceLastFrame ();
Ogre::Vector3 posDiff = camPos - mLastCameraPosition;
// Avoid division by 0 and keep old camera speed.
if (timeDiff > 1e-10) {
mCameraSpeed = posDiff / timeDiff;
} else {
// Keep old camera speed.
}
/*
LogManager::getSingletonPtr ()->logMessage (
"Caelum::PrecipitationInstance:"
" posDiff = " + StringConverter::toString(posDiff) +
" timeDiff = " + StringConverter::toString(mParent->getSecondsSinceLastFrame (), 10) +
" speed = " + StringConverter::toString(mCameraSpeed));
*/
}
mLastCamera = cam;
mLastCameraPosition = camPos;
}
this->_updateMaterialParams(mat, mViewport->getCamera(), mCameraSpeed);
}
void PrecipitationInstance::_updateMaterialParams(
const Ogre::MaterialPtr& mat,
const Ogre::Camera* cam,
const Ogre::Vector3& camSpeed)
{
// 4523.893416f is divisible with all the sine periods in the shader
Real appTime = static_cast<Real>(fmod(mParent->mInternalTime, static_cast<Real>(4523.893416f)));
ColourValue sceneColour = mParent->mSceneColour;
Real sceneLum = (sceneColour.r + sceneColour.g + sceneColour.b) / 3;
mParams.precColor.set(mParams.fpParams, ColourValue::White * sceneLum * mParent->mColour);
mParams.intensity.set(mParams.fpParams, mParent->mIntensity);
mParams.dropSpeed.set(mParams.fpParams, 0);
Ogre::Vector3 corner1, corner2, corner3, corner4;
corner1 = cam->getCameraToViewportRay(0, 0).getDirection();
corner2 = cam->getCameraToViewportRay(1, 0).getDirection();
corner3 = cam->getCameraToViewportRay(0, 1).getDirection();
corner4 = cam->getCameraToViewportRay(1, 1).getDirection();
Ogre::Vector3 precDir =
mParent->mSpeed * mParent->mFallingDirection +
mParent->mWindSpeed -
camSpeed * mParent->mCameraSpeedScale;
Ogre::Quaternion quat = precDir.getRotationTo(Ogre::Vector3(0, -1, 0));
corner1 = quat * corner1;
corner2 = quat * corner2;
corner3 = quat * corner3;
corner4 = quat * corner4;
mParams.corner1.set(mParams.fpParams, corner1);
mParams.corner2.set(mParams.fpParams, corner2);
mParams.corner3.set(mParams.fpParams, corner3);
mParams.corner4.set(mParams.fpParams, corner4);
float fallSpeed = precDir.length();
mParams.deltaX.set(mParams.fpParams,
Ogre::Vector3(sin(appTime) + 4.33,
cos(appTime * 1.5) + 5.26,
cos(appTime * 2.5)) * fallSpeed / 10 + 88.001);
mParams.deltaY.set(mParams.fpParams,
Ogre::Vector3(0.6, 1.0, 1.4) * fallSpeed * appTime);
if (mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->getTextureName() != mParent->mTextureName) {
mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName(mParent->mTextureName);
}
}
bool PrecipitationInstance::getAutoCameraSpeed () {
return mAutoCameraSpeed;
}
void PrecipitationInstance::setAutoCameraSpeed () {
mAutoCameraSpeed = true;
mCameraSpeed = Ogre::Vector3::ZERO;
mLastCamera = 0;
}
void PrecipitationInstance::setManualCameraSpeed (const Ogre::Vector3& value) {
mAutoCameraSpeed = false;
mCameraSpeed = value;
}
const Ogre::Vector3 PrecipitationInstance::getCameraSpeed () {
return mCameraSpeed;
}
bool PrecipitationInstance::shouldBeEnabled () const {
return mParent->getAutoDisableThreshold () < 0 ||
mParent->getIntensity () > mParent->getAutoDisableThreshold ();
}
void PrecipitationInstance::_update ()
{
mCompInst->setEnabled (shouldBeEnabled ());
}
PrecipitationInstance* PrecipitationController::createViewportInstance (Ogre::Viewport* vp)
{
ViewportInstanceMap::const_iterator it = mViewportInstanceMap.find (vp);
if (it == mViewportInstanceMap.end()) {
std::auto_ptr<PrecipitationInstance> inst (new PrecipitationInstance(this, vp));
mViewportInstanceMap.insert (std::make_pair (vp, inst.get()));
// hold instance until successfully added to map.
return inst.release();
} else {
return it->second;
}
}
PrecipitationInstance* PrecipitationController::getViewportInstance(Ogre::Viewport* vp) {
ViewportInstanceMap::iterator it = mViewportInstanceMap.find (vp);
if (it != mViewportInstanceMap.end ()) {
return it->second;
} else {
return 0;
}
}
void PrecipitationController::destroyViewportInstance (Viewport* vp)
{
ViewportInstanceMap::iterator it = mViewportInstanceMap.find (vp);
if (it != mViewportInstanceMap.end ()) {
PrecipitationInstance* inst = it->second;
delete inst;
mViewportInstanceMap.erase (it);
}
}
void PrecipitationController::destroyAllViewportInstances () {
ViewportInstanceMap::const_iterator it;
ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
for (it = begin; it != end; ++it) {
assert(it->first == it->second->getViewport ());
delete it->second;
}
mViewportInstanceMap.clear ();
}
}

@ -0,0 +1,152 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "SkyDome.h"
#include "CaelumExceptions.h"
#include "InternalUtilities.h"
namespace Caelum
{
const Ogre::String SkyDome::SPHERIC_DOME_NAME = "CaelumSphericDome";
const Ogre::String SkyDome::SKY_DOME_MATERIAL_NAME = "CaelumSkyDomeMaterial";
SkyDome::SkyDome (Ogre::SceneManager *sceneMgr, Ogre::SceneNode *caelumRootNode)
{
String uniqueSuffix = "/" + InternalUtilities::pointerToString(this);
// First clone material
mMaterial.reset(InternalUtilities::checkLoadMaterialClone(SKY_DOME_MATERIAL_NAME, SKY_DOME_MATERIAL_NAME + uniqueSuffix));
// Determine if the shader technique works.
mShadersEnabled = mMaterial->getBestTechnique()->getPass(0)->isProgrammable();
// Force setting haze, ensure mHazeEnabled != value.
mHazeEnabled = true;
setHazeEnabled(false);
sceneMgr->getRenderQueue()->getQueueGroup(CAELUM_RENDER_QUEUE_SKYDOME)->setShadowsEnabled(false);
// Generate dome entity.
InternalUtilities::generateSphericDome (SPHERIC_DOME_NAME, 32, InternalUtilities::DT_SKY_DOME);
mEntity.reset(sceneMgr->createEntity ("Caelum/SkyDome/Entity" + uniqueSuffix, SPHERIC_DOME_NAME));
mEntity->setMaterialName (mMaterial->getName());
mEntity->setRenderQueueGroup (CAELUM_RENDER_QUEUE_SKYDOME);
mEntity->setCastShadows (false);
mNode.reset(caelumRootNode->createChildSceneNode ("Caelum/SkyDome/Node" + uniqueSuffix));
mNode->attachObject (mEntity.get());
}
SkyDome::~SkyDome () {
}
void SkyDome::notifyCameraChanged (Ogre::Camera *cam) {
CameraBoundElement::notifyCameraChanged (cam);
}
void SkyDome::setFarRadius (Ogre::Real radius) {
CameraBoundElement::setFarRadius(radius);
mNode->setScale (Ogre::Vector3::UNIT_SCALE * radius);
}
void SkyDome::setSunDirection (const Ogre::Vector3& sunDir) {
float elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y);
elevation = elevation * 0.5 + 0.5;
Ogre::Pass* pass = mMaterial->getBestTechnique()->getPass(0);
if (mShadersEnabled) {
mParams.sunDirection.set(mParams.vpParams, sunDir);
mParams.offset.set(mParams.fpParams, elevation);
} else {
Ogre::TextureUnitState* gradientsTus = pass->getTextureUnitState(0);
gradientsTus->setTextureUScroll (elevation);
}
}
void SkyDome::setHazeColour (const Ogre::ColourValue& hazeColour) {
if (mShadersEnabled && mHazeEnabled) {
mParams.hazeColour.set(mParams.fpParams, hazeColour);
}
}
void SkyDome::setSkyGradientsImage (const Ogre::String& gradients)
{
Ogre::TextureUnitState* gradientsTus =
mMaterial->getTechnique (0)->getPass (0)->getTextureUnitState(0);
gradientsTus->setTextureAddressingMode (Ogre::TextureUnitState::TAM_CLAMP);
// Per 1.4 compatibility. Not tested with recent svn.
#if OGRE_VERSION < ((1 << 16) | (3 << 8))
gradientsTus->setTextureName (gradients, Ogre::TEX_TYPE_2D, -1, true);
#else
gradientsTus->setTextureName (gradients, Ogre::TEX_TYPE_2D);
gradientsTus->setIsAlpha (true);
#endif
}
void SkyDome::setAtmosphereDepthImage (const Ogre::String& atmosphereDepth)
{
if (!mShadersEnabled) {
return;
}
Ogre::TextureUnitState* atmosphereTus =
mMaterial->getTechnique (0)->getPass (0)->getTextureUnitState(1);
atmosphereTus->setTextureName (atmosphereDepth, Ogre::TEX_TYPE_1D);
atmosphereTus->setTextureAddressingMode (Ogre::TextureUnitState::TAM_CLAMP, Ogre::TextureUnitState::TAM_WRAP, Ogre::TextureUnitState::TAM_WRAP);
}
bool SkyDome::getHazeEnabled () const {
return mHazeEnabled;
}
void SkyDome::setHazeEnabled (bool value)
{
if (mHazeEnabled == value) {
return;
}
mHazeEnabled = value;
if (!mShadersEnabled) {
return;
}
Ogre::Pass *pass = mMaterial->getTechnique (0)->getPass (0);
if (value) {
pass->setFragmentProgram("CaelumSkyDomeFP");
} else {
pass->setFragmentProgram("CaelumSkyDomeFP_NoHaze");
}
mParams.setup(
pass->getVertexProgramParameters(),
pass->getFragmentProgramParameters());
}
void SkyDome::Params::setup(Ogre::GpuProgramParametersSharedPtr vpParams, Ogre::GpuProgramParametersSharedPtr fpParams)
{
this->fpParams = fpParams;
this->vpParams = vpParams;
sunDirection.bind(vpParams, "sunDirection");
offset.bind(fpParams, "offset");
hazeColour.bind(fpParams, "hazeColour");
}
}

@ -0,0 +1,160 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "SkyLight.h"
namespace Caelum
{
const Ogre::Real BaseSkyLight::DEFAULT_AUTO_DISABLE_THRESHOLD = 0.1;
BaseSkyLight::BaseSkyLight (Ogre::SceneManager *sceneMgr, Ogre::SceneNode *caelumRootNode):
mDirection(Ogre::Vector3::ZERO),
mBodyColour(Ogre::ColourValue::White),
mLightColour(Ogre::ColourValue::White),
mDiffuseMultiplier(Ogre::ColourValue(1, 1, 0.9)),
mSpecularMultiplier(Ogre::ColourValue(1, 1, 1)),
mAmbientMultiplier(Ogre::ColourValue(0.2, 0.2, 0.2)),
mAutoDisableLight(false),
mAutoDisableThreshold(DEFAULT_AUTO_DISABLE_THRESHOLD),
mForceDisableLight(false)
{
Ogre::String lightName = "CaelumSkyLight" + Ogre::StringConverter::toString((size_t)this);
mMainLight = sceneMgr->createLight (lightName);
mMainLight->setType (Ogre::Light::LT_DIRECTIONAL);
sceneMgr->getRenderQueue()->getQueueGroup(CAELUM_RENDER_QUEUE_SUN)->setShadowsEnabled(false);
mNode = caelumRootNode->createChildSceneNode ();
}
BaseSkyLight::~BaseSkyLight () {
if (mNode) {
static_cast<Ogre::SceneNode *>(mNode->getParent ())->removeAndDestroyChild (mNode->getName ());
mNode = 0;
}
if (mMainLight) {
mMainLight->_getManager ()->destroyLight (mMainLight);
mMainLight = 0;
}
}
void BaseSkyLight::setFarRadius (Ogre::Real radius) {
CameraBoundElement::setFarRadius(radius);
mRadius = radius;
}
void BaseSkyLight::update (
const Ogre::Vector3& direction,
const Ogre::ColourValue &lightColour,
const Ogre::ColourValue &bodyColour)
{
setLightDirection(direction);
setLightColour(lightColour);
setBodyColour(bodyColour);
}
const Ogre::Vector3 BaseSkyLight::getLightDirection () const {
return mDirection;
}
void BaseSkyLight::setLightDirection (const Ogre::Vector3 &dir) {
mDirection = dir;
if (mMainLight != 0) {
mMainLight->setDirection (mNode->_getDerivedOrientation() * dir);
}
}
void BaseSkyLight::setBodyColour (const Ogre::ColourValue &colour) {
// Store this last colour
mBodyColour = colour;
}
const Ogre::ColourValue BaseSkyLight::getBodyColour () const {
return mBodyColour;
}
void BaseSkyLight::setLightColour (const Ogre::ColourValue &colour) {
// Store this last colour
mLightColour = colour;
// Apply change
setMainLightColour(colour);
}
void BaseSkyLight::setMainLightColour (const Ogre::ColourValue &colour) {
// Set light colours.
bool enable = shouldEnableLight (colour);
if (enable) {
mMainLight->setVisible(true);
mMainLight->setDiffuseColour (colour * mDiffuseMultiplier);
mMainLight->setSpecularColour (colour * mSpecularMultiplier);
} else {
mMainLight->setVisible(false);
}
}
const Ogre::ColourValue BaseSkyLight::getLightColour () const {
return mLightColour;
}
void BaseSkyLight::setDiffuseMultiplier (const Ogre::ColourValue &diffuse) {
mDiffuseMultiplier = diffuse;
}
const Ogre::ColourValue BaseSkyLight::getDiffuseMultiplier () const {
return mDiffuseMultiplier;
}
void BaseSkyLight::setSpecularMultiplier (const Ogre::ColourValue &specular) {
mSpecularMultiplier = specular;
}
const Ogre::ColourValue BaseSkyLight::getSpecularMultiplier () const {
return mSpecularMultiplier;
}
void BaseSkyLight::setAmbientMultiplier (const Ogre::ColourValue &ambient) {
mAmbientMultiplier = ambient;
}
const Ogre::ColourValue BaseSkyLight::getAmbientMultiplier () const {
return mAmbientMultiplier;
}
Ogre::Light* BaseSkyLight::getMainLight() const {
return mMainLight;
}
bool BaseSkyLight::shouldEnableLight(const Ogre::ColourValue &colour) {
if (mForceDisableLight) {
return false;
}
if (mAutoDisableLight) {
Ogre::Real sum = colour.r + colour.g + colour.b;
return sum >= mAutoDisableThreshold;
} else {
return true;
}
}
}

@ -0,0 +1,131 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "Sun.h"
#include "InternalUtilities.h"
namespace Caelum
{
const Ogre::String SphereSun::SUN_MATERIAL_NAME = "CaelumSphereSun";
SphereSun::SphereSun
(
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
const Ogre::String &meshName
):
BaseSkyLight(sceneMgr, caelumRootNode)
{
Ogre::String uniqueSuffix = "/" + InternalUtilities::pointerToString (this);
mSunMaterial.reset (InternalUtilities::checkLoadMaterialClone (SUN_MATERIAL_NAME, SUN_MATERIAL_NAME + uniqueSuffix));
mSunEntity.reset (sceneMgr->createEntity ("Caelum/SphereSun" + uniqueSuffix, meshName));
mSunEntity->setMaterialName (mSunMaterial->getName ());
mSunEntity->setCastShadows (false);
mSunEntity->setRenderQueueGroup (CAELUM_RENDER_QUEUE_SUN);
mNode->attachObject (mSunEntity.get ());
}
SphereSun::~SphereSun () { }
void SphereSun::setBodyColour (const Ogre::ColourValue &colour) {
BaseSkyLight::setBodyColour(colour);
// Set sun material colour.
mSunMaterial->setSelfIllumination (colour);
}
void SphereSun::notifyCameraChanged (Ogre::Camera *cam) {
// This calls setFarRadius
CameraBoundElement::notifyCameraChanged(cam);
// Set sun position.
Ogre::Real sunDistance = mRadius - mRadius * Ogre::Math::Tan (Ogre::Degree (0.01));
mNode->setPosition(-mDirection * sunDistance);
// Set sun scaling in [1.6(6) ~ 2.0] range.
float factor = 2 - mBodyColour.b / 3;
float scale = factor * sunDistance * Ogre::Math::Tan (Ogre::Degree (0.01));
mNode->setScale (Ogre::Vector3::UNIT_SCALE * scale);
}
const Ogre::String SpriteSun::SUN_MATERIAL_NAME = "CaelumSpriteSun";
SpriteSun::SpriteSun (
Ogre::SceneManager *sceneMgr,
Ogre::SceneNode *caelumRootNode,
const Ogre::String &sunTextureName,
const Ogre::Degree& sunTextureAngularSize
):
BaseSkyLight(sceneMgr, caelumRootNode),
mSunTextureAngularSize(sunTextureAngularSize)
{
Ogre::String uniqueSuffix = "/" + InternalUtilities::pointerToString (this);
mSunMaterial.reset (InternalUtilities::checkLoadMaterialClone (SUN_MATERIAL_NAME, SUN_MATERIAL_NAME + uniqueSuffix));
setSunTexture (sunTextureName);
mSunBillboardSet.reset (sceneMgr->createBillboardSet ("Caelum/SpriteSun" + uniqueSuffix, 2));
mSunBillboardSet->setMaterialName (mSunMaterial->getName());
mSunBillboardSet->setCastShadows (false);
mSunBillboardSet->setRenderQueueGroup (CAELUM_RENDER_QUEUE_SUN);
mSunBillboardSet->setDefaultDimensions (1.0f, 1.0f);
mSunBillboardSet->createBillboard (Ogre::Vector3::ZERO);
mNode->attachObject (mSunBillboardSet.get ());
}
SpriteSun::~SpriteSun () { }
void SpriteSun::setBodyColour (const Ogre::ColourValue &colour) {
BaseSkyLight::setBodyColour (colour);
// Set sun material colour.
mSunBillboardSet->getBillboard (0)->setColour (colour);
}
void SpriteSun::setSunTexture (const Ogre::String &textureName) {
// Update the sun material
assert(mSunMaterial->getBestTechnique ());
assert(mSunMaterial->getBestTechnique ()->getPass (0));
assert(mSunMaterial->getBestTechnique ()->getPass (0)->getTextureUnitState (0));
mSunMaterial->getBestTechnique ()->getPass (0)->getTextureUnitState (0)->setTextureName (textureName);
}
void SpriteSun::setSunTextureAngularSize(const Ogre::Degree& sunTextureAngularSize){
mSunTextureAngularSize = sunTextureAngularSize;
}
void SpriteSun::notifyCameraChanged (Ogre::Camera *cam) {
// This calls setFarRadius
BaseSkyLight::notifyCameraChanged(cam);
// Set sun position.
Ogre::Real sunDistance = mRadius - mRadius * Ogre::Math::Tan(mSunTextureAngularSize);
mNode->setPosition (-mDirection * sunDistance);
// Set sun scaling in [1.0 ~ 1.2] range
float factor = 1.2f - mBodyColour.b * 0.2f;
float scale = factor * sunDistance * Ogre::Math::Tan(mSunTextureAngularSize);
mNode->setScale (Ogre::Vector3::UNIT_SCALE * scale);
}
}

@ -0,0 +1,69 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "TypeDescriptor.h"
#if CAELUM_TYPE_DESCRIPTORS
using namespace Ogre;
namespace Caelum
{
DefaultTypeDescriptor::DefaultTypeDescriptor ()
{
}
DefaultTypeDescriptor::~DefaultTypeDescriptor () {
for (TypeDescriptor::PropertyMap::const_iterator it = mPropertyMap.begin(), end = mPropertyMap.end(); it != end; ++it) {
delete it->second;
}
}
const ValuePropertyDescriptor* DefaultTypeDescriptor::getPropertyDescriptor (const Ogre::String& name) const
{
PropertyMap::const_iterator it = mPropertyMap.find(name);
if (it != mPropertyMap.end()) {
return it->second;
} else {
return 0;
}
}
const std::vector<String> DefaultTypeDescriptor::getPropertyNames () const
{
std::vector<String> result;
for (TypeDescriptor::PropertyMap::const_iterator it = mPropertyMap.begin(), end = mPropertyMap.end(); it != end; ++it) {
result.push_back(it->first);
}
return result;
}
const TypeDescriptor::PropertyMap DefaultTypeDescriptor::getFullPropertyMap () const {
return mPropertyMap;
}
void DefaultTypeDescriptor::add (const Ogre::String& name, const ValuePropertyDescriptor* descriptor)
{
mPropertyMap.insert(make_pair(name, descriptor));
}
}
#endif

@ -0,0 +1,84 @@
/*
This file is part of Caelum.
See http://www.ogre3d.org/wiki/index.php/Caelum
Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
Caelum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caelum 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Caelum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CaelumPrecompiled.h"
#include "UniversalClock.h"
#include "Astronomy.h"
namespace Caelum
{
const Caelum::LongReal UniversalClock::SECONDS_PER_DAY = 86400.0;
UniversalClock::UniversalClock () {
setJulianDay (Astronomy::J2000);
setTimeScale (1.0);
}
void UniversalClock::setJulianDay (Caelum::LongReal value) {
mJulianDayBase = value;
mCurrentTime = 0;
mLastUpdateTime = 0;
}
void UniversalClock::setGregorianDateTime(
int year, int month, int day,
int hour, int minute, double second)
{
ScopedHighPrecissionFloatSwitch precissionSwitch;
setJulianDay(Astronomy::getJulianDayFromGregorianDateTime(year, month, day, hour, minute, second));
}
LongReal UniversalClock::getJulianDay () const
{
ScopedHighPrecissionFloatSwitch precissionSwitch;
Caelum::LongReal res = mJulianDayBase + mCurrentTime / SECONDS_PER_DAY;
return res;
}
LongReal UniversalClock::getJulianDayDifference () const {
ScopedHighPrecissionFloatSwitch precissionSwitch;
return (mCurrentTime - mLastUpdateTime) / SECONDS_PER_DAY;
}
LongReal UniversalClock::getJulianSecond () const {
ScopedHighPrecissionFloatSwitch precissionSwitch;
LongReal res = mJulianDayBase * SECONDS_PER_DAY + mCurrentTime;
return res;
}
LongReal UniversalClock::getJulianSecondDifference () const {
ScopedHighPrecissionFloatSwitch precissionSwitch;
return mCurrentTime - mLastUpdateTime;
}
void UniversalClock::setTimeScale (const Ogre::Real scale) {
mTimeScale = scale;
}
Ogre::Real UniversalClock::getTimeScale () const {
return mTimeScale;
}
void UniversalClock::update (const Ogre::Real time) {
mLastUpdateTime = mCurrentTime;
mCurrentTime += time * mTimeScale;
}
}

@ -11,7 +11,7 @@ using namespace Ogre;
using namespace ESMS;
bool InteriorCellRender::lightConst = false;
float InteriorCellRender::lightConstValue = 0.0;
float InteriorCellRender::lightConstValue = 0.0f;
bool InteriorCellRender::lightLinear = true;
int InteriorCellRender::lightLinearMethod = 1;
@ -141,7 +141,7 @@ void InteriorCellRender::configureFog()
float low = 200;
scene.getMgr()->setFog (FOG_LINEAR, color, 0, low, high);
scene.getCamera()->setFarClipDistance (high + 10);
scene.getCamera()->setFarClipDistance (high + 10 * 1000);
scene.getViewport()->setBackgroundColour (color);
}

@ -9,8 +9,88 @@
#include "OgreCamera.h"
#include "OgreTextureManager.h"
#include "Caelum.h"
using namespace MWRender;
using namespace Ogre;
using namespace Caelum;
class MWWeatherFrameListener : public Ogre::FrameListener
{
protected:
Caelum::CaelumSystem* mpCaelumSystem;
Ogre::SceneManager* mpScene;
float mfSpeedFactor;
bool mbPaused;
float mfTimeTillNextUpdate;
public:
MWWeatherFrameListener(RenderWindow* pRenderWindow, Camera* pCamera)
: mpCaelumSystem (NULL)
, mpScene (NULL)
, mfSpeedFactor (1.0f)
, mbPaused (false)
, mfTimeTillNextUpdate (0.0f)
{
ConfigFile cf;
cf.load("resources.cfg");
ResourceGroupManager::getSingleton().addResourceLocation(".", "FileSystem");
ConfigFile::SectionIterator seci = cf.getSectionIterator();
String secName, typeName, archName;
while (seci.hasMoreElements())
{
secName = seci.peekNextKey();
ConfigFile::SettingsMultiMap *settings = seci.getNext();
ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
typeName = i->first;
archName = i->second;
ResourceGroupManager::getSingleton().addResourceLocation(
archName, typeName, secName);
}
}
mpScene = pCamera->getSceneManager();
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
Caelum::CaelumSystem::CaelumComponent componentMask = CaelumSystem::CAELUM_COMPONENTS_DEFAULT;
componentMask = static_cast<Caelum::CaelumSystem::CaelumComponent> (
//Caelum::CaelumSystem::CAELUM_COMPONENT_SUN |
//Caelum::CaelumSystem::CAELUM_COMPONENT_MOON |
//Caelum::CaelumSystem::CAELUM_COMPONENT_SKY_DOME |
//Caelum::CaelumSystem::CAELUM_COMPONENT_IMAGE_STARFIELD |
//Caelum::CaelumSystem::CAELUM_COMPONENT_POINT_STARFIELD |
Caelum::CaelumSystem::CAELUM_COMPONENT_CLOUDS |
0);
componentMask = CaelumSystem::CAELUM_COMPONENTS_DEFAULT;
mpCaelumSystem = new Caelum::CaelumSystem (Root::getSingletonPtr(), mpScene, componentMask);
mpCaelumSystem->setManageSceneFog(false);
// mpCaelumSystem->getCloudSystem()->
// Set time acceleration.
mpCaelumSystem->getUniversalClock ()->setTimeScale(512);
mfSpeedFactor = mpCaelumSystem->getUniversalClock ()->getTimeScale();
// Register caelum as a listener.
pRenderWindow->addListener(mpCaelumSystem);
Root::getSingletonPtr()->addFrameListener(mpCaelumSystem);
}
~MWWeatherFrameListener()
{
if (mpCaelumSystem)
{
mpCaelumSystem->shutdown (false);
mpCaelumSystem = NULL;
}
}
};
MWScene::MWScene(Render::OgreRenderer &_rend)
: rend(_rend)
@ -25,7 +105,7 @@ MWScene::MWScene(Render::OgreRenderer &_rend)
camera = sceneMgr->createCamera("PlayerCam");
camera->setNearClipDistance(5);
// Create one viewport, entire window
vp = window->addViewport(camera);
@ -50,4 +130,17 @@ MWScene::MWScene(Render::OgreRenderer &_rend)
// For testing
sceneMgr->setAmbientLight(ColourValue(1,1,1));
try
{
MWWeatherFrameListener* pWeather = new MWWeatherFrameListener (window, camera);
}
catch (Exception& e)
{
std::cout << "\nERROR: " << e.getFullDescription().c_str() << std::endl;
}
catch(std::exception &e)
{
std::cout << "\nERROR: " << e.what() << std::endl;
}
}

Loading…
Cancel
Save