Add support for using textures as a basis for cloud fields. This is not yet completely finished. The orientation is not right.

This commit is contained in:
ehofman
2003-08-07 12:34:23 +00:00
parent 54b3c711c3
commit 0dd50cf3d8
7 changed files with 168 additions and 10 deletions

View File

@@ -26,16 +26,6 @@
#include <assert.h>
// FIXME: Remove this section whenever plib has it's own endian conversion
// funcrtions for 64-bit data types.
#ifndef ulEndianLittleDouble
// This hack doesn't actually do anything, but it's pressence
// marks the places that need endiannes attention.
inline double ulEndianLittleDouble(double x) {
return x;
}
#endif
struct SkyArchiveEntry
{
SkyArchiveEntry() : type(0), pData(NULL), iDataSize(0) {}

View File

@@ -624,6 +624,102 @@ SkyMinMaxBox* SkyCloud::CopyBoundingVolume() const
return pBox;
}
SKYRESULT SkyCloud::Load(const unsigned char *data, unsigned int size,
float rScale, /* = 1.0f */
double latitude, double longitude )
{
unsigned int iNumParticles;
Vec3f vecCenter = Vec3f::ZERO;
//Vec3f vecCenter;
//float rRadius;
//_boundingBox.SetMin(vecCenter - Vec3f(rRadius, rRadius, rRadius));
//_boundingBox.SetMax(vecCenter + Vec3f(rRadius, rRadius, rRadius));
for (unsigned int i = 0; i < size*size*4; i += 4)
{
Vec3f pos;
Vec4f color;
float radius;
color.x = data[i]; // FIXME: Which unit?
color.y = data[i+1];
color.z = data[i+2];
color.w = data[i+3];
radius = (color.w/255) * rScale;
//radius = (color.x * color.y * color.z * color.w * rScale) / 4096;
pos.x = (i / (size*4)) * 10; // FIXME: Which unit?
pos.y = (i % (size*4)) * 10;
pos.z = radius / 2;
if (radius > 0)
{
SkyCloudParticle *pParticle = new SkyCloudParticle((pos + vecCenter) * rScale, radius * rScale, color);
_boundingBox.AddPoint(pParticle->GetPosition());
_particles.push_back(pParticle);
}
}
// this is just a bad hack to align cloud field from skyworks with local horizon at KSFO
// this "almost" works not quite the right solution okay to get some up and running
// we need to develop our own scheme for loading and positioning clouds
Mat33f R;
Vec3f moveit;
R.Set( 0, 1, 0,
1, 0, 0,
0, 0, 1);
// clouds sit in the y-z plane and x-axis is the vertical cloud height
Rotate( R );
// rotate the cloud field about the fgfs z-axis based on initial longitude
float ex = 1.0;
float ey = 1.0;
float ez = 1.0;
float phi = longitude / 57.29578;
float one_min_cos = 1 - cos(phi);
R.Set(
cos(phi) + one_min_cos*ex*ex, one_min_cos*ex*ey - ez*sin(phi), one_min_cos*ex*ez + ey*sin(phi),
one_min_cos*ex*ey + ez*sin(phi), cos(phi) + one_min_cos*ey*ey, one_min_cos*ey*ez - ex*sin(phi),
one_min_cos*ex*ez - ey*sin(phi), one_min_cos*ey*ez + ex*sin(phi), cos(phi) + one_min_cos*ez*ez );
Rotate( R );
// okay now that let's rotate about a vector for latitude where longitude forms the
// components of a unit vector in the x-y plane
ex = sin( longitude / 57.29578 );
ey = -cos( longitude / 57.29578 );
ez = 0.0;
phi = latitude / 57.29578;
one_min_cos = 1 - cos(phi);
R.Set(
cos(phi) + one_min_cos*ex*ex, one_min_cos*ex*ey - ez*sin(phi), one_min_cos*ex*ez + ey*sin(phi),
one_min_cos*ex*ey + ez*sin(phi), cos(phi) + one_min_cos*ey*ey, one_min_cos*ey*ez - ex*sin(phi),
one_min_cos*ex*ez - ey*sin(phi), one_min_cos*ey*ez + ex*sin(phi), cos(phi) + one_min_cos*ez*ez );
Rotate( R );
// need to calculate an offset to place the clouds at ~3000 feet MSL ATM this is an approximation
// to move the clouds to some altitude above sea level. At some locations this could be underground
// will need a better scheme to position clouds per user preferences
float cloud_level_msl = 3000.0f;
float x_offset = ex * cloud_level_msl;
float y_offset = ey * cloud_level_msl;
float z_offset = cloud_level_msl * 0.5;
moveit.Set( x_offset, y_offset, z_offset );
Translate( moveit );
return SKYRESULT_OK;
}
SKYRESULT SkyCloud::Load(const SkyArchive &archive,
float rScale, /* = 1.0f */
double latitude, double longitude )

View File

@@ -99,6 +99,7 @@ public:
SKYRESULT Save(SkyArchive &archive) const;
SKYRESULT Load(const SkyArchive &archive, float rScale = 1.0f,double latitude=0.0, double longitude=0.0);
SKYRESULT Load(const unsigned char *data, unsigned int size, float rScale = 1.0f,double latitude=0.0,double longitude=0.0);
void Rotate(const Mat33f& rot);
void Translate(const Vec3f& trans);

View File

@@ -89,6 +89,52 @@ SkySceneLoader::~SkySceneLoader()
}
//------------------------------------------------------------------------------
// Function : SkySceneLoader::Load
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneLoader::Load(std::string filename)
* @brief Loads a SkyWorks scene.
*
* This is a temporary fix, as it loads only limited scenes
* It can however, load any number of Cloud
+
*/
//bool SkySceneLoader::Load(std::string filepath)
bool SkySceneLoader::Load( unsigned char *data, unsigned int size, double latitude, double longitude )
{
// Need to create the managers
cout << "GraphicsContext::Instantiate();" << endl;
GraphicsContext::Instantiate();
cout << " TextureManager::Instantiate();" << endl;
TextureManager::Instantiate();
cout << " DynamicTextureManager::Instantiate();" << endl;
DynamicTextureManager::Instantiate();
cout << " SceneManager::Instantiate();" << endl;
SceneManager::Instantiate();
float rScale = 40.0;
FAIL_RETURN(SceneManager::InstancePtr()->LoadClouds(data, size, rScale, latitude, longitude));
Vec3f dir(0, 0, 1);
pLight->SetPosition(Vec3f(0, 0, 17000));
pLight->SetDirection(dir);
pLight->SetAmbient(Vec4f( 0.0f, 0.0f, 0.0f, 0.0f));
pLight->SetDiffuse(Vec4f(1.0f, 1.0f, 1.0f, 0.0f));
//pLight->SetDiffuse(Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
//pLight->SetSpecular(Vec4f(1.0f, 1.0f, 1.0f, 0.0f));
// No attenuation
pLight->SetAttenuation(1.0f, 0.0f, 0.0f);
SceneManager::InstancePtr()->AddLight(pLight);
SceneManager::InstancePtr()->ShadeClouds();
return true;
}
//------------------------------------------------------------------------------
// Function : SkySceneLoader::Load
// Description :

View File

@@ -48,6 +48,7 @@ public:
SkySceneLoader();
~SkySceneLoader();
bool Load( unsigned char *data, unsigned int size, double latitude, double longitude );
bool Load( SGPath fileroot, double latitude, double longitude );
void Set_Cloud_Orig( Point3D *posit );

View File

@@ -499,6 +499,29 @@ SKYRESULT SkySceneManager::ShadeClouds()
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::LoadClouds
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::LoadClouds(SkyArchive& cloudArchive, float rScale)
* @brief @todo <WRITE BRIEF SkySceneManager::LoadClouds DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::LoadClouds FUNCTION DOCUMENTATION>
*/
SKYRESULT SkySceneManager::LoadClouds(unsigned char *data, unsigned int size, float rScale, double latitude, double longitude)
{
SkyCloud *pCloud = new SkyCloud();
pCloud->Load(data, size, rScale, latitude, longitude);
SkyRenderableInstanceCloud *pInstance = new SkyRenderableInstanceCloud(pCloud, false);
AddCloud(pCloud);
AddCloudInstance(pInstance);
RebuildCloudBVTree();
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::LoadClouds
// Description :

View File

@@ -104,6 +104,7 @@ public:
static void SortInstances(InstanceArray& instances, const Vec3f& vecSortPoint);
// load a set of clouds from an archive file.
SKYRESULT LoadClouds(unsigned char *data, unsigned int size, float rScale = 1.0f, double latitude=0.0, double longitude=0.0);
SKYRESULT LoadClouds(SkyArchive& cloudArchive, float rScale = 1.0f, double latitude=0.0, double longitude=0.0);
protected: // datatypes