📄 sky.cc
字号:
mFogVolumes[x].percentage;
if(mStormFogData.volume[x].state == comingIn)
mStormFogData.current = 0;
else
mStormFogData.current = mNumFogVolumes-1;
}
else if(mFogVolume < mNumFogVolumes)
{
mStormFogData.volume[mFogVolume].speed = (mFogPercentage - mFogVolumes[mFogVolume].percentage) / ((mStormFogData.time * 32.0f) / (F32)mNumFogVolumes);
mStormFogData.volume[mFogVolume].state = (mFogVolumes[mFogVolume].percentage > mFogPercentage) ? goingOut : comingIn;
mStormFogData.volume[mFogVolume].endPercentage = mFogPercentage;
mStormFogData.current = mFogVolume;
}
}
//---------------------------------------------------------------------------
void Sky::updateFog()
{
F32 overFlow, offset = 1.0f;
U32 currentTime = Sim::getCurrentTime();
if(mStormFogData.lastTime != 0)
offset = F32(currentTime - mStormFogData.lastTime) / 32.0f;
Con::printf("OFFSET: %g", offset);
mStormFogData.lastTime = currentTime;
mFogVolumes[mStormFogData.current].percentage += (mStormFogData.volume[mStormFogData.current].speed * offset);
do
{
Con::printf("CURRENT: %d PERCENTAGE: %g TIME: %u",mStormFogData.current, mFogVolumes[mStormFogData.current].percentage, currentTime);
overFlow = 0.0f;
if(mStormFogData.volume[mStormFogData.current].state == comingIn && mFogVolumes[mStormFogData.current].percentage >= mStormFogData.volume[mStormFogData.current].endPercentage)
{
overFlow = mFogVolumes[mStormFogData.current].percentage - mStormFogData.volume[mStormFogData.current].endPercentage;
mFogVolumes[mStormFogData.current].percentage = mStormFogData.volume[mStormFogData.current].endPercentage;
mStormFogData.volume[mStormFogData.current].state = isDone;
if(++mStormFogData.current >= mNumFogVolumes)
{
mStormFogData.current -= 1;
mStormFogData.lastTime = 0;
mStormFogOn = false;
Con::printf("FOG IS DONE");
}
else
mFogVolumes[mStormFogData.current].percentage += overFlow;
}
else if(mStormFogData.volume[mStormFogData.current].state == goingOut && mFogVolumes[mStormFogData.current].percentage <= mStormFogData.volume[mStormFogData.current].endPercentage)
{
overFlow = mStormFogData.volume[mStormFogData.current].endPercentage - mFogVolumes[mStormFogData.current].percentage;
mFogVolumes[mStormFogData.current].percentage = mStormFogData.volume[mStormFogData.current].endPercentage;
mStormFogData.volume[mStormFogData.current].state = isDone;
if(--mStormFogData.current < 0)
{
mStormFogData.current += 1;
mStormFogData.lastTime = 0;
mStormFogOn = false;
Con::printf("FOG IS DONE");
}
else
mFogVolumes[mStormFogData.current].percentage -= overFlow;
}
} while(overFlow > 0.0f && mStormFogOn);
// if(mStormFogData.volume[mStormFogData.current].state != done)
mSceneManager->setFogVolumes(mNumFogVolumes, mFogVolumes);
}
//---------------------------------------------------------------------------
void Sky::updateRealFog()
{
for(S32 x = 0; x < mNumFogVolumes; ++x)
{
mFogVolumes[x].percentage += mStormFogData.volume[x].speed;
if((mStormFogData.volume[x].speed < 0.0f && mFogVolumes[x].percentage <= mStormFogData.volume[x].endPercentage) ||
(mStormFogData.volume[x].speed > 0.0f && mFogVolumes[x].percentage >= mStormFogData.volume[x].endPercentage))
{
mFogVolumes[x].percentage = mStormFogData.volume[x].endPercentage;
F32 save = mStormFogData.volume[x].lastPercentage;
mStormFogData.volume[x].lastPercentage = mStormFogData.volume[x].endPercentage;
mStormFogData.volume[x].endPercentage = save;
mStormFogData.volume[x].speed *= -1;
}
}
mSceneManager->setFogVolumes(mNumFogVolumes, mFogVolumes);
}
//---------------------------------------------------------------------------
void Sky::calcPoints()
{
S32 x, y, xval = 1, yval = -1, zval = 1;
F32 textureDem;
F32 visDisMod = mVisibleDistance;
if(gClientSceneGraph)
visDisMod = gClientSceneGraph->getVisibleDistanceMod();
mRadius = visDisMod * 0.95f;
Cloud::setRadius(mRadius);
Point3F tpt(1,1,1);
tpt.normalize(mRadius);
mPoints[0] = mPoints[4] = Point3F(-tpt.x, -tpt.y, tpt.z);
mPoints[5] = mPoints[9] = Point3F(-tpt.x, -tpt.y, -tpt.z);
for(x = 1; x < 4; ++x)
{
mPoints[x] = Point3F(tpt.x * xval, tpt.y * yval, tpt.z);
mPoints[x+5] = Point3F(tpt.x * xval, tpt.y * yval, -tpt.z);
if(yval > 0 && xval > 0)
xval *= -1;
if(yval < 0)
yval *= -1;
}
mFogLine = 0.0f;
for(x = 0; x < mNumFogVolumes; ++x)
mFogLine = (mFogVolumes[x].maxHeight > mFogLine) ? mFogVolumes[x].maxHeight : mFogLine;
textureDem = 512;
if(mSkyHandle[0])
textureDem = mSkyHandle[0].getWidth();
for(y = 0; y < 2 ; ++y)
for(x = 0; x < 2 ; ++x)
{
mTexCoord[x+(y*2)].set(x,y);
mTexCoord[x+(y*2)] *= (textureDem-1.0f)/textureDem;
mTexCoord[x+(y*2)] += Point2F(0.5 / textureDem, 0.5 / textureDem);
}
mSpherePt = mSkyBoxPt = mPoints[1];
mSpherePt.set(mSpherePt.x,0.0f,mSpherePt.z);
mSpherePt.normalize(mSkyBoxPt.x);
mTopCenterPt.set(0.0f,0.0f,mSkyBoxPt.z);
}
//---------------------------------------------------------------------------
bool Sky::loadDml()
{
char path[1024], *p;
dStrcpy(path, mMaterialListName);
if ((p = dStrrchr(path, '/')) != NULL)
*p = 0;
mNumCloudLayers = 0;
Stream *stream = ResourceManager->openStream(mMaterialListName);
if (stream==NULL)
{
#if defined(TORQUE_DEBUG)
Con::warnf("Sky material list is missing: %s", mMaterialListName);
#else
// ASSERT?? !!!!!!TBD
#endif
return false;
}
else
{// !!!!!TBD dhc - there's no fricking error checking here or in materialList.read!!!!
mMaterialList.read(*stream);
ResourceManager->closeStream(stream);
if(!mMaterialList.load(SkyTexture, path))
return false;
for(S32 x = 0; x < 6; ++x)
{
mMaterialList.getMaterial(x).setClamp(true);
mSkyHandle[x] = mMaterialList.getMaterial(x);
}
for(S32 x = 0; x < mMaterialList.size() - CloudMaterialOffset; ++x, ++mNumCloudLayers)
{
mMaterialList.getMaterial(x + CloudMaterialOffset).setClamp(false);
mCloudLayer[x].setTexture(mMaterialList.getMaterial(x + CloudMaterialOffset));
}
}
return true;
}
//---------------------------------------------------------------------------
void Sky::updateVisibility()
{
setVisibility();
setMaskBits(VisibilityMask);
}
//---------------------------------------------------------------------------
void Sky::stormCloudsOn(S32 state, F32 time)
{
mStormCloudData.state = (state) ? comingIn : goingOut;
mStormCloudData.time = time;
setMaskBits(StormCloudMask);
}
//---------------------------------------------------------------------------
void Sky::stormFogOn(F32 percentage, F32 time)
{
mStormFogData.time = time;
if(mStormFogData.endPercentage >= 0.0f)
{
mStormFogData.state = (mStormFogData.endPercentage > percentage) ? goingOut : comingIn;
mFogPercentage = mStormFogData.endPercentage;
}
else
mStormFogData.state = (mFogPercentage > percentage) ? goingOut : comingIn;
mStormFogData.endPercentage = percentage;
setMaskBits(StormFogMask);
}
//---------------------------------------------------------------------------
void Sky::stormRealFog(S32 value, F32 max, F32 min, F32 speed)
{
mRealFog = value;
mRealFogMax = max;
mRealFogMin = min;
mRealFogSpeed = speed;
setMaskBits(StormRealFogMask);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Cloud Code
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
Cloud::Cloud()
{
mDown=5;
mOver=1;
mBaseOffset.set(0, 0);
mTextureScale.set(1, 1);
mCenterHeight=0.5;
mInnerHeight=0.45;
mEdgeHeight=0.4;
mLastTime = 0;
mOffset=0;
mSpeed.set(1,1);
mGStormData.currentCloud = MAX_NUM_LAYERS;
mGStormData.fadeSpeed = 0.0f;
mGStormData.StormOn = false;
mGStormData.stormState = isDone;
for(int i = 0; i < 25; ++i)
stormAlpha[i] = 1.0f;
mRadius = 1.0f;
}
//---------------------------------------------------------------------------
Cloud::~Cloud()
{
}
//---------------------------------------------------------------------------
void Cloud::updateCoord()
{
mBaseOffset += mSpeed*mOffset;
if(mSpeed.x < 0)
mBaseOffset.x -= mCeil(mBaseOffset.x);
else
mBaseOffset.x -= mFloor(mBaseOffset.x);
if(mSpeed.y < 0)
mBaseOffset.y -= mCeil(mBaseOffset.y);
else
mBaseOffset.y -= mFloor(mBaseOffset.y);
}
//---------------------------------------------------------------------------
void Cloud::setHeights(F32 cHeight, F32 iHeight, F32 eHeight)
{
mCenterHeight = cHeight;
mInnerHeight = iHeight;
mEdgeHeight = eHeight;
}
//---------------------------------------------------------------------------
void Cloud::setTexture(TextureHandle textHand)
{
if(textHand)
{
mCloudHandle = textHand;
AssertFatal(bool(mCloudHandle) != false, "Error, couldn't load cloud layer bitmap");
}
}
//---------------------------------------------------------------------------
void Cloud::setSpeed(Point2F setSpeed)
{
mSpeed = setSpeed;
}
//---------------------------------------------------------------------------
void Cloud::setPoints()
{
S32 x, y;
F32 xyDiff = (mRadius - -mRadius)/4;
F32 cDis = mRadius*mCenterHeight,
upDis = mRadius*mInnerHeight,
edgeZ = mRadius*mEdgeHeight;
F32 zValue[25] = {edgeZ,edgeZ,edgeZ,edgeZ,edgeZ,edgeZ,upDis,upDis,upDis,edgeZ,edgeZ,upDis,cDis,upDis,edgeZ,edgeZ,upDis,upDis,upDis,edgeZ,edgeZ,edgeZ,edgeZ,edgeZ,edgeZ};
for(y = 0; y < 5; ++y)
for(x = 0; x < 5; ++x)
mPoints[y*5+x].set(-mRadius+(xyDiff*x),mRadius - (xyDiff*y),zValue[y*5+x]);
//Used to modify the corners of the cloud layers to make them one plane..
Point3F vec = (mPoints[5] + ((mPoints[1] - mPoints[5]) * 0.5f)) - mPoints[6];
mPoints[0] = mPoints[6] + (vec * 2.0f);
vec = (mPoints[9] + ((mPoints[3] - mPoints[9]) * 0.5f)) - mPoints[8];
mPoints[4] = mPoints[8] + (vec * 2.0f);
vec = (mPoints[21] + ((mPoints[15] - mPoints[21]) * 0.5f)) - mPoints[16];
mPoints[20] = mPoints[16] + (vec * 2.0f);
vec = (mPoints[23] + ((mPoints[19] - mPoints[23]) * 0.5f)) - mPoints[18];
mPoints[24] = mPoints[18] + (vec * 2.0f);
calcAlpha();
}
//---------------------------------------------------------------------------
void Cloud::calcAlpha()
{
for(S32 i = 0; i < 25; ++i)
{
mAlpha[i] = 1.3f - ((mPoints[i] - Point3F(0, 0, mPoints[i].z)).len())/mRadius;
if(mAlpha[i] < 0.4f)
mAlpha[i]=0.0f;
else if(mAlpha[i] > 0.8f)
mAlpha[i] = 1.0f;
}
}
//---------------------------------------------------------------------------
void Cloud::render(U32 currentTime, U32 cloudLayer, bool outlineOn, S32 numLayers, PlaneF* planes)
{
mGStormData.numCloudLayers = numLayers;
mOffset = 1.0f;
U32 numPoints;
Point3F renderPoints[128];
Point2F renderTexPoints[128];
F32 renderAlpha[128];
F32 renderSAlpha[128];
if(mLastTime != 0)
mOffset = (currentTime - mLastTime)/32.0f;
mLastTime=currentTime;
//celestial
ColorF dn;
if(gCelestials)
dn = gCelestials->mCurrentColor;
//celestial end
if(!mCloudHandle || (mGStormData.StormOn && mGStormData.currentCloud < cloudLayer))
return;
S32 start=0, i, j, k;
updateCoord();
for(S32 x = 0; x < 5; x++)
for(S32 y = 0; y < 5; y++)
mTexCoords[y * 5 + x].set ( x * mTextureScale.x + mBaseOffset.x,
y * mTextureScale.y - mBaseOffset.y);
if(mGStormData.StormOn && mGStormData.currentCloud == cloudLayer)
updateStorm();
if(!outlineOn)
{
glBindTexture(GL_TEXTURE_2D, mCloudHandle.getGLName());
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
for(i = 0; i < 4; ++i)
{
start = i * 5;
for(j = 0; j < 4; ++j )
{
numPoints = 4;
setRenderPoints(renderPoints, renderTexPoints, renderAlpha, renderSAlpha, start);
for(S32 i = 0; i < 4; ++i)
clipToPlane(renderPoints, renderTexPoints, renderAlpha, renderSAlpha,
numPoints, planes[i]);
if(!outlineOn)
glBegin(GL_TRIANGLE_FAN);
else
glBegin(GL_LINE_LOOP);
//celestial
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -