Re-enabled RenderAnimateTrees. Fixes issue 1101: http://goo.gl/YIvqSY

This commit is contained in:
Salvatore La Bua
2013-09-22 05:52:35 +02:00
parent 67720c6a6a
commit da4196c246
6 changed files with 209 additions and 42 deletions

View File

@@ -12221,7 +12221,7 @@ This should be as low as possible, but too low may break functionality</string>
<integer>0</integer> <integer>0</integer>
</map> </map>
<!--<key>RenderAnimateTrees</key> <key>RenderAnimateTrees</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
<string>Use GL matrix ops to animate tree branches.</string> <string>Use GL matrix ops to animate tree branches.</string>
@@ -12231,7 +12231,7 @@ This should be as low as possible, but too low may break functionality</string>
<string>Boolean</string> <string>Boolean</string>
<key>Value</key> <key>Value</key>
<integer>0</integer> <integer>0</integer>
</map>--> </map>
<key>RenderNoAlpha</key> <key>RenderNoAlpha</key>
<map> <map>
<key>Comment</key> <key>Comment</key>

View File

@@ -104,12 +104,12 @@ void LLDrawPoolTree::render(S32 pass)
LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1); LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1);
LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f); LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);
/*static const LLCachedControl<bool> render_animate_trees("RenderAnimateTrees",false); static LLCachedControl<bool> sRenderAnimateTrees("RenderAnimateTrees", false);
if (render_animate_trees) if (sRenderAnimateTrees)
{ {
renderTree(); renderTree();
} }
else*/ else
gGL.getTexUnit(sDiffTex)->bind(mTexturep); gGL.getTexUnit(sDiffTex)->bind(mTexturep);
for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
@@ -209,7 +209,7 @@ void LLDrawPoolTree::endShadowPass(S32 pass)
gDeferredTreeShadowProgram.unbind(); gDeferredTreeShadowProgram.unbind();
} }
/* //
void LLDrawPoolTree::renderTree(BOOL selecting) void LLDrawPoolTree::renderTree(BOOL selecting)
{ {
LLGLState normalize(GL_NORMALIZE, TRUE); LLGLState normalize(GL_NORMALIZE, TRUE);
@@ -331,7 +331,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
//gGL.popMatrix(); //gGL.popMatrix();
} }
} }
}*/ }//
BOOL LLDrawPoolTree::verify() const BOOL LLDrawPoolTree::verify() const
{ {

View File

@@ -75,8 +75,8 @@ public:
static S32 sDiffTex; static S32 sDiffTex;
//private: private:
//void renderTree(BOOL selecting = FALSE); void renderTree(BOOL selecting = FALSE);
}; };
#endif // LL_LLDRAWPOOLTREE_H #endif // LL_LLDRAWPOOLTREE_H

View File

@@ -642,7 +642,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
//gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));

View File

@@ -49,6 +49,7 @@
#include "llagentcamera.h" #include "llagentcamera.h"
#include "lldrawable.h" #include "lldrawable.h"
#include "llface.h" #include "llface.h"
#include "llselectmgr.h"
#include "llviewercamera.h" #include "llviewercamera.h"
#include "llviewertexturelist.h" #include "llviewertexturelist.h"
#include "llviewerobjectlist.h" #include "llviewerobjectlist.h"
@@ -57,6 +58,7 @@
#include "noise.h" #include "noise.h"
#include "pipeline.h" #include "pipeline.h"
#include "llspatialpartition.h" #include "llspatialpartition.h"
//#include "llviewerwindow.h"
#include "llnotificationsutil.h" #include "llnotificationsutil.h"
#include "raytrace.h" #include "raytrace.h"
#include "llglslshader.h" #include "llglslshader.h"
@@ -356,12 +358,47 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{ {
const U16 FRAMES_PER_WIND_UPDATE = 20; // How many frames between wind update per tree
const F32 TREE_WIND_SENSITIVITY = 0.005f;
const F32 TREE_TRUNK_STIFFNESS = 0.1f;
if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE))) if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE)))
{ {
return; return;
} }
S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; static LLCachedControl<bool> sRenderAnimateTrees(gSavedSettings, "RenderAnimateTrees");
if (sRenderAnimateTrees)
{
F32 mass_inv;
// For all tree objects, update the trunk bending with the current wind
// Walk sprite list in order away from viewer
if (!(mFrameCount % FRAMES_PER_WIND_UPDATE))
{
// If needed, Get latest wind for this tree
mWind = mRegionp->mWind.getVelocity(getPositionRegion());
}
mFrameCount++;
mass_inv = 1.f/(5.f + mDepth*mBranches*0.2f);
mTrunkVel += (mWind * mass_inv * TREE_WIND_SENSITIVITY); // Pull in direction of wind
mTrunkVel -= (mTrunkBend * mass_inv * TREE_TRUNK_STIFFNESS); // Restoring force in direction of trunk
mTrunkBend += mTrunkVel;
mTrunkVel *= 0.99f; // Add damping
if (mTrunkBend.length() > 1.f)
{
mTrunkBend.normalize();
}
if (mTrunkVel.length() > 1.f)
{
mTrunkVel.normalize();
}
}
S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS;
F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor; F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor;
for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++) for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++)
@@ -373,41 +410,45 @@ void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
} }
} }
if (mReferenceBuffer.isNull()) if (!sRenderAnimateTrees)
{ {
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); if (mReferenceBuffer.isNull())
}
else if (trunk_LOD != mTrunkLOD)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, FALSE);
}
else
{
// we're not animating but we may *still* need to
// regenerate the mesh if we moved, since position
// and rotation are baked into the mesh.
// *TODO: I don't know what's so special about trees
// that they don't get REBUILD_POSITION automatically
// at a higher level.
const LLVector3 &this_position = getPositionRegion();
if (this_position != mLastPosition)
{ {
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
mLastPosition = this_position; }
else if (trunk_LOD != mTrunkLOD)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, FALSE);
} }
else else
{ {
const LLQuaternion &this_rotation = getRotation(); // we're not animating but we may *still* need to
// regenerate the mesh if we moved, since position
if (this_rotation != mLastRotation) // and rotation are baked into the mesh.
// *TODO: I don't know what's so special about trees
// that they don't get REBUILD_POSITION automatically
// at a higher level.
const LLVector3 &this_position = getPositionRegion();
if (this_position != mLastPosition)
{ {
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
mLastRotation = this_rotation; mLastPosition = this_position;
}
else
{
const LLQuaternion &this_rotation = getRotation();
if (this_rotation != mLastRotation)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
mLastRotation = this_rotation;
}
} }
} }
} }
mTrunkLOD = trunk_LOD; mTrunkLOD = trunk_LOD;
//return TRUE;
} }
const F32 TREE_BLEND_MIN = 1.f; const F32 TREE_BLEND_MIN = 1.f;
@@ -541,7 +582,8 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
max_vertices += sLODVertexCount[lod]; max_vertices += sLODVertexCount[lod];
} }
mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, 0); static LLCachedControl<bool> sRenderAnimateTrees(gSavedSettings, "RenderAnimateTrees");
mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, sRenderAnimateTrees ? GL_STATIC_DRAW_ARB : 0);
mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE); mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE);
LLStrider<LLVector3> vertices; LLStrider<LLVector3> vertices;
@@ -845,8 +887,16 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
llassert(index_count == max_indices); llassert(index_count == max_indices);
} }
//generate tree mesh static LLCachedControl<bool> sRenderAnimateTrees(gSavedSettings, "RenderAnimateTrees");
updateMesh(); if (sRenderAnimateTrees)
{
mDrawable->getFace(0)->setVertexBuffer(mReferenceBuffer);
}
else
{
//generate tree mesh
updateMesh();
}
return TRUE; return TRUE;
} }
@@ -1314,3 +1364,110 @@ LLTreePartition::LLTreePartition()
mLODPeriod = 1; mLODPeriod = 1;
} }
void LLVOTree::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
std::vector<LLVector3> &normals,
const LLVector3& obj_cam_vec,
const LLMatrix4& local_matrix,
const LLMatrix3& normal_matrix)
{
vertices.clear();
normals.clear();
F32 height = mBillboardScale; // *mBillboardRatio * 0.5;
F32 width = height * mTrunkAspect;
LLVector3 position1 = LLVector3(-width * 0.5, 0, 0) * local_matrix;
LLVector3 position2 = LLVector3(-width * 0.5, 0, height) * local_matrix;
LLVector3 position3 = LLVector3(width * 0.5, 0, height) * local_matrix;
LLVector3 position4 = LLVector3(width * 0.5, 0, 0) * local_matrix;
LLVector3 position5 = LLVector3(0, -width * 0.5, 0) * local_matrix;
LLVector3 position6 = LLVector3(0, -width * 0.5, height) * local_matrix;
LLVector3 position7 = LLVector3(0, width * 0.5, height) * local_matrix;
LLVector3 position8 = LLVector3(0, width * 0.5, 0) * local_matrix;
LLVector3 normal = (position1 - position2) % (position2 - position3);
normal.normalize();
vertices.push_back(position1);
normals.push_back(normal);
vertices.push_back(position2);
normals.push_back(normal);
vertices.push_back(position2);
normals.push_back(normal);
vertices.push_back(position3);
normals.push_back(normal);
vertices.push_back(position3);
normals.push_back(normal);
vertices.push_back(position4);
normals.push_back(normal);
vertices.push_back(position4);
normals.push_back(normal);
vertices.push_back(position1);
normals.push_back(normal);
normal = (position5 - position6) % (position6 - position7);
normal.normalize();
vertices.push_back(position5);
normals.push_back(normal);
vertices.push_back(position6);
normals.push_back(normal);
vertices.push_back(position6);
normals.push_back(normal);
vertices.push_back(position7);
normals.push_back(normal);
vertices.push_back(position7);
normals.push_back(normal);
vertices.push_back(position8);
normals.push_back(normal);
vertices.push_back(position8);
normals.push_back(normal);
vertices.push_back(position5);
normals.push_back(normal);
}
void LLVOTree::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
{
LLVector3 position;
LLQuaternion rotation;
if (mDrawable->isActive())
{
if (mDrawable->isSpatialRoot())
{
position = LLVector3();
rotation = LLQuaternion();
}
else
{
position = mDrawable->getPosition();
rotation = mDrawable->getRotation();
}
}
else
{
position = getPosition() + getRegion()->getOriginAgent();
rotation = getRotation();
}
// trees have bizzare scaling rules... because it's cool to make needless exceptions
// PS: the trees are the last remaining tidbit of Philip's code. take a look sometime.
F32 radius = getScale().length() * 0.05f;
LLVector3 scale = LLVector3(1, 1, 1) * radius;
// compose final matrix
LLMatrix4 local_matrix;
local_matrix.initAll(scale, rotation, position);
generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals,
LLVector3(0, 0, 0), local_matrix, LLMatrix3());
nodep->mSilhouetteExists = TRUE;
}

View File

@@ -39,6 +39,7 @@
class LLFace; class LLFace;
class LLDrawPool; class LLDrawPool;
class LLSelectNode;
class LLViewerFetchedTexture; class LLViewerFetchedTexture;
class LLVOTree : public LLViewerObject class LLVOTree : public LLViewerObject
@@ -122,8 +123,9 @@ public:
LLVector3* intersection = NULL, // return the intersection point LLVector3* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
LLVector3* normal = NULL, // return the surface normal at the intersection point LLVector3* normal = NULL, // return the surface normal at the intersection point
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
);
void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
static S32 sMaxTreeSpecies; static S32 sMaxTreeSpecies;
@@ -162,6 +164,7 @@ public:
friend class LLDrawPoolTree; friend class LLDrawPoolTree;
protected: protected:
LLVector3 mTrunkBend; // Accumulated wind (used for blowing trees) LLVector3 mTrunkBend; // Accumulated wind (used for blowing trees)
LLVector3 mTrunkVel; //
LLVector3 mWind; LLVector3 mWind;
LLPointer<LLVertexBuffer> mReferenceBuffer; //reference geometry for generating tree mesh LLPointer<LLVertexBuffer> mReferenceBuffer; //reference geometry for generating tree mesh
@@ -201,6 +204,13 @@ protected:
static S32 sLODVertexCount[4]; static S32 sLODVertexCount[4];
static S32 sLODSlices[4]; static S32 sLODSlices[4];
static F32 sLODAngles[4]; static F32 sLODAngles[4];
private:
void generateSilhouetteVertices(std::vector<LLVector3> &vertices,
std::vector<LLVector3> &normals,
const LLVector3& view_vec,
const LLMatrix4& mat,
const LLMatrix3& norm_mat);
}; };
#endif #endif