diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-15 11:16:27 +0300 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-15 11:16:27 +0300 |
commit | bccc10db9a90d365c353baebf443fde2030ce970 (patch) | |
tree | 2c2e1fd94b29667a809f8d7285d049f5ff5d424d /indra/newview/llvotree.cpp | |
parent | 531cd34f670170ade57f8813fe48012b61a1d3c2 (diff) | |
parent | bb3c36f5cbc0c3b542045fd27255eee24e03da22 (diff) |
Merge branch 'main' into marchcat/x-b-merge
# Conflicts:
# autobuild.xml
# indra/cmake/ConfigurePkgConfig.cmake
# indra/cmake/ICU4C.cmake
# indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
# indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h
# indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
# indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
# indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
# indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
# indra/newview/llappviewerlinux_api.h
# indra/newview/llappviewerlinux_api_dbus.cpp
# indra/newview/llappviewerlinux_api_dbus.h
# indra/newview/llfloateremojipicker.cpp
# indra/newview/lloutfitslist.cpp
Diffstat (limited to 'indra/newview/llvotree.cpp')
-rw-r--r-- | indra/newview/llvotree.cpp | 1998 |
1 files changed, 999 insertions, 999 deletions
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 575b1dbe7e..8b229ec98b 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvotree.cpp * @brief LLVOTree class implementation * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library 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; * version 2.1 of the License only. - * + * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -81,291 +81,291 @@ S32 LLVOTree::sMaxTreeSpecies = 0; // Tree variables and functions LLVOTree::LLVOTree(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp): - LLViewerObject(id, pcode, regionp) + LLViewerObject(id, pcode, regionp) { - mSpecies = 0; - mFrameCount = 0; - mWind = mRegionp->mWind.getVelocity(getPositionRegion()); - mTrunkLOD = 0; + mSpecies = 0; + mFrameCount = 0; + mWind = mRegionp->mWind.getVelocity(getPositionRegion()); + mTrunkLOD = 0; - // if assert triggers, idleUpdate() needs to be revised and adjusted to new LOD levels - llassert(sMAX_NUM_TREE_LOD_LEVELS == LLVolumeLODGroup::NUM_LODS); + // if assert triggers, idleUpdate() needs to be revised and adjusted to new LOD levels + llassert(sMAX_NUM_TREE_LOD_LEVELS == LLVolumeLODGroup::NUM_LODS); } LLVOTree::~LLVOTree() { - if (mData) - { - delete[] mData; - mData = NULL; - } + if (mData) + { + delete[] mData; + mData = NULL; + } } //static bool LLVOTree::isTreeRenderingStopped() { - return LLVOTree::sTreeFactor < LLVOTree::sLODAngles[sMAX_NUM_TREE_LOD_LEVELS - 1] ; + return LLVOTree::sTreeFactor < LLVOTree::sLODAngles[sMAX_NUM_TREE_LOD_LEVELS - 1] ; } // static void LLVOTree::initClass() { - std::string xml_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"trees.xml"); - - LLXmlTree tree_def_tree; - - if (!tree_def_tree.parseFile(xml_filename)) - { - LL_ERRS() << "Failed to parse tree file." << LL_ENDL; - } - - LLXmlTreeNode* rootp = tree_def_tree.getRoot(); - - for (LLXmlTreeNode* tree_def = rootp->getFirstChild(); - tree_def; - tree_def = rootp->getNextChild()) - { - if (!tree_def->hasName("tree")) - { - LL_WARNS() << "Invalid tree definition node " << tree_def->getName() << LL_ENDL; - continue; - } - F32 F32_val; - LLUUID id; - S32 S32_val; - - BOOL success = TRUE; - - - - S32 species; - static LLStdStringHandle species_id_string = LLXmlTree::addAttributeString("species_id"); - if (!tree_def->getFastAttributeS32(species_id_string, species)) - { - LL_WARNS() << "No species id defined" << LL_ENDL; - continue; - } - - if (species < 0) - { - LL_WARNS() << "Invalid species id " << species << LL_ENDL; - continue; - } - - if (sSpeciesTable.count(species)) - { - LL_WARNS() << "Tree species " << species << " already defined! Duplicate discarded." << LL_ENDL; - continue; - } - - TreeSpeciesData* newTree = new TreeSpeciesData(); - - static LLStdStringHandle texture_id_string = LLXmlTree::addAttributeString("texture_id"); - success &= tree_def->getFastAttributeUUID(texture_id_string, id); - newTree->mTextureID = id; - - static LLStdStringHandle droop_string = LLXmlTree::addAttributeString("droop"); - success &= tree_def->getFastAttributeF32(droop_string, F32_val); - newTree->mDroop = F32_val; - - static LLStdStringHandle twist_string = LLXmlTree::addAttributeString("twist"); - success &= tree_def->getFastAttributeF32(twist_string, F32_val); - newTree->mTwist = F32_val; - - static LLStdStringHandle branches_string = LLXmlTree::addAttributeString("branches"); - success &= tree_def->getFastAttributeF32(branches_string, F32_val); - newTree->mBranches = F32_val; - - static LLStdStringHandle depth_string = LLXmlTree::addAttributeString("depth"); - success &= tree_def->getFastAttributeS32(depth_string, S32_val); - newTree->mDepth = S32_val; - - static LLStdStringHandle scale_step_string = LLXmlTree::addAttributeString("scale_step"); - success &= tree_def->getFastAttributeF32(scale_step_string, F32_val); - newTree->mScaleStep = F32_val; - - static LLStdStringHandle trunk_depth_string = LLXmlTree::addAttributeString("trunk_depth"); - success &= tree_def->getFastAttributeS32(trunk_depth_string, S32_val); - newTree->mTrunkDepth = S32_val; - - static LLStdStringHandle branch_length_string = LLXmlTree::addAttributeString("branch_length"); - success &= tree_def->getFastAttributeF32(branch_length_string, F32_val); - newTree->mBranchLength = F32_val; - - static LLStdStringHandle trunk_length_string = LLXmlTree::addAttributeString("trunk_length"); - success &= tree_def->getFastAttributeF32(trunk_length_string, F32_val); - newTree->mTrunkLength = F32_val; - - static LLStdStringHandle leaf_scale_string = LLXmlTree::addAttributeString("leaf_scale"); - success &= tree_def->getFastAttributeF32(leaf_scale_string, F32_val); - newTree->mLeafScale = F32_val; - - static LLStdStringHandle billboard_scale_string = LLXmlTree::addAttributeString("billboard_scale"); - success &= tree_def->getFastAttributeF32(billboard_scale_string, F32_val); - newTree->mBillboardScale = F32_val; - - static LLStdStringHandle billboard_ratio_string = LLXmlTree::addAttributeString("billboard_ratio"); - success &= tree_def->getFastAttributeF32(billboard_ratio_string, F32_val); - newTree->mBillboardRatio = F32_val; - - static LLStdStringHandle trunk_aspect_string = LLXmlTree::addAttributeString("trunk_aspect"); - success &= tree_def->getFastAttributeF32(trunk_aspect_string, F32_val); - newTree->mTrunkAspect = F32_val; - - static LLStdStringHandle branch_aspect_string = LLXmlTree::addAttributeString("branch_aspect"); - success &= tree_def->getFastAttributeF32(branch_aspect_string, F32_val); - newTree->mBranchAspect = F32_val; - - static LLStdStringHandle leaf_rotate_string = LLXmlTree::addAttributeString("leaf_rotate"); - success &= tree_def->getFastAttributeF32(leaf_rotate_string, F32_val); - newTree->mRandomLeafRotate = F32_val; - - static LLStdStringHandle noise_mag_string = LLXmlTree::addAttributeString("noise_mag"); - success &= tree_def->getFastAttributeF32(noise_mag_string, F32_val); - newTree->mNoiseMag = F32_val; - - static LLStdStringHandle noise_scale_string = LLXmlTree::addAttributeString("noise_scale"); - success &= tree_def->getFastAttributeF32(noise_scale_string, F32_val); - newTree->mNoiseScale = F32_val; - - static LLStdStringHandle taper_string = LLXmlTree::addAttributeString("taper"); - success &= tree_def->getFastAttributeF32(taper_string, F32_val); - newTree->mTaper = F32_val; - - static LLStdStringHandle repeat_z_string = LLXmlTree::addAttributeString("repeat_z"); - success &= tree_def->getFastAttributeF32(repeat_z_string, F32_val); - newTree->mRepeatTrunkZ = F32_val; - - sSpeciesTable[species] = newTree; - - if (species >= sMaxTreeSpecies) sMaxTreeSpecies = species + 1; - - if (!success) - { - std::string name; - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - tree_def->getFastAttributeString(name_string, name); - LL_WARNS() << "Incomplete definition of tree " << name << LL_ENDL; - } - } - - BOOL have_all_trees = TRUE; - std::string err; - - for (S32 i=0;i<sMaxTreeSpecies;++i) - { - if (!sSpeciesTable.count(i)) - { - err.append(llformat(" %d",i)); - have_all_trees = FALSE; - } - } - - if (!have_all_trees) - { - LLSD args; - args["SPECIES"] = err; - LLNotificationsUtil::add("ErrorUndefinedTrees", args); - } + std::string xml_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"trees.xml"); + + LLXmlTree tree_def_tree; + + if (!tree_def_tree.parseFile(xml_filename)) + { + LL_ERRS() << "Failed to parse tree file." << LL_ENDL; + } + + LLXmlTreeNode* rootp = tree_def_tree.getRoot(); + + for (LLXmlTreeNode* tree_def = rootp->getFirstChild(); + tree_def; + tree_def = rootp->getNextChild()) + { + if (!tree_def->hasName("tree")) + { + LL_WARNS() << "Invalid tree definition node " << tree_def->getName() << LL_ENDL; + continue; + } + F32 F32_val; + LLUUID id; + S32 S32_val; + + BOOL success = TRUE; + + + + S32 species; + static LLStdStringHandle species_id_string = LLXmlTree::addAttributeString("species_id"); + if (!tree_def->getFastAttributeS32(species_id_string, species)) + { + LL_WARNS() << "No species id defined" << LL_ENDL; + continue; + } + + if (species < 0) + { + LL_WARNS() << "Invalid species id " << species << LL_ENDL; + continue; + } + + if (sSpeciesTable.count(species)) + { + LL_WARNS() << "Tree species " << species << " already defined! Duplicate discarded." << LL_ENDL; + continue; + } + + TreeSpeciesData* newTree = new TreeSpeciesData(); + + static LLStdStringHandle texture_id_string = LLXmlTree::addAttributeString("texture_id"); + success &= tree_def->getFastAttributeUUID(texture_id_string, id); + newTree->mTextureID = id; + + static LLStdStringHandle droop_string = LLXmlTree::addAttributeString("droop"); + success &= tree_def->getFastAttributeF32(droop_string, F32_val); + newTree->mDroop = F32_val; + + static LLStdStringHandle twist_string = LLXmlTree::addAttributeString("twist"); + success &= tree_def->getFastAttributeF32(twist_string, F32_val); + newTree->mTwist = F32_val; + + static LLStdStringHandle branches_string = LLXmlTree::addAttributeString("branches"); + success &= tree_def->getFastAttributeF32(branches_string, F32_val); + newTree->mBranches = F32_val; + + static LLStdStringHandle depth_string = LLXmlTree::addAttributeString("depth"); + success &= tree_def->getFastAttributeS32(depth_string, S32_val); + newTree->mDepth = S32_val; + + static LLStdStringHandle scale_step_string = LLXmlTree::addAttributeString("scale_step"); + success &= tree_def->getFastAttributeF32(scale_step_string, F32_val); + newTree->mScaleStep = F32_val; + + static LLStdStringHandle trunk_depth_string = LLXmlTree::addAttributeString("trunk_depth"); + success &= tree_def->getFastAttributeS32(trunk_depth_string, S32_val); + newTree->mTrunkDepth = S32_val; + + static LLStdStringHandle branch_length_string = LLXmlTree::addAttributeString("branch_length"); + success &= tree_def->getFastAttributeF32(branch_length_string, F32_val); + newTree->mBranchLength = F32_val; + + static LLStdStringHandle trunk_length_string = LLXmlTree::addAttributeString("trunk_length"); + success &= tree_def->getFastAttributeF32(trunk_length_string, F32_val); + newTree->mTrunkLength = F32_val; + + static LLStdStringHandle leaf_scale_string = LLXmlTree::addAttributeString("leaf_scale"); + success &= tree_def->getFastAttributeF32(leaf_scale_string, F32_val); + newTree->mLeafScale = F32_val; + + static LLStdStringHandle billboard_scale_string = LLXmlTree::addAttributeString("billboard_scale"); + success &= tree_def->getFastAttributeF32(billboard_scale_string, F32_val); + newTree->mBillboardScale = F32_val; + + static LLStdStringHandle billboard_ratio_string = LLXmlTree::addAttributeString("billboard_ratio"); + success &= tree_def->getFastAttributeF32(billboard_ratio_string, F32_val); + newTree->mBillboardRatio = F32_val; + + static LLStdStringHandle trunk_aspect_string = LLXmlTree::addAttributeString("trunk_aspect"); + success &= tree_def->getFastAttributeF32(trunk_aspect_string, F32_val); + newTree->mTrunkAspect = F32_val; + + static LLStdStringHandle branch_aspect_string = LLXmlTree::addAttributeString("branch_aspect"); + success &= tree_def->getFastAttributeF32(branch_aspect_string, F32_val); + newTree->mBranchAspect = F32_val; + + static LLStdStringHandle leaf_rotate_string = LLXmlTree::addAttributeString("leaf_rotate"); + success &= tree_def->getFastAttributeF32(leaf_rotate_string, F32_val); + newTree->mRandomLeafRotate = F32_val; + + static LLStdStringHandle noise_mag_string = LLXmlTree::addAttributeString("noise_mag"); + success &= tree_def->getFastAttributeF32(noise_mag_string, F32_val); + newTree->mNoiseMag = F32_val; + + static LLStdStringHandle noise_scale_string = LLXmlTree::addAttributeString("noise_scale"); + success &= tree_def->getFastAttributeF32(noise_scale_string, F32_val); + newTree->mNoiseScale = F32_val; + + static LLStdStringHandle taper_string = LLXmlTree::addAttributeString("taper"); + success &= tree_def->getFastAttributeF32(taper_string, F32_val); + newTree->mTaper = F32_val; + + static LLStdStringHandle repeat_z_string = LLXmlTree::addAttributeString("repeat_z"); + success &= tree_def->getFastAttributeF32(repeat_z_string, F32_val); + newTree->mRepeatTrunkZ = F32_val; + + sSpeciesTable[species] = newTree; + + if (species >= sMaxTreeSpecies) sMaxTreeSpecies = species + 1; + + if (!success) + { + std::string name; + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); + tree_def->getFastAttributeString(name_string, name); + LL_WARNS() << "Incomplete definition of tree " << name << LL_ENDL; + } + } + + BOOL have_all_trees = TRUE; + std::string err; + + for (S32 i=0;i<sMaxTreeSpecies;++i) + { + if (!sSpeciesTable.count(i)) + { + err.append(llformat(" %d",i)); + have_all_trees = FALSE; + } + } + + if (!have_all_trees) + { + LLSD args; + args["SPECIES"] = err; + LLNotificationsUtil::add("ErrorUndefinedTrees", args); + } }; //static void LLVOTree::cleanupClass() { - std::for_each(sSpeciesTable.begin(), sSpeciesTable.end(), DeletePairedPointer()); - sSpeciesTable.clear(); + std::for_each(sSpeciesTable.begin(), sSpeciesTable.end(), DeletePairedPointer()); + sSpeciesTable.clear(); } U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, EObjectUpdateType update_type, - LLDataPacker *dp) + void **user_data, + U32 block_num, EObjectUpdateType update_type, + LLDataPacker *dp) { - // Do base class updates... - U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); - - if ( (getVelocity().lengthSquared() > 0.f) - ||(getAcceleration().lengthSquared() > 0.f) - ||(getAngularVelocity().lengthSquared() > 0.f)) - { - LL_INFOS() << "ACK! Moving tree!" << LL_ENDL; - setVelocity(LLVector3::zero); - setAcceleration(LLVector3::zero); - setAngularVelocity(LLVector3::zero); - } - - if (update_type == OUT_TERSE_IMPROVED) - { - // Nothing else needs to be done for the terse message. - return retval; - } - - // - // Load Instance-Specific data - // - if (mData) - { - mSpecies = ((U8 *)mData)[0]; - } - - if (!sSpeciesTable.count(mSpecies)) - { - if (sSpeciesTable.size()) - { - SpeciesMap::const_iterator it = sSpeciesTable.begin(); - mSpecies = (*it).first; - } - } - - // - // Load Species-Specific data - // - static const S32 MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 32 ; //frames. - mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - mTreeImagep->setMaxVirtualSizeResetInterval(MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); //allow to wait for at most 16 frames to reset virtual size. - - mBranchLength = sSpeciesTable[mSpecies]->mBranchLength; - mTrunkLength = sSpeciesTable[mSpecies]->mTrunkLength; - mLeafScale = sSpeciesTable[mSpecies]->mLeafScale; - mDroop = sSpeciesTable[mSpecies]->mDroop; - mTwist = sSpeciesTable[mSpecies]->mTwist; - mBranches = sSpeciesTable[mSpecies]->mBranches; - mDepth = sSpeciesTable[mSpecies]->mDepth; - mScaleStep = sSpeciesTable[mSpecies]->mScaleStep; - mTrunkDepth = sSpeciesTable[mSpecies]->mTrunkDepth; - mBillboardScale = sSpeciesTable[mSpecies]->mBillboardScale; - mBillboardRatio = sSpeciesTable[mSpecies]->mBillboardRatio; - mTrunkAspect = sSpeciesTable[mSpecies]->mTrunkAspect; - mBranchAspect = sSpeciesTable[mSpecies]->mBranchAspect; - - // position change not caused by us, etc. make sure to rebuild. - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - - return retval; + // Do base class updates... + U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); + + if ( (getVelocity().lengthSquared() > 0.f) + ||(getAcceleration().lengthSquared() > 0.f) + ||(getAngularVelocity().lengthSquared() > 0.f)) + { + LL_INFOS() << "ACK! Moving tree!" << LL_ENDL; + setVelocity(LLVector3::zero); + setAcceleration(LLVector3::zero); + setAngularVelocity(LLVector3::zero); + } + + if (update_type == OUT_TERSE_IMPROVED) + { + // Nothing else needs to be done for the terse message. + return retval; + } + + // + // Load Instance-Specific data + // + if (mData) + { + mSpecies = ((U8 *)mData)[0]; + } + + if (!sSpeciesTable.count(mSpecies)) + { + if (sSpeciesTable.size()) + { + SpeciesMap::const_iterator it = sSpeciesTable.begin(); + mSpecies = (*it).first; + } + } + + // + // Load Species-Specific data + // + static const S32 MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 32 ; //frames. + mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mTreeImagep->setMaxVirtualSizeResetInterval(MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); //allow to wait for at most 16 frames to reset virtual size. + + mBranchLength = sSpeciesTable[mSpecies]->mBranchLength; + mTrunkLength = sSpeciesTable[mSpecies]->mTrunkLength; + mLeafScale = sSpeciesTable[mSpecies]->mLeafScale; + mDroop = sSpeciesTable[mSpecies]->mDroop; + mTwist = sSpeciesTable[mSpecies]->mTwist; + mBranches = sSpeciesTable[mSpecies]->mBranches; + mDepth = sSpeciesTable[mSpecies]->mDepth; + mScaleStep = sSpeciesTable[mSpecies]->mScaleStep; + mTrunkDepth = sSpeciesTable[mSpecies]->mTrunkDepth; + mBillboardScale = sSpeciesTable[mSpecies]->mBillboardScale; + mBillboardRatio = sSpeciesTable[mSpecies]->mBillboardRatio; + mTrunkAspect = sSpeciesTable[mSpecies]->mTrunkAspect; + mBranchAspect = sSpeciesTable[mSpecies]->mBranchAspect; + + // position change not caused by us, etc. make sure to rebuild. + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + + return retval; } void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time) { - if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE))) - { - return; - } - - S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; // disabled - F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor; - F32 distance = mDrawable->mDistanceWRTCamera * LLVOVolume::sDistanceFactor * (F_PI / 3.f); - F32 diameter = getScale().length(); // trees have very broken scale, but length rougtly outlines proper diameter - F32 sz = mBillboardScale * mBillboardRatio * diameter; - - for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++) - { - if (app_angle > LLVOTree::sLODAngles[j]) - { - trunk_LOD = j; - break; - } - } + if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE))) + { + return; + } + + S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; // disabled + F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor; + F32 distance = mDrawable->mDistanceWRTCamera * LLVOVolume::sDistanceFactor * (F_PI / 3.f); + F32 diameter = getScale().length(); // trees have very broken scale, but length rougtly outlines proper diameter + F32 sz = mBillboardScale * mBillboardRatio * diameter; + + for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++) + { + if (app_angle > LLVOTree::sLODAngles[j]) + { + trunk_LOD = j; + break; + } + } F32 tan_angle = (LLVOTree::sTreeFactor * 64 * sz) / distance; S32 cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); // larger value, better quality @@ -374,41 +374,41 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time) trunk_LOD = llmax(trunk_LOD, LLVolumeLODGroup::NUM_LODS - cur_detail - 1); trunk_LOD = llmin(trunk_LOD, sMAX_NUM_TREE_LOD_LEVELS); - if (mReferenceBuffer.isNull()) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - } - else if (trunk_LOD != mTrunkLOD) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - } - 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); - 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; + if (mReferenceBuffer.isNull()) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + } + else if (trunk_LOD != mTrunkLOD) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + } + 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); + 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; } void LLVOTree::render(LLAgent &agent) @@ -418,74 +418,74 @@ void LLVOTree::render(LLAgent &agent) void LLVOTree::setPixelAreaAndAngle(LLAgent &agent) { - LLVector3 center = getPositionAgent();//center of tree. - LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent(); - LLVector3 lookAt = center - viewer_pos_agent; - F32 dist = lookAt.normVec() ; - F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; - F32 radius = getScale().length()*0.5f; - F32 range = dist - radius; - - if (range < F_ALMOST_ZERO || isHUDAttachment()) // range == zero - { - mAppAngle = 180.f; - } - else - { - mAppAngle = (F32) atan2( getMaxScale(), range) * RAD_TO_DEG; - } - - F32 max_scale = mBillboardScale * getMaxScale(); - F32 area = max_scale * (max_scale*mBillboardRatio); - // Compute pixels per meter at the given range - F32 pixels_per_meter = LLViewerCamera::getInstance()->getViewHeightInPixels() / (tan(LLViewerCamera::getInstance()->getView()) * dist); - mPixelArea = pixels_per_meter * pixels_per_meter * area ; - - F32 importance = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ; - mPixelArea = LLFace::adjustPixelArea(importance, mPixelArea) ; - if (mPixelArea > LLViewerCamera::getInstance()->getScreenPixelArea()) - { - mAppAngle = 180.f; - } + LLVector3 center = getPositionAgent();//center of tree. + LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent(); + LLVector3 lookAt = center - viewer_pos_agent; + F32 dist = lookAt.normVec() ; + F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; + F32 radius = getScale().length()*0.5f; + F32 range = dist - radius; + + if (range < F_ALMOST_ZERO || isHUDAttachment()) // range == zero + { + mAppAngle = 180.f; + } + else + { + mAppAngle = (F32) atan2( getMaxScale(), range) * RAD_TO_DEG; + } + + F32 max_scale = mBillboardScale * getMaxScale(); + F32 area = max_scale * (max_scale*mBillboardRatio); + // Compute pixels per meter at the given range + F32 pixels_per_meter = LLViewerCamera::getInstance()->getViewHeightInPixels() / (tan(LLViewerCamera::getInstance()->getView()) * dist); + mPixelArea = pixels_per_meter * pixels_per_meter * area ; + + F32 importance = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ; + mPixelArea = LLFace::adjustPixelArea(importance, mPixelArea) ; + if (mPixelArea > LLViewerCamera::getInstance()->getScreenPixelArea()) + { + mAppAngle = 180.f; + } #if 0 - // mAppAngle is a bit of voodoo; - // use the one calculated LLViewerObject::setPixelAreaAndAngle above - // to avoid LOD miscalculations - mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; + // mAppAngle is a bit of voodoo; + // use the one calculated LLViewerObject::setPixelAreaAndAngle above + // to avoid LOD miscalculations + mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; #endif } void LLVOTree::updateTextures() { - if (mTreeImagep) - { - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) - { - setDebugText(llformat("%4.0f", (F32) sqrt(mPixelArea))); - } - mTreeImagep->addTextureStats(mPixelArea); - } + if (mTreeImagep) + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) + { + setDebugText(llformat("%4.0f", (F32) sqrt(mPixelArea))); + } + mTreeImagep->addTextureStats(mPixelArea); + } } LLDrawable* LLVOTree::createDrawable(LLPipeline *pipeline) { - pipeline->allocDrawable(this); - mDrawable->setLit(FALSE); + pipeline->allocDrawable(this); + mDrawable->setLit(FALSE); - mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TREE); + mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TREE); - LLDrawPoolTree *poolp = (LLDrawPoolTree*) gPipeline.getPool(LLDrawPool::POOL_TREE, mTreeImagep); + LLDrawPoolTree *poolp = (LLDrawPoolTree*) gPipeline.getPool(LLDrawPool::POOL_TREE, mTreeImagep); - // Just a placeholder for an actual object... - LLFace *facep = mDrawable->addFace(poolp, mTreeImagep); - facep->setSize(1, 3); + // Just a placeholder for an actual object... + LLFace *facep = mDrawable->addFace(poolp, mTreeImagep); + facep->setSize(1, 3); - updateRadius(); + updateRadius(); - return mDrawable; + return mDrawable; } @@ -497,744 +497,744 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) { LL_PROFILE_ZONE_SCOPED; - if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree. - { - mReferenceBuffer = NULL ; - LLFace * facep = drawable->getFace(0); - if (facep) - { - facep->setVertexBuffer(NULL); - } - return TRUE ; - } - - if (mDrawable->getFace(0) && - (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer())) - { - const F32 SRR3 = 0.577350269f; // sqrt(1/3) - const F32 SRR2 = 0.707106781f; // sqrt(1/2) - U32 i, j; - - U32 slices = MAX_SLICES; - - S32 max_indices = LEAF_INDICES; - S32 max_vertices = LEAF_VERTICES; - S32 lod; - - LLFace *face = drawable->getFace(0); - if (!face) return TRUE; - - face->mCenterAgent = getPositionAgent(); - face->mCenterLocal = face->mCenterAgent; - - for (lod = 0; lod < sMAX_NUM_TREE_LOD_LEVELS; lod++) - { - slices = sLODSlices[lod]; - sLODVertexOffset[lod] = max_vertices; - sLODVertexCount[lod] = slices*slices; - sLODIndexOffset[lod] = max_indices; - sLODIndexCount[lod] = (slices-1)*(slices-1)*6; - max_indices += sLODIndexCount[lod]; - max_vertices += sLODVertexCount[lod]; - } - - mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - if (!mReferenceBuffer->allocateBuffer(max_vertices, max_indices)) - { - LL_WARNS() << "Failed to allocate Vertex Buffer on update to " - << max_vertices << " vertices and " - << max_indices << " indices" << LL_ENDL; - mReferenceBuffer = NULL; //unref - return TRUE; - } - - LLStrider<LLVector3> vertices; - LLStrider<LLVector3> normals; + if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree. + { + mReferenceBuffer = NULL ; + LLFace * facep = drawable->getFace(0); + if (facep) + { + facep->setVertexBuffer(NULL); + } + return TRUE ; + } + + if (mDrawable->getFace(0) && + (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer())) + { + const F32 SRR3 = 0.577350269f; // sqrt(1/3) + const F32 SRR2 = 0.707106781f; // sqrt(1/2) + U32 i, j; + + U32 slices = MAX_SLICES; + + S32 max_indices = LEAF_INDICES; + S32 max_vertices = LEAF_VERTICES; + S32 lod; + + LLFace *face = drawable->getFace(0); + if (!face) return TRUE; + + face->mCenterAgent = getPositionAgent(); + face->mCenterLocal = face->mCenterAgent; + + for (lod = 0; lod < sMAX_NUM_TREE_LOD_LEVELS; lod++) + { + slices = sLODSlices[lod]; + sLODVertexOffset[lod] = max_vertices; + sLODVertexCount[lod] = slices*slices; + sLODIndexOffset[lod] = max_indices; + sLODIndexCount[lod] = (slices-1)*(slices-1)*6; + max_indices += sLODIndexCount[lod]; + max_vertices += sLODVertexCount[lod]; + } + + mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + if (!mReferenceBuffer->allocateBuffer(max_vertices, max_indices)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on update to " + << max_vertices << " vertices and " + << max_indices << " indices" << LL_ENDL; + mReferenceBuffer = NULL; //unref + return TRUE; + } + + LLStrider<LLVector3> vertices; + LLStrider<LLVector3> normals; LLStrider<LLColor4U> colors; - LLStrider<LLVector2> tex_coords; - LLStrider<U16> indicesp; + LLStrider<LLVector2> tex_coords; + LLStrider<U16> indicesp; - mReferenceBuffer->getVertexStrider(vertices); - mReferenceBuffer->getNormalStrider(normals); - mReferenceBuffer->getTexCoord0Strider(tex_coords); + mReferenceBuffer->getVertexStrider(vertices); + mReferenceBuffer->getNormalStrider(normals); + mReferenceBuffer->getTexCoord0Strider(tex_coords); mReferenceBuffer->getColorStrider(colors); - mReferenceBuffer->getIndexStrider(indicesp); - - S32 vertex_count = 0; - S32 index_count = 0; - - // First leaf - *(normals++) = LLVector3(-SRR2, -SRR2, 0.f); - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); - *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f); + mReferenceBuffer->getIndexStrider(indicesp); + + S32 vertex_count = 0; + S32 index_count = 0; + + // First leaf + *(normals++) = LLVector3(-SRR2, -SRR2, 0.f); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); + *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(SRR3, -SRR3, SRR3); - *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); - *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f); + *(normals++) = LLVector3(SRR3, -SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); + *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(-SRR3, -SRR3, SRR3); - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); - *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f); + *(normals++) = LLVector3(-SRR3, -SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); + *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(SRR2, -SRR2, 0.f); - *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); - *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f); + *(normals++) = LLVector3(SRR2, -SRR2, 0.f); + *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); + *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f); *(colors++) = LLColor4U::white; - vertex_count++; - - *(indicesp++) = 0; - index_count++; - *(indicesp++) = 1; - index_count++; - *(indicesp++) = 2; - index_count++; - - *(indicesp++) = 0; - index_count++; - *(indicesp++) = 3; - index_count++; - *(indicesp++) = 1; - index_count++; - - // Same leaf, inverse winding/normals - *(normals++) = LLVector3(-SRR2, SRR2, 0.f); - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); - *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f); + vertex_count++; + + *(indicesp++) = 0; + index_count++; + *(indicesp++) = 1; + index_count++; + *(indicesp++) = 2; + index_count++; + + *(indicesp++) = 0; + index_count++; + *(indicesp++) = 3; + index_count++; + *(indicesp++) = 1; + index_count++; + + // Same leaf, inverse winding/normals + *(normals++) = LLVector3(-SRR2, SRR2, 0.f); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); + *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(SRR3, SRR3, SRR3); - *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); - *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f); + *(normals++) = LLVector3(SRR3, SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); + *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(-SRR3, SRR3, SRR3); - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); - *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f); + *(normals++) = LLVector3(-SRR3, SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); + *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(SRR2, SRR2, 0.f); - *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); - *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f); + *(normals++) = LLVector3(SRR2, SRR2, 0.f); + *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); + *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f); *(colors++) = LLColor4U::white; - vertex_count++; - - *(indicesp++) = 4; - index_count++; - *(indicesp++) = 6; - index_count++; - *(indicesp++) = 5; - index_count++; - - *(indicesp++) = 4; - index_count++; - *(indicesp++) = 5; - index_count++; - *(indicesp++) = 7; - index_count++; - - - // next leaf - *(normals++) = LLVector3(SRR2, -SRR2, 0.f); - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); - *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f); + vertex_count++; + + *(indicesp++) = 4; + index_count++; + *(indicesp++) = 6; + index_count++; + *(indicesp++) = 5; + index_count++; + + *(indicesp++) = 4; + index_count++; + *(indicesp++) = 5; + index_count++; + *(indicesp++) = 7; + index_count++; + + + // next leaf + *(normals++) = LLVector3(SRR2, -SRR2, 0.f); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); + *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(SRR3, SRR3, SRR3); - *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); - *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f); + *(normals++) = LLVector3(SRR3, SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); + *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(SRR3, -SRR3, SRR3); - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); - *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f); + *(normals++) = LLVector3(SRR3, -SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); + *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(SRR2, SRR2, 0.f); - *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); - *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f); + *(normals++) = LLVector3(SRR2, SRR2, 0.f); + *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); + *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f); *(colors++) = LLColor4U::white; - vertex_count++; - - *(indicesp++) = 8; - index_count++; - *(indicesp++) = 9; - index_count++; - *(indicesp++) = 10; - index_count++; - - *(indicesp++) = 8; - index_count++; - *(indicesp++) = 11; - index_count++; - *(indicesp++) = 9; - index_count++; - - - // other side of same leaf - *(normals++) = LLVector3(-SRR2, -SRR2, 0.f); - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); - *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f); + vertex_count++; + + *(indicesp++) = 8; + index_count++; + *(indicesp++) = 9; + index_count++; + *(indicesp++) = 10; + index_count++; + + *(indicesp++) = 8; + index_count++; + *(indicesp++) = 11; + index_count++; + *(indicesp++) = 9; + index_count++; + + + // other side of same leaf + *(normals++) = LLVector3(-SRR2, -SRR2, 0.f); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); + *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(-SRR3, SRR3, SRR3); - *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); - *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f); + *(normals++) = LLVector3(-SRR3, SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); + *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(-SRR3, -SRR3, SRR3); - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); - *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f); + *(normals++) = LLVector3(-SRR3, -SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); + *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f); *(colors++) = LLColor4U::white; - vertex_count++; + vertex_count++; - *(normals++) = LLVector3(-SRR2, SRR2, 0.f); - *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); - *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f); + *(normals++) = LLVector3(-SRR2, SRR2, 0.f); + *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); + *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f); *(colors++) = LLColor4U::white; - vertex_count++; - - *(indicesp++) = 12; - index_count++; - *(indicesp++) = 14; - index_count++; - *(indicesp++) = 13; - index_count++; - - *(indicesp++) = 12; - index_count++; - *(indicesp++) = 13; - index_count++; - *(indicesp++) = 15; - index_count++; - - // Generate geometry for the cylinders - - // Different LOD's - - // Generate the vertices - // Generate the indices - - for (lod = 0; lod < sMAX_NUM_TREE_LOD_LEVELS; lod++) - { - slices = sLODSlices[lod]; - F32 base_radius = 0.65f; - F32 top_radius = base_radius * sSpeciesTable[mSpecies]->mTaper; - //LL_INFOS() << "Species " << ((U32) mSpecies) << ", taper = " << sSpeciesTable[mSpecies].mTaper << LL_ENDL; - //LL_INFOS() << "Droop " << mDroop << ", branchlength: " << mBranchLength << LL_ENDL; - F32 angle = 0; - F32 angle_inc = 360.f/(slices-1); - F32 z = 0.f; - F32 z_inc = 1.f; - if (slices > 3) - { - z_inc = 1.f/(slices - 3); - } - F32 radius = base_radius; - - F32 x1,y1; - F32 noise_scale = sSpeciesTable[mSpecies]->mNoiseMag; - LLVector3 nvec; - - const F32 cap_nudge = 0.1f; // Height to 'peak' the caps on top/bottom of branch - - const S32 fractal_depth = 5; - F32 nvec_scale = 1.f * sSpeciesTable[mSpecies]->mNoiseScale; - F32 nvec_scalez = 4.f * sSpeciesTable[mSpecies]->mNoiseScale; - - F32 tex_z_repeat = sSpeciesTable[mSpecies]->mRepeatTrunkZ; - - F32 start_radius; - F32 nangle = 0; - F32 height = 1.f; - F32 r0; - - for (i = 0; i < slices; i++) - { - if (i == 0) - { - z = - cap_nudge; - r0 = 0.0; - } - else if (i == (slices - 1)) - { - z = 1.f + cap_nudge;//((i - 2) * z_inc) + cap_nudge; - r0 = 0.0; - } - else - { - z = (i - 1) * z_inc; - r0 = base_radius + (top_radius - base_radius)*z; - } - - for (j = 0; j < slices; j++) - { - if (slices - 1 == j) - { - angle = 0.f; - } - else - { - angle = j*angle_inc; - } - - nangle = angle; - - x1 = cos(angle * DEG_TO_RAD); - y1 = sin(angle * DEG_TO_RAD); - LLVector2 tc; - // This isn't totally accurate. Should compute based on slope as well. - start_radius = r0 * (1.f + 1.2f*fabs(z - 0.66f*height)/height); - nvec.set( cos(nangle * DEG_TO_RAD)*start_radius*nvec_scale, - sin(nangle * DEG_TO_RAD)*start_radius*nvec_scale, - z*nvec_scalez); - // First and last slice at 0 radius (to bring in top/bottom of structure) - radius = start_radius + turbulence3((F32*)&nvec.mV, (F32)fractal_depth)*noise_scale; - - if (slices - 1 == j) - { - // Not 0.5 for slight slop factor to avoid edges on leaves - tc = LLVector2(0.490f, (1.f - z/2.f)*tex_z_repeat); - } - else - { - tc = LLVector2((angle/360.f)*0.5f, (1.f - z/2.f)*tex_z_repeat); - } - - *(vertices++) = LLVector3(x1*radius, y1*radius, z); - *(normals++) = LLVector3(x1, y1, 0.f); - *(tex_coords++) = tc; + vertex_count++; + + *(indicesp++) = 12; + index_count++; + *(indicesp++) = 14; + index_count++; + *(indicesp++) = 13; + index_count++; + + *(indicesp++) = 12; + index_count++; + *(indicesp++) = 13; + index_count++; + *(indicesp++) = 15; + index_count++; + + // Generate geometry for the cylinders + + // Different LOD's + + // Generate the vertices + // Generate the indices + + for (lod = 0; lod < sMAX_NUM_TREE_LOD_LEVELS; lod++) + { + slices = sLODSlices[lod]; + F32 base_radius = 0.65f; + F32 top_radius = base_radius * sSpeciesTable[mSpecies]->mTaper; + //LL_INFOS() << "Species " << ((U32) mSpecies) << ", taper = " << sSpeciesTable[mSpecies].mTaper << LL_ENDL; + //LL_INFOS() << "Droop " << mDroop << ", branchlength: " << mBranchLength << LL_ENDL; + F32 angle = 0; + F32 angle_inc = 360.f/(slices-1); + F32 z = 0.f; + F32 z_inc = 1.f; + if (slices > 3) + { + z_inc = 1.f/(slices - 3); + } + F32 radius = base_radius; + + F32 x1,y1; + F32 noise_scale = sSpeciesTable[mSpecies]->mNoiseMag; + LLVector3 nvec; + + const F32 cap_nudge = 0.1f; // Height to 'peak' the caps on top/bottom of branch + + const S32 fractal_depth = 5; + F32 nvec_scale = 1.f * sSpeciesTable[mSpecies]->mNoiseScale; + F32 nvec_scalez = 4.f * sSpeciesTable[mSpecies]->mNoiseScale; + + F32 tex_z_repeat = sSpeciesTable[mSpecies]->mRepeatTrunkZ; + + F32 start_radius; + F32 nangle = 0; + F32 height = 1.f; + F32 r0; + + for (i = 0; i < slices; i++) + { + if (i == 0) + { + z = - cap_nudge; + r0 = 0.0; + } + else if (i == (slices - 1)) + { + z = 1.f + cap_nudge;//((i - 2) * z_inc) + cap_nudge; + r0 = 0.0; + } + else + { + z = (i - 1) * z_inc; + r0 = base_radius + (top_radius - base_radius)*z; + } + + for (j = 0; j < slices; j++) + { + if (slices - 1 == j) + { + angle = 0.f; + } + else + { + angle = j*angle_inc; + } + + nangle = angle; + + x1 = cos(angle * DEG_TO_RAD); + y1 = sin(angle * DEG_TO_RAD); + LLVector2 tc; + // This isn't totally accurate. Should compute based on slope as well. + start_radius = r0 * (1.f + 1.2f*fabs(z - 0.66f*height)/height); + nvec.set( cos(nangle * DEG_TO_RAD)*start_radius*nvec_scale, + sin(nangle * DEG_TO_RAD)*start_radius*nvec_scale, + z*nvec_scalez); + // First and last slice at 0 radius (to bring in top/bottom of structure) + radius = start_radius + turbulence3((F32*)&nvec.mV, (F32)fractal_depth)*noise_scale; + + if (slices - 1 == j) + { + // Not 0.5 for slight slop factor to avoid edges on leaves + tc = LLVector2(0.490f, (1.f - z/2.f)*tex_z_repeat); + } + else + { + tc = LLVector2((angle/360.f)*0.5f, (1.f - z/2.f)*tex_z_repeat); + } + + *(vertices++) = LLVector3(x1*radius, y1*radius, z); + *(normals++) = LLVector3(x1, y1, 0.f); + *(tex_coords++) = tc; *(colors++) = LLColor4U::white; - vertex_count++; - } - } - - for (i = 0; i < (slices - 1); i++) - { - for (j = 0; j < (slices - 1); j++) - { - S32 x1_offset = j+1; - if ((j+1) == slices) - { - x1_offset = 0; - } - // Generate the matching quads - *(indicesp) = j + (i*slices) + sLODVertexOffset[lod]; - llassert(*(indicesp) < (U32)max_vertices); - indicesp++; - index_count++; - *(indicesp) = x1_offset + ((i+1)*slices) + sLODVertexOffset[lod]; - llassert(*(indicesp) < (U32)max_vertices); - indicesp++; - index_count++; - *(indicesp) = j + ((i+1)*slices) + sLODVertexOffset[lod]; - llassert(*(indicesp) < (U32)max_vertices); - indicesp++; - index_count++; - - *(indicesp) = j + (i*slices) + sLODVertexOffset[lod]; - llassert(*(indicesp) < (U32)max_vertices); - indicesp++; - index_count++; - *(indicesp) = x1_offset + (i*slices) + sLODVertexOffset[lod]; - llassert(*(indicesp) < (U32)max_vertices); - indicesp++; - index_count++; - *(indicesp) = x1_offset + ((i+1)*slices) + sLODVertexOffset[lod]; - llassert(*(indicesp) < (U32)max_vertices); - indicesp++; - index_count++; - } - } - slices /= 2; - } - - mReferenceBuffer->unmapBuffer(); - llassert(vertex_count == max_vertices); - llassert(index_count == max_indices); + vertex_count++; + } + } + + for (i = 0; i < (slices - 1); i++) + { + for (j = 0; j < (slices - 1); j++) + { + S32 x1_offset = j+1; + if ((j+1) == slices) + { + x1_offset = 0; + } + // Generate the matching quads + *(indicesp) = j + (i*slices) + sLODVertexOffset[lod]; + llassert(*(indicesp) < (U32)max_vertices); + indicesp++; + index_count++; + *(indicesp) = x1_offset + ((i+1)*slices) + sLODVertexOffset[lod]; + llassert(*(indicesp) < (U32)max_vertices); + indicesp++; + index_count++; + *(indicesp) = j + ((i+1)*slices) + sLODVertexOffset[lod]; + llassert(*(indicesp) < (U32)max_vertices); + indicesp++; + index_count++; + + *(indicesp) = j + (i*slices) + sLODVertexOffset[lod]; + llassert(*(indicesp) < (U32)max_vertices); + indicesp++; + index_count++; + *(indicesp) = x1_offset + (i*slices) + sLODVertexOffset[lod]; + llassert(*(indicesp) < (U32)max_vertices); + indicesp++; + index_count++; + *(indicesp) = x1_offset + ((i+1)*slices) + sLODVertexOffset[lod]; + llassert(*(indicesp) < (U32)max_vertices); + indicesp++; + index_count++; + } + } + slices /= 2; + } + + mReferenceBuffer->unmapBuffer(); + llassert(vertex_count == max_vertices); + llassert(index_count == max_indices); #ifndef SHOW_ASSERT (void)vertex_count; (void)index_count; #endif - } + } - //generate tree mesh - updateMesh(); - - return TRUE; + //generate tree mesh + updateMesh(); + + return TRUE; } void LLVOTree::updateMesh() { - LLMatrix4 matrix; - - // Translate to tree base HACK - adjustment in Z plants tree underground - const LLVector3 &pos_region = getPositionRegion(); - //gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); - LLMatrix4 trans_mat; - trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY], pos_region.mV[VZ] - 0.1f); - trans_mat *= matrix; - - // Rotate to tree position and bend for current trunk/wind - // Note that trunk stiffness controls the amount of bend at the trunk as - // opposed to the crown of the tree - // - const F32 TRUNK_STIFF = 22.f; - - LLQuaternion rot = - LLQuaternion(mTrunkBend.magVec()*TRUNK_STIFF*DEG_TO_RAD, LLVector4(mTrunkBend.mV[VX], mTrunkBend.mV[VY], 0)) * - LLQuaternion(90.f*DEG_TO_RAD, LLVector4(0,0,1)) * - getRotation(); - - LLMatrix4 rot_mat(rot); - rot_mat *= trans_mat; - - F32 radius = getScale().magVec()*0.05f; - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = - scale_mat.mMatrix[1][1] = - scale_mat.mMatrix[2][2] = radius; - - scale_mat *= rot_mat; - -// const F32 THRESH_ANGLE_FOR_BILLBOARD = 15.f; -// const F32 BLEND_RANGE_FOR_BILLBOARD = 3.f; - - F32 droop = mDroop + 25.f*(1.f - mTrunkBend.magVec()); - - S32 stop_depth = 0; - F32 alpha = 1.0; - - U32 vert_count = 0; - U32 index_count = 0; - - calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, mBranches); - - LLFace* facep = mDrawable->getFace(0); - if (!facep) return; - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - if (!buff->allocateBuffer(vert_count, index_count)) - { - LL_WARNS() << "Failed to allocate Vertex Buffer on mesh update to " - << vert_count << " vertices and " - << index_count << " indices" << LL_ENDL; - buff->allocateBuffer(1, 3); - memset((U8*)buff->getMappedData(), 0, buff->getSize()); - memset((U8*)buff->getMappedIndices(), 0, buff->getIndicesSize()); - facep->setSize(1, 3); - facep->setVertexBuffer(buff); - mReferenceBuffer->unmapBuffer(); - buff->unmapBuffer(); - return; - } - - facep->setVertexBuffer(buff); - - LLStrider<LLVector3> vertices; - LLStrider<LLVector3> normals; - LLStrider<LLVector2> tex_coords; + LLMatrix4 matrix; + + // Translate to tree base HACK - adjustment in Z plants tree underground + const LLVector3 &pos_region = getPositionRegion(); + //gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); + LLMatrix4 trans_mat; + trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY], pos_region.mV[VZ] - 0.1f); + trans_mat *= matrix; + + // Rotate to tree position and bend for current trunk/wind + // Note that trunk stiffness controls the amount of bend at the trunk as + // opposed to the crown of the tree + // + const F32 TRUNK_STIFF = 22.f; + + LLQuaternion rot = + LLQuaternion(mTrunkBend.magVec()*TRUNK_STIFF*DEG_TO_RAD, LLVector4(mTrunkBend.mV[VX], mTrunkBend.mV[VY], 0)) * + LLQuaternion(90.f*DEG_TO_RAD, LLVector4(0,0,1)) * + getRotation(); + + LLMatrix4 rot_mat(rot); + rot_mat *= trans_mat; + + F32 radius = getScale().magVec()*0.05f; + LLMatrix4 scale_mat; + scale_mat.mMatrix[0][0] = + scale_mat.mMatrix[1][1] = + scale_mat.mMatrix[2][2] = radius; + + scale_mat *= rot_mat; + +// const F32 THRESH_ANGLE_FOR_BILLBOARD = 15.f; +// const F32 BLEND_RANGE_FOR_BILLBOARD = 3.f; + + F32 droop = mDroop + 25.f*(1.f - mTrunkBend.magVec()); + + S32 stop_depth = 0; + F32 alpha = 1.0; + + U32 vert_count = 0; + U32 index_count = 0; + + calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, mBranches); + + LLFace* facep = mDrawable->getFace(0); + if (!facep) return; + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + if (!buff->allocateBuffer(vert_count, index_count)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on mesh update to " + << vert_count << " vertices and " + << index_count << " indices" << LL_ENDL; + buff->allocateBuffer(1, 3); + memset((U8*)buff->getMappedData(), 0, buff->getSize()); + memset((U8*)buff->getMappedIndices(), 0, buff->getIndicesSize()); + facep->setSize(1, 3); + facep->setVertexBuffer(buff); + mReferenceBuffer->unmapBuffer(); + buff->unmapBuffer(); + return; + } + + facep->setVertexBuffer(buff); + + LLStrider<LLVector3> vertices; + LLStrider<LLVector3> normals; + LLStrider<LLVector2> tex_coords; LLStrider<LLColor4U> colors; - LLStrider<U16> indices; - U16 idx_offset = 0; + LLStrider<U16> indices; + U16 idx_offset = 0; - buff->getVertexStrider(vertices); - buff->getNormalStrider(normals); - buff->getTexCoord0Strider(tex_coords); + buff->getVertexStrider(vertices); + buff->getNormalStrider(normals); + buff->getTexCoord0Strider(tex_coords); buff->getColorStrider(colors); - buff->getIndexStrider(indices); + buff->getIndexStrider(indices); + + genBranchPipeline(vertices, normals, tex_coords, colors, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha); - genBranchPipeline(vertices, normals, tex_coords, colors, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha); - - mReferenceBuffer->unmapBuffer(); - buff->unmapBuffer(); + mReferenceBuffer->unmapBuffer(); + buff->unmapBuffer(); } -void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices, - LLStrider<LLVector3>& normals, - LLStrider<LLVector2>& tex_coords, - LLStrider<LLColor4U>& colors, - LLStrider<U16>& indices, - U16& cur_idx, - LLMatrix4& matrix, - LLMatrix4& norm_mat, - S32 vert_start, - S32 vert_count, - S32 index_count, - S32 index_offset) +void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices, + LLStrider<LLVector3>& normals, + LLStrider<LLVector2>& tex_coords, + LLStrider<LLColor4U>& colors, + LLStrider<U16>& indices, + U16& cur_idx, + LLMatrix4& matrix, + LLMatrix4& norm_mat, + S32 vert_start, + S32 vert_count, + S32 index_count, + S32 index_offset) { - LLStrider<LLVector3> v; - LLStrider<LLVector3> n; - LLStrider<LLVector2> t; + LLStrider<LLVector3> v; + LLStrider<LLVector3> n; + LLStrider<LLVector2> t; LLStrider<LLColor4U> c; - LLStrider<U16> idx; + LLStrider<U16> idx; - mReferenceBuffer->getVertexStrider(v); - mReferenceBuffer->getNormalStrider(n); - mReferenceBuffer->getTexCoord0Strider(t); + mReferenceBuffer->getVertexStrider(v); + mReferenceBuffer->getNormalStrider(n); + mReferenceBuffer->getTexCoord0Strider(t); mReferenceBuffer->getColorStrider(c); - mReferenceBuffer->getIndexStrider(idx); - - //copy/transform vertices into mesh - check - for (S32 i = 0; i < vert_count; i++) - { - U16 index = vert_start + i; - *vertices++ = v[index] * matrix; - LLVector3 norm = n[index] * norm_mat; - norm.normalize(); - *normals++ = norm; - *tex_coords++ = t[index]; + mReferenceBuffer->getIndexStrider(idx); + + //copy/transform vertices into mesh - check + for (S32 i = 0; i < vert_count; i++) + { + U16 index = vert_start + i; + *vertices++ = v[index] * matrix; + LLVector3 norm = n[index] * norm_mat; + norm.normalize(); + *normals++ = norm; + *tex_coords++ = t[index]; *colors++ = c[index]; - } + } - //copy offset indices into mesh - check - for (S32 i = 0; i < index_count; i++) - { - U16 index = index_offset + i; - *indices++ = idx[index]-vert_start+cur_idx; - } + //copy offset indices into mesh - check + for (S32 i = 0; i < index_count; i++) + { + U16 index = index_offset + i; + *indices++ = idx[index]-vert_start+cur_idx; + } - //increment index offset - check - cur_idx += vert_count; + //increment index offset - check + cur_idx += vert_count; } - -void LLVOTree::genBranchPipeline(LLStrider<LLVector3>& vertices, - LLStrider<LLVector3>& normals, - LLStrider<LLVector2>& tex_coords, + +void LLVOTree::genBranchPipeline(LLStrider<LLVector3>& vertices, + LLStrider<LLVector3>& normals, + LLStrider<LLVector2>& tex_coords, LLStrider<LLColor4U>& colors, - LLStrider<U16>& indices, - U16& index_offset, - LLMatrix4& matrix, - S32 trunk_LOD, - S32 stop_level, - U16 depth, - U16 trunk_depth, - F32 scale, - F32 twist, - F32 droop, - F32 branches, - F32 alpha) + LLStrider<U16>& indices, + U16& index_offset, + LLMatrix4& matrix, + S32 trunk_LOD, + S32 stop_level, + U16 depth, + U16 trunk_depth, + F32 scale, + F32 twist, + F32 droop, + F32 branches, + F32 alpha) { - // - // Generates a tree mesh by recursing, generating branches and then a 'leaf' texture. - - static F32 constant_twist; - static F32 width = 0; - - F32 length = ((trunk_depth || (scale == 1.f))? mTrunkLength:mBranchLength); - F32 aspect = ((trunk_depth || (scale == 1.f))? mTrunkAspect:mBranchAspect); - - constant_twist = 360.f/branches; - - if (stop_level >= 0) - { - if (depth > stop_level) - { - { - llassert(sLODIndexCount[trunk_LOD] > 0); - width = scale * length * aspect; - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = width; - scale_mat.mMatrix[1][1] = width; - scale_mat.mMatrix[2][2] = scale*length; - scale_mat *= matrix; - - glh::matrix4f norm((F32*) scale_mat.mMatrix); - LLMatrix4 norm_mat = LLMatrix4(norm.inverse().transpose().m); - - norm_mat.invert(); - appendMesh(vertices, normals, tex_coords, colors, indices, index_offset, scale_mat, norm_mat, - sLODVertexOffset[trunk_LOD], sLODVertexCount[trunk_LOD], sLODIndexCount[trunk_LOD], sLODIndexOffset[trunk_LOD]); - } - - // Recurse to create more branches - for (S32 i=0; i < (S32)branches; i++) - { - LLMatrix4 trans_mat; - trans_mat.setTranslation(0,0,scale*length); - trans_mat *= matrix; - - LLQuaternion rot = - LLQuaternion(20.f*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)) * - LLQuaternion(droop*DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f)) * - LLQuaternion(((constant_twist + ((i%2==0)?twist:-twist))*i)*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)); - - LLMatrix4 rot_mat(rot); - rot_mat *= trans_mat; - - genBranchPipeline(vertices, normals, tex_coords, colors, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha); - } - // Recurse to continue trunk - if (trunk_depth) - { - LLMatrix4 trans_mat; - trans_mat.setTranslation(0,0,scale*length); - trans_mat *= matrix; - - LLMatrix4 rot_mat(70.5f*DEG_TO_RAD, LLVector4(0,0,1)); - rot_mat *= trans_mat; // rotate a bit around Z when ascending - genBranchPipeline(vertices, normals, tex_coords, colors, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha); - } - } - else - { - // - // Append leaves as two 90 deg crossed quads with leaf textures - // - { - LLMatrix4 scale_mat; - scale_mat.mMatrix[0][0] = - scale_mat.mMatrix[1][1] = - scale_mat.mMatrix[2][2] = scale*mLeafScale; - - scale_mat *= matrix; - - glh::matrix4f norm((F32*) scale_mat.mMatrix); - LLMatrix4 norm_mat = LLMatrix4(norm.inverse().transpose().m); - - appendMesh(vertices, normals, tex_coords, colors, indices, index_offset, scale_mat, norm_mat, 0, LEAF_VERTICES, LEAF_INDICES, 0); - } - } - } + // + // Generates a tree mesh by recursing, generating branches and then a 'leaf' texture. + + static F32 constant_twist; + static F32 width = 0; + + F32 length = ((trunk_depth || (scale == 1.f))? mTrunkLength:mBranchLength); + F32 aspect = ((trunk_depth || (scale == 1.f))? mTrunkAspect:mBranchAspect); + + constant_twist = 360.f/branches; + + if (stop_level >= 0) + { + if (depth > stop_level) + { + { + llassert(sLODIndexCount[trunk_LOD] > 0); + width = scale * length * aspect; + LLMatrix4 scale_mat; + scale_mat.mMatrix[0][0] = width; + scale_mat.mMatrix[1][1] = width; + scale_mat.mMatrix[2][2] = scale*length; + scale_mat *= matrix; + + glh::matrix4f norm((F32*) scale_mat.mMatrix); + LLMatrix4 norm_mat = LLMatrix4(norm.inverse().transpose().m); + + norm_mat.invert(); + appendMesh(vertices, normals, tex_coords, colors, indices, index_offset, scale_mat, norm_mat, + sLODVertexOffset[trunk_LOD], sLODVertexCount[trunk_LOD], sLODIndexCount[trunk_LOD], sLODIndexOffset[trunk_LOD]); + } + + // Recurse to create more branches + for (S32 i=0; i < (S32)branches; i++) + { + LLMatrix4 trans_mat; + trans_mat.setTranslation(0,0,scale*length); + trans_mat *= matrix; + + LLQuaternion rot = + LLQuaternion(20.f*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)) * + LLQuaternion(droop*DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f)) * + LLQuaternion(((constant_twist + ((i%2==0)?twist:-twist))*i)*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)); + + LLMatrix4 rot_mat(rot); + rot_mat *= trans_mat; + + genBranchPipeline(vertices, normals, tex_coords, colors, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha); + } + // Recurse to continue trunk + if (trunk_depth) + { + LLMatrix4 trans_mat; + trans_mat.setTranslation(0,0,scale*length); + trans_mat *= matrix; + + LLMatrix4 rot_mat(70.5f*DEG_TO_RAD, LLVector4(0,0,1)); + rot_mat *= trans_mat; // rotate a bit around Z when ascending + genBranchPipeline(vertices, normals, tex_coords, colors, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha); + } + } + else + { + // + // Append leaves as two 90 deg crossed quads with leaf textures + // + { + LLMatrix4 scale_mat; + scale_mat.mMatrix[0][0] = + scale_mat.mMatrix[1][1] = + scale_mat.mMatrix[2][2] = scale*mLeafScale; + + scale_mat *= matrix; + + glh::matrix4f norm((F32*) scale_mat.mMatrix); + LLMatrix4 norm_mat = LLMatrix4(norm.inverse().transpose().m); + + appendMesh(vertices, normals, tex_coords, colors, indices, index_offset, scale_mat, norm_mat, 0, LEAF_VERTICES, LEAF_INDICES, 0); + } + } + } } void LLVOTree::calcNumVerts(U32& vert_count, U32& index_count, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 branches) { - if (stop_level >= 0) - { - if (depth > stop_level) - { - index_count += sLODIndexCount[trunk_LOD]; - vert_count += sLODVertexCount[trunk_LOD]; - - // Recurse to create more branches - for (S32 i=0; i < (S32)branches; i++) - { - calcNumVerts(vert_count, index_count, trunk_LOD, stop_level, depth - 1, 0, branches); - } - - // Recurse to continue trunk - if (trunk_depth) - { - calcNumVerts(vert_count, index_count, trunk_LOD, stop_level, depth, trunk_depth-1, branches); - } - } - else - { - index_count += LEAF_INDICES; - vert_count += LEAF_VERTICES; - } - } - else - { - index_count += LEAF_INDICES; - vert_count += LEAF_VERTICES; - } + if (stop_level >= 0) + { + if (depth > stop_level) + { + index_count += sLODIndexCount[trunk_LOD]; + vert_count += sLODVertexCount[trunk_LOD]; + + // Recurse to create more branches + for (S32 i=0; i < (S32)branches; i++) + { + calcNumVerts(vert_count, index_count, trunk_LOD, stop_level, depth - 1, 0, branches); + } + + // Recurse to continue trunk + if (trunk_depth) + { + calcNumVerts(vert_count, index_count, trunk_LOD, stop_level, depth, trunk_depth-1, branches); + } + } + else + { + index_count += LEAF_INDICES; + vert_count += LEAF_VERTICES; + } + } + else + { + index_count += LEAF_INDICES; + vert_count += LEAF_VERTICES; + } } void LLVOTree::updateRadius() { - if (mDrawable.isNull()) - { - return; - } - - mDrawable->setRadius(32.0f); + if (mDrawable.isNull()) + { + return; + } + + mDrawable->setRadius(32.0f); } void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { - F32 radius = getScale().length()*0.05f; - LLVector3 center = getRenderPosition(); - - F32 sz = mBillboardScale*mBillboardRatio*radius*0.5f; - LLVector3 size(sz,sz,sz); - - center += LLVector3(0, 0, size.mV[2]) * getRotation(); - - newMin.load3((center-size).mV); - newMax.load3((center+size).mV); - LLVector4a pos; - pos.load3(center.mV); - mDrawable->setPositionGroup(pos); + F32 radius = getScale().length()*0.05f; + LLVector3 center = getRenderPosition(); + + F32 sz = mBillboardScale*mBillboardRatio*radius*0.5f; + LLVector3 size(sz,sz,sz); + + center += LLVector3(0, 0, size.mV[2]) * getRotation(); + + newMin.load3((center-size).mV); + newMax.load3((center+size).mV); + LLVector4a pos; + pos.load3(center.mV); + mDrawable->setPositionGroup(pos); } BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp, - LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) - + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) + { - if (!lineSegmentBoundingBox(start, end)) - { - return FALSE; - } - - const LLVector4a* exta = mDrawable->getSpatialExtents(); - - //VECTORIZE THIS - LLVector3 ext[2]; - ext[0].set(exta[0].getF32ptr()); - ext[1].set(exta[1].getF32ptr()); - - LLVector3 center = (ext[1]+ext[0])*0.5f; - LLVector3 size = (ext[1]-ext[0]); - - LLQuaternion quat = getRotation(); - - center -= LLVector3(0,0,size.magVec() * 0.25f)*quat; - - size.scaleVec(LLVector3(0.25f, 0.25f, 1.f)); - size.mV[0] = llmin(size.mV[0], 1.f); - size.mV[1] = llmin(size.mV[1], 1.f); - - LLVector3 pos, norm; - - LLVector3 start3(start.getF32ptr()); - LLVector3 end3(end.getF32ptr()); - - if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm)) - { - if (intersection) - { - intersection->load3(pos.mV); - } - - if (normal) - { - normal->load3(norm.mV); - } - return TRUE; - } - - return FALSE; + if (!lineSegmentBoundingBox(start, end)) + { + return FALSE; + } + + const LLVector4a* exta = mDrawable->getSpatialExtents(); + + //VECTORIZE THIS + LLVector3 ext[2]; + ext[0].set(exta[0].getF32ptr()); + ext[1].set(exta[1].getF32ptr()); + + LLVector3 center = (ext[1]+ext[0])*0.5f; + LLVector3 size = (ext[1]-ext[0]); + + LLQuaternion quat = getRotation(); + + center -= LLVector3(0,0,size.magVec() * 0.25f)*quat; + + size.scaleVec(LLVector3(0.25f, 0.25f, 1.f)); + size.mV[0] = llmin(size.mV[0], 1.f); + size.mV[1] = llmin(size.mV[1], 1.f); + + LLVector3 pos, norm; + + LLVector3 start3(start.getF32ptr()); + LLVector3 end3(end.getF32ptr()); + + if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm)) + { + if (intersection) + { + intersection->load3(pos.mV); + } + + if (normal) + { + normal->load3(norm.mV); + } + return TRUE; + } + + return FALSE; } U32 LLVOTree::getPartitionType() const -{ - return LLViewerRegion::PARTITION_TREE; +{ + return LLViewerRegion::PARTITION_TREE; } LLTreePartition::LLTreePartition(LLViewerRegion* regionp) : LLSpatialPartition(0, FALSE, regionp) { - mDrawableType = LLPipeline::RENDER_TYPE_TREE; - mPartitionType = LLViewerRegion::PARTITION_TREE; - mSlopRatio = 0.f; - mLODPeriod = 1; + mDrawableType = LLPipeline::RENDER_TYPE_TREE; + mPartitionType = LLViewerRegion::PARTITION_TREE; + mSlopRatio = 0.f; + mLODPeriod = 1; } |