GBE::GDynamicGeneratorAgent Class Reference

Implements deterministic random element content generation. More...

#include <GDynamicGeneratorAgent.h>

Inheritance diagram for GBE::GDynamicGeneratorAgent:

Inheritance graph
[legend]
Collaboration diagram for GBE::GDynamicGeneratorAgent:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 GDynamicGeneratorAgent ()
virtual ~GDynamicGeneratorAgent ()
virtual void receiveInfluence (const GCS::GElementInfluence &influence)
virtual void initRandomSeed (unsigned long random_seed)
virtual void initCreationTime (QDateTime creation_time=QDateTime::currentDateTime())
virtual void initDensity (unsigned short density)
virtual void initAllAtOnce (bool create_all_at_once)
virtual void initCreationRangeFactor (double range_factor)
virtual void initCategory (GDynamicGeneratorCategory *category)

Protected Member Functions

void generateInArea (const GCS::GVector3 &position, double radius)
void recursiveGeneration (GDynamicGeneratorOctreeNode *node, const GCS::GVector3 &position, double radius, short unsigned depth)
virtual bool checkGenerationPlausibility (const GDynamicGeneratorCategory &category, const GCS::GVector3 &position)
virtual GCS::GElementcreateElement (const GDynamicGeneratorCategory &category, const GCS::GVector3 &position)
virtual void loadData (bool force=false)

Protected Attributes

bool DataLoaded
unsigned long RandomSeed
QList< GDynamicGeneratorCategory * > Categories
QDateTime CreationTime
unsigned short Density
bool CreateAllAtOnce
double CreationRangeFactor
Util::PseudoRNG RNG
GDynamicGeneratorOctreeNodeTopNode

Private Attributes

double EnergyFractionChildCreation
bool EnergyFractionDirtyFlag

Detailed Description

Implements deterministic random element content generation.

Author:
Martin Reinsprecht (idea), Raphael Langerhorst (implementation)
Dynamic world generation is a key concept in creating huge worlds. This class serves as base class for content creating agents for specific elements.

A random number generator (RNG) is used to create a series of random numbers which are mapped to coordinates octree inside the element. According to a mapping it is possible to tell what kind of child element is created at a certain location. This child element is given a seed value for its own RNG according to the current RNG state. Categories are used to create the child elements. The correct category is chosen by the random number.

This mechanism results in a random but deterministic universe according to the seed value for the first element.

Good examples for using this agent are galaxies, solar systems, planet surface generation, ...

Note:
This agent can only work if the element has a form attribute!
Todo:
Make this Agent thread safe - especially receiveInfluence!! Or put generation into a separate thread.
Todo:
The energy used for creation is NOT deterministic as we GEnergy::take() some out of the current element(!)
Unlike other more simple agents this agent does not directly read its data from the element data, but keeps a copy in this class to reduce overhead.

Adds the following xml data to the element data:

 <worldgeneration>
   <randomseed>number</randomseed>
   <creationtime>datetime</creationtime>
   <density>double value</density>
   <allatonce>bool</allatonce>
   <creationrangefactor>double value</creationrangefactor>
   <categories>
     <!-- sequence of categories, these are examples -->
     <solarsystem>
       <range>double value</range>
     </solarsystem>
     <planet>
       <range>double value</range>
 <!-- these are possible additional values (generic category)
       <radiusmin>double value</radiusmin>
       <radiusmax>double value</radiusmax>
       <allowoverlap>bool</allowoverlap>
 -->
     </planet>
   </categories>
   <!-- gs means generation state and stores the complete state of the octree 
        if all is generated then the done attribute of the top node is 1,
        and then there is almost no memory consumption.
        n is the number of the child node so position and everything can be applied.
        rs is the random seed for the top node, only the top node needs the seed. -->
   <gs n="0" done="0" rs="32152">
     <gs n="0" done="1"></gs>
     <gs n="1" done="0"></gs>
     <gs n="2" done="1"></gs>
     <gs n="3" done="0"></gs>
        <gs n="0" done="1"></gs>
        <gs n="1" done="0"></gs>
        <gs n="2" done="1"></gs>
        <gs n="3" done="1"></gs>
        <gs n="4" done="0"></gs>
        <gs n="5" done="0"></gs>
        <gs n="6" done="0"></gs>
        <gs n="7" done="1"></gs>
     <gs n="4" done="1"></gs>
     <gs n="5" done="0"></gs>
     <gs n="6" done="0"></gs>
     <gs n="7" done="0"></gs>
   </gs>
 </worldgeneration>


Constructor & Destructor Documentation

GBE::GDynamicGeneratorAgent::GDynamicGeneratorAgent (  ) 

Constructor. You MUST use the init member functions to initialize this agent, or the element data must already contain worldgeneration data.

GBE::GDynamicGeneratorAgent::~GDynamicGeneratorAgent (  )  [virtual]

Virtual destructor.


Member Function Documentation

bool GBE::GDynamicGeneratorAgent::checkGenerationPlausibility ( const GDynamicGeneratorCategory category,
const GCS::GVector3 position 
) [protected, virtual]

This method is a simple way of intervention if a new element should be created at a determined position by the generation algorithm.

Only when this method returns true, createElement() will be called, which actually creates the element.

By default this method returns true if given position is with the maximum radius of the form or if the element has no form. If you want different behaviour, you have to reimplement/overload it.

Possible usage of this is method is e.g. to limit generation to the surface of a sphere.

GElement * GBE::GDynamicGeneratorAgent::createElement ( const GDynamicGeneratorCategory category,
const GCS::GVector3 position 
) [protected, virtual]

Creates an element at a given position. For special creation routines this method can be reimplemented.

void GBE::GDynamicGeneratorAgent::generateInArea ( const GCS::GVector3 position,
double  radius 
) [protected]

Generates elements in given sphere area. If active elements are detected by receiveInfluence() then this method is used to do the actual element generation.

See also:
receiveInfluence()

void GBE::GDynamicGeneratorAgent::initAllAtOnce ( bool  create_all_at_once  )  [virtual]

Parameters:
create_all_at_once Determines if all the element content should be created in one go as soon as a user influence is recognised. This is required if child elements heavily influence each other. Otherwise (like solar systems or galaxies) it can be set to false. Default value is false.

void GBE::GDynamicGeneratorAgent::initCategory ( GDynamicGeneratorCategory category  )  [virtual]

Adds given category to element data.

Categories are used to generate child elements at certain nodes.

GDynamicGeneratorAgent takes ownership over given category (for memory management).

Note:
It is VERY important to have a total range size < 1 because the random value used to determine the category is between 0 and 1. If the random value is bigger than the sum of all categories then nothing is created at that position.
See also:
recursiveGeneration(), GDynamicGeneratorCategory

void GBE::GDynamicGeneratorAgent::initCreationRangeFactor ( double  range_factor  )  [virtual]

See also:
CreationRangeFactor

void GBE::GDynamicGeneratorAgent::initCreationTime ( QDateTime  creation_time = QDateTime::currentDateTime()  )  [virtual]

Parameters:
creation_time Holds the time at which this element was created.
See also:
GDynamicGeneratorCategory::createElement()

void GBE::GDynamicGeneratorAgent::initDensity ( unsigned short  density  )  [virtual]

Parameters:
density Specifies the density of the octree for element generation. A higher value gives finer grained child creation.
Note:
Every step means at maximum eight times more octree nodes!! High values should be avoided, a density of 5 can already give 32768 octree nodes! Still, the dynamic management of nodes minimises this memory exhaustion.

void GBE::GDynamicGeneratorAgent::initRandomSeed ( unsigned long  random_seed  )  [virtual]

Initializes given random seed for the pseudo RNG in the element data.

Parameters:
random_seed The seed with which the RNG starts at the initial position.

void GBE::GDynamicGeneratorAgent::loadData ( bool  force = false  )  [protected, virtual]

Loads current data from element data. But only if DataLoaded is false. Sets DataLoaded to true. If force is true then data is loaded from element data no matter what DataLoaded is set to.

void GBE::GDynamicGeneratorAgent::receiveInfluence ( const GCS::GElementInfluence influence  )  [virtual]

Reacts to user influences and creates contents of the element accordingly. That means, if a user is recognised at a certain location this agent will create element content in this area so it is visible and active for the user.

See also:
generateInArea()

void GBE::GDynamicGeneratorAgent::recursiveGeneration ( GDynamicGeneratorOctreeNode node,
const GCS::GVector3 position,
double  radius,
short unsigned  depth 
) [protected]

Implements recursive generation of elements in area. When the lowest level is reached (depth==this->Density) then a random value between 0 and 1 is generated with the seed of the node with which the category can be determined. Categories have a range. The Categories list will be iterated through and the range attribute of every category will be added. As soon as the determined random value is reached the currently selected category is used for element creation.


Member Data Documentation

QList<GDynamicGeneratorCategory*> GBE::GDynamicGeneratorAgent::Categories [protected]

Stores all available category implementations, these are used to generate child elements at certain nodes.

Note:
It is VERY important to have a total range size < 1 because the random value used to determine the category is between 0 and 1. If the random value is bigger than the sum of all categories then nothing is created at that position.
See also:
recursiveGeneration(), GDynamicGeneratorCategory

bool GBE::GDynamicGeneratorAgent::CreateAllAtOnce [protected]

Determines if all the element content should be created in one go as soon as a user influence is recognised. This is required if child elements heavily influence each other. Otherwise (like solar systems or galaxies) it can be set to false. Default value is false.

double GBE::GDynamicGeneratorAgent::CreationRangeFactor [protected]

Unless CreateAllAtOnce is set, the CreationRangeFactor is used to determine the actual area which needs to be generated. The radius of the element which sent the influence is multiplied with this factor to determine the actual creation area.

QDateTime GBE::GDynamicGeneratorAgent::CreationTime [protected]

Holds the time at which this element was created.

See also:
GDynamicGeneratorCategory::createElement()

bool GBE::GDynamicGeneratorAgent::DataLoaded [protected]

Is true if latest data has been fetched from element data. If it's false, the agent initializes its dat from element data and sets this attribute to true. It is false by default, which means it will initialize from element data. DataLoaded is checked whenever an influence arrives and thus the up-to-date data is needed.

unsigned short GBE::GDynamicGeneratorAgent::Density [protected]

Specifies the density of the octree for element generation. A higher value gives finer grained child creation.

Note:
Every step means at maximum eight times more octree nodes!! High values should be avoided, a density of 5 can already give 32768 octree nodes! Still, the dynamic management of nodes minimises this memory exhaustion.

double GBE::GDynamicGeneratorAgent::EnergyFractionChildCreation [private]

Holds the fraction of energy that should be taken from the own energy to create a child element. It is for the moment auto generated and it's simply better for the performance to have the value here rather than recomputing it for each element.

bool GBE::GDynamicGeneratorAgent::EnergyFractionDirtyFlag [private]

Set to true when the above value should be recalculated the next time it is needed.

unsigned long GBE::GDynamicGeneratorAgent::RandomSeed [protected]

The seed with which the RNG starts at the initial position.

Util::PseudoRNG GBE::GDynamicGeneratorAgent::RNG [protected]

The random number generator.

GDynamicGeneratorOctreeNode* GBE::GDynamicGeneratorAgent::TopNode [protected]

The top node of the octree which is used for content creation.


The documentation for this class was generated from the following files:
Generated on Thu Nov 16 07:49:20 2006 for G System by  doxygen 1.4.7