diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-04-29 07:43:28 +0300 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-04-29 07:56:09 +0300 |
commit | 1b68f71348ecf3983b76b40d7940da8377f049b7 (patch) | |
tree | 2974eddaef130a067c26033d60a59fc790365b3d /indra/newview/llvograss.cpp | |
parent | af4ea94efc1999f3b19fd8d643d0331f0b77e265 (diff) |
#824 Process source files in bulk: replace tabs with spaces, convert CRLF to LF, and trim trailing whitespaces as needed
Diffstat (limited to 'indra/newview/llvograss.cpp')
-rw-r--r-- | indra/newview/llvograss.cpp | 1462 |
1 files changed, 731 insertions, 731 deletions
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index b814f15232..a92244b7da 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvograss.cpp * @brief Not a blade, but a clump of grass * * $LicenseInfo:firstyear=2001&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$ */ @@ -48,10 +48,10 @@ #include "llxmltree.h" #include "llvotree.h" -const S32 GRASS_MAX_BLADES = 32; -const F32 GRASS_BLADE_BASE = 0.25f; // Width of grass at base -const F32 GRASS_BLADE_HEIGHT = 0.5f; // meters -const F32 GRASS_DISTRIBUTION_SD = 0.15f; // empirically defined +const S32 GRASS_MAX_BLADES = 32; +const F32 GRASS_BLADE_BASE = 0.25f; // Width of grass at base +const F32 GRASS_BLADE_HEIGHT = 0.5f; // meters +const F32 GRASS_DISTRIBUTION_SD = 0.15f; // empirically defined F32 exp_x[GRASS_MAX_BLADES]; F32 exp_y[GRASS_MAX_BLADES]; @@ -60,28 +60,28 @@ F32 rot_y[GRASS_MAX_BLADES]; F32 dz_x [GRASS_MAX_BLADES]; F32 dz_y [GRASS_MAX_BLADES]; -F32 w_mod[GRASS_MAX_BLADES]; // Factor to modulate wind movement by to randomize appearance +F32 w_mod[GRASS_MAX_BLADES]; // Factor to modulate wind movement by to randomize appearance LLVOGrass::SpeciesMap LLVOGrass::sSpeciesTable; S32 LLVOGrass::sMaxGrassSpecies = 0; LLVOGrass::LLVOGrass(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) -: LLAlphaObject(id, pcode, regionp) +: LLAlphaObject(id, pcode, regionp) { - mPatch = NULL; - mLastPatchUpdateTime = 0; - mGrassVel.clearVec(); - mGrassBend.clearVec(); - mbCanSelect = TRUE; + mPatch = NULL; + mLastPatchUpdateTime = 0; + mGrassVel.clearVec(); + mGrassBend.clearVec(); + mbCanSelect = TRUE; - mBladeWindAngle = 35.f; - mBWAOverlap = 2.f; + mBladeWindAngle = 35.f; + mBWAOverlap = 2.f; - setNumTEs(1); + setNumTEs(1); - setTEColor(0, LLColor4(1.0f, 1.0f, 1.0f, 1.f)); - mNumBlades = GRASS_MAX_BLADES; + setTEColor(0, LLColor4(1.0f, 1.0f, 1.0f, 1.f)); + mNumBlades = GRASS_MAX_BLADES; } LLVOGrass::~LLVOGrass() @@ -91,805 +91,805 @@ LLVOGrass::~LLVOGrass() void LLVOGrass::updateSpecies() { - mSpecies = getAttachmentState(); - - if (!sSpeciesTable.count(mSpecies)) - { - LL_INFOS() << "Unknown grass type, substituting grass type." << LL_ENDL; - SpeciesMap::const_iterator it = sSpeciesTable.begin(); - mSpecies = (*it).first; - } - setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + mSpecies = getAttachmentState(); + + if (!sSpeciesTable.count(mSpecies)) + { + LL_INFOS() << "Unknown grass type, substituting grass type." << LL_ENDL; + SpeciesMap::const_iterator it = sSpeciesTable.begin(); + mSpecies = (*it).first; + } + setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); } void LLVOGrass::initClass() { - LLVector3 pos(0.0f, 0.0f, 0.0f); - // Create nifty list of exponential distribution 0-1 - F32 x = 0.f; - F32 y = 0.f; - F32 rot; - - std::string xml_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"grass.xml"); - - LLXmlTree grass_def_grass; - - if (!grass_def_grass.parseFile(xml_filename)) - { - LL_ERRS() << "Failed to parse grass file." << LL_ENDL; - return; - } - - LLXmlTreeNode* rootp = grass_def_grass.getRoot(); - - for (LLXmlTreeNode* grass_def = rootp->getFirstChild(); - grass_def; - grass_def = rootp->getNextChild()) - { - if (!grass_def->hasName("grass")) - { - LL_WARNS() << "Invalid grass definition node " << grass_def->getName() << LL_ENDL; - continue; - } - F32 F32_val; - LLUUID id; - - BOOL success = TRUE; - - S32 species; - static LLStdStringHandle species_id_string = LLXmlTree::addAttributeString("species_id"); - if (!grass_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; - } - - GrassSpeciesData* newGrass = new GrassSpeciesData(); - - - static LLStdStringHandle texture_id_string = LLXmlTree::addAttributeString("texture_id"); - grass_def->getFastAttributeUUID(texture_id_string, id); - newGrass->mTextureID = id; - - static LLStdStringHandle blade_sizex_string = LLXmlTree::addAttributeString("blade_size_x"); - success &= grass_def->getFastAttributeF32(blade_sizex_string, F32_val); - newGrass->mBladeSizeX = F32_val; - - static LLStdStringHandle blade_sizey_string = LLXmlTree::addAttributeString("blade_size_y"); - success &= grass_def->getFastAttributeF32(blade_sizey_string, F32_val); - newGrass->mBladeSizeY = F32_val; - - if (sSpeciesTable.count(species)) - { - LL_INFOS() << "Grass species " << species << " already defined! Duplicate discarded." << LL_ENDL; - delete newGrass; - continue; - } - else - { - sSpeciesTable[species] = newGrass; - } - - if (species >= sMaxGrassSpecies) sMaxGrassSpecies = species + 1; - - if (!success) - { - std::string name; - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - grass_def->getFastAttributeString(name_string, name); - LL_WARNS() << "Incomplete definition of grass " << name << LL_ENDL; - } - } - - BOOL have_all_grass = TRUE; - std::string err; - - for (S32 i=0;i<sMaxGrassSpecies;++i) - { - if (!sSpeciesTable.count(i)) - { - err.append(llformat(" %d",i)); - have_all_grass = FALSE; - } - } - - if (!have_all_grass) - { - LLSD args; - args["SPECIES"] = err; - LLNotificationsUtil::add("ErrorUndefinedGrasses", args); - } - - for (S32 i = 0; i < GRASS_MAX_BLADES; ++i) - { - if (1) //(i%2 == 0) Uncomment for X blading - { - F32 u = sqrt(-2.0f * log(ll_frand())); - F32 v = 2.0f * F_PI * ll_frand(); - - x = u * sin(v) * GRASS_DISTRIBUTION_SD; - y = u * cos(v) * GRASS_DISTRIBUTION_SD; - - rot = ll_frand(F_PI); - } - else - { - rot += (F_PI*0.4f + ll_frand(0.2f*F_PI)); - } - - exp_x[i] = x; - exp_y[i] = y; - rot_x[i] = sin(rot); - rot_y[i] = cos(rot); - dz_x[i] = ll_frand(GRASS_BLADE_BASE * 0.25f); - dz_y[i] = ll_frand(GRASS_BLADE_BASE * 0.25f); - w_mod[i] = 0.5f + ll_frand(); // Degree to which blade is moved by wind - - } + LLVector3 pos(0.0f, 0.0f, 0.0f); + // Create nifty list of exponential distribution 0-1 + F32 x = 0.f; + F32 y = 0.f; + F32 rot; + + std::string xml_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"grass.xml"); + + LLXmlTree grass_def_grass; + + if (!grass_def_grass.parseFile(xml_filename)) + { + LL_ERRS() << "Failed to parse grass file." << LL_ENDL; + return; + } + + LLXmlTreeNode* rootp = grass_def_grass.getRoot(); + + for (LLXmlTreeNode* grass_def = rootp->getFirstChild(); + grass_def; + grass_def = rootp->getNextChild()) + { + if (!grass_def->hasName("grass")) + { + LL_WARNS() << "Invalid grass definition node " << grass_def->getName() << LL_ENDL; + continue; + } + F32 F32_val; + LLUUID id; + + BOOL success = TRUE; + + S32 species; + static LLStdStringHandle species_id_string = LLXmlTree::addAttributeString("species_id"); + if (!grass_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; + } + + GrassSpeciesData* newGrass = new GrassSpeciesData(); + + + static LLStdStringHandle texture_id_string = LLXmlTree::addAttributeString("texture_id"); + grass_def->getFastAttributeUUID(texture_id_string, id); + newGrass->mTextureID = id; + + static LLStdStringHandle blade_sizex_string = LLXmlTree::addAttributeString("blade_size_x"); + success &= grass_def->getFastAttributeF32(blade_sizex_string, F32_val); + newGrass->mBladeSizeX = F32_val; + + static LLStdStringHandle blade_sizey_string = LLXmlTree::addAttributeString("blade_size_y"); + success &= grass_def->getFastAttributeF32(blade_sizey_string, F32_val); + newGrass->mBladeSizeY = F32_val; + + if (sSpeciesTable.count(species)) + { + LL_INFOS() << "Grass species " << species << " already defined! Duplicate discarded." << LL_ENDL; + delete newGrass; + continue; + } + else + { + sSpeciesTable[species] = newGrass; + } + + if (species >= sMaxGrassSpecies) sMaxGrassSpecies = species + 1; + + if (!success) + { + std::string name; + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); + grass_def->getFastAttributeString(name_string, name); + LL_WARNS() << "Incomplete definition of grass " << name << LL_ENDL; + } + } + + BOOL have_all_grass = TRUE; + std::string err; + + for (S32 i=0;i<sMaxGrassSpecies;++i) + { + if (!sSpeciesTable.count(i)) + { + err.append(llformat(" %d",i)); + have_all_grass = FALSE; + } + } + + if (!have_all_grass) + { + LLSD args; + args["SPECIES"] = err; + LLNotificationsUtil::add("ErrorUndefinedGrasses", args); + } + + for (S32 i = 0; i < GRASS_MAX_BLADES; ++i) + { + if (1) //(i%2 == 0) Uncomment for X blading + { + F32 u = sqrt(-2.0f * log(ll_frand())); + F32 v = 2.0f * F_PI * ll_frand(); + + x = u * sin(v) * GRASS_DISTRIBUTION_SD; + y = u * cos(v) * GRASS_DISTRIBUTION_SD; + + rot = ll_frand(F_PI); + } + else + { + rot += (F_PI*0.4f + ll_frand(0.2f*F_PI)); + } + + exp_x[i] = x; + exp_y[i] = y; + rot_x[i] = sin(rot); + rot_y[i] = cos(rot); + dz_x[i] = ll_frand(GRASS_BLADE_BASE * 0.25f); + dz_y[i] = ll_frand(GRASS_BLADE_BASE * 0.25f); + w_mod[i] = 0.5f + ll_frand(); // Degree to which blade is moved by wind + + } } void LLVOGrass::cleanupClass() { - for_each(sSpeciesTable.begin(), sSpeciesTable.end(), DeletePairedPointer()); - sSpeciesTable.clear(); + for_each(sSpeciesTable.begin(), sSpeciesTable.end(), DeletePairedPointer()); + sSpeciesTable.clear(); } U32 LLVOGrass::processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, - const EObjectUpdateType update_type, - LLDataPacker *dp) + void **user_data, + U32 block_num, + const EObjectUpdateType update_type, + LLDataPacker *dp) { - // Do base class updates... - U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); - - updateSpecies(); - - if ( (getVelocity().lengthSquared() > 0.f) - ||(getAcceleration().lengthSquared() > 0.f) - ||(getAngularVelocity().lengthSquared() > 0.f)) - { - LL_INFOS() << "ACK! Moving grass!" << LL_ENDL; - setVelocity(LLVector3::zero); - setAcceleration(LLVector3::zero); - setAngularVelocity(LLVector3::zero); - } - - if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - } - - return retval; + // Do base class updates... + U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); + + updateSpecies(); + + if ( (getVelocity().lengthSquared() > 0.f) + ||(getAcceleration().lengthSquared() > 0.f) + ||(getAngularVelocity().lengthSquared() > 0.f)) + { + LL_INFOS() << "ACK! Moving grass!" << LL_ENDL; + setVelocity(LLVector3::zero); + setAcceleration(LLVector3::zero); + setAngularVelocity(LLVector3::zero); + } + + if (mDrawable) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + } + + return retval; } BOOL LLVOGrass::isActive() const { - return TRUE; + return TRUE; } void LLVOGrass::idleUpdate(LLAgent &agent, const F64 &time) { - if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GRASS))) - { - return; - } - - if (!mDrawable) - { - // So drones work. - return; - } - if (!LLVOTree::isTreeRenderingStopped() && !mNumBlades)//restart grass rendering - { - mNumBlades = GRASS_MAX_BLADES; - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - return; - } - if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime())) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - } - - return; + if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GRASS))) + { + return; + } + + if (!mDrawable) + { + // So drones work. + return; + } + if (!LLVOTree::isTreeRenderingStopped() && !mNumBlades)//restart grass rendering + { + mNumBlades = GRASS_MAX_BLADES; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + return; + } + if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime())) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + } + + return; } void LLVOGrass::setPixelAreaAndAngle(LLAgent &agent) { - // This should be the camera's center, as soon as we move to all region-local. - LLVector3 relative_position = getPositionAgent() - gAgentCamera.getCameraPositionAgent(); - F32 range = relative_position.length(); + // This should be the camera's center, as soon as we move to all region-local. + LLVector3 relative_position = getPositionAgent() - gAgentCamera.getCameraPositionAgent(); + F32 range = relative_position.length(); - F32 max_scale = getMaxScale(); + F32 max_scale = getMaxScale(); - mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; + mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; - // Compute pixels per meter at the given range - F32 pixels_per_meter = LLViewerCamera::getInstance()->getViewHeightInPixels() / (tan(LLViewerCamera::getInstance()->getView()) * range); + // Compute pixels per meter at the given range + F32 pixels_per_meter = LLViewerCamera::getInstance()->getViewHeightInPixels() / (tan(LLViewerCamera::getInstance()->getView()) * range); - // Assume grass texture is a 5 meter by 5 meter sprite at the grass object's center - mPixelArea = (pixels_per_meter) * (pixels_per_meter) * 25.f; + // Assume grass texture is a 5 meter by 5 meter sprite at the grass object's center + mPixelArea = (pixels_per_meter) * (pixels_per_meter) * 25.f; } // BUG could speed this up by caching the relative_position and range calculations void LLVOGrass::updateTextures() { - if (getTEImage(0)) - { - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) - { - setDebugText(llformat("%4.0f", (F32) sqrt(mPixelArea))); - } - getTEImage(0)->addTextureStats(mPixelArea); - } + if (getTEImage(0)) + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) + { + setDebugText(llformat("%4.0f", (F32) sqrt(mPixelArea))); + } + getTEImage(0)->addTextureStats(mPixelArea); + } } BOOL LLVOGrass::updateLOD() { - if (mDrawable->getNumFaces() <= 0) - { - return FALSE; - } + if (mDrawable->getNumFaces() <= 0) + { + return FALSE; + } LLFace* face = mDrawable->getFace(0); - if(LLVOTree::isTreeRenderingStopped()) - { - if(mNumBlades) - { - mNumBlades = 0 ; + if(LLVOTree::isTreeRenderingStopped()) + { + if(mNumBlades) + { + mNumBlades = 0 ; face->setSize(0, 0); - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - } - return TRUE ; - } - if(!mNumBlades) - { - mNumBlades = GRASS_MAX_BLADES; - } - - F32 tan_angle = 0.f; - S32 num_blades = 0; - - tan_angle = (mScale.mV[0]*mScale.mV[1])/mDrawable->mDistanceWRTCamera; - num_blades = llmin(GRASS_MAX_BLADES, lltrunc(tan_angle * 5)); - num_blades = llmax(1, num_blades); - if (num_blades >= (mNumBlades << 1)) - { - while (mNumBlades < num_blades) - { - mNumBlades <<= 1; - } - if (face) - { - face->setSize(mNumBlades*8, mNumBlades*12); - } - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - } - else if (num_blades <= (mNumBlades >> 1)) - { - while (mNumBlades > num_blades) - { - mNumBlades >>=1; - } - - if (face) - { - face->setSize(mNumBlades*8, mNumBlades*12); - } - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - return TRUE; - } - - return FALSE; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + } + return TRUE ; + } + if(!mNumBlades) + { + mNumBlades = GRASS_MAX_BLADES; + } + + F32 tan_angle = 0.f; + S32 num_blades = 0; + + tan_angle = (mScale.mV[0]*mScale.mV[1])/mDrawable->mDistanceWRTCamera; + num_blades = llmin(GRASS_MAX_BLADES, lltrunc(tan_angle * 5)); + num_blades = llmax(1, num_blades); + if (num_blades >= (mNumBlades << 1)) + { + while (mNumBlades < num_blades) + { + mNumBlades <<= 1; + } + if (face) + { + face->setSize(mNumBlades*8, mNumBlades*12); + } + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + } + else if (num_blades <= (mNumBlades >> 1)) + { + while (mNumBlades > num_blades) + { + mNumBlades >>=1; + } + + if (face) + { + face->setSize(mNumBlades*8, mNumBlades*12); + } + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + return TRUE; + } + + return FALSE; } LLDrawable* LLVOGrass::createDrawable(LLPipeline *pipeline) { - pipeline->allocDrawable(this); - mDrawable->setRenderType(LLPipeline::RENDER_TYPE_GRASS); - - return mDrawable; + pipeline->allocDrawable(this); + mDrawable->setRenderType(LLPipeline::RENDER_TYPE_GRASS); + + return mDrawable; } static LLTrace::BlockTimerStatHandle FTM_UPDATE_GRASS("Update Grass"); BOOL LLVOGrass::updateGeometry(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_GRASS); - - dirtySpatialGroup(); - - if(!mNumBlades)//stop rendering grass - { - if (mDrawable->getNumFaces() > 0) - { - LLFace* facep = mDrawable->getFace(0); - if(facep) - { - facep->setSize(0, 0); - } - } - } - else - { - plantBlades(); - } - return TRUE; + LL_RECORD_BLOCK_TIME(FTM_UPDATE_GRASS); + + dirtySpatialGroup(); + + if(!mNumBlades)//stop rendering grass + { + if (mDrawable->getNumFaces() > 0) + { + LLFace* facep = mDrawable->getFace(0); + if(facep) + { + facep->setSize(0, 0); + } + } + } + else + { + plantBlades(); + } + return TRUE; } void LLVOGrass::plantBlades() { - // It is possible that the species of a grass is not defined - // This is bad, but not the end of the world. - if (!sSpeciesTable.count(mSpecies)) - { - LL_INFOS() << "Unknown grass species " << mSpecies << LL_ENDL; - return; - } - - if (mDrawable->getNumFaces() < 1) - { - mDrawable->setNumFaces(1, NULL, getTEImage(0)); - } - - LLFace *face = mDrawable->getFace(0); - if (face) - { - face->setTexture(getTEImage(0)); - face->setState(LLFace::GLOBAL); - face->setSize(mNumBlades * 8, mNumBlades * 12); - face->setVertexBuffer(NULL); - face->setTEOffset(0); - face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); - } - - mDepth = (face->mCenterLocal - LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis(); - mDrawable->setPosition(face->mCenterLocal); - mDrawable->movePartition(); - LLPipeline::sCompiles++; + // It is possible that the species of a grass is not defined + // This is bad, but not the end of the world. + if (!sSpeciesTable.count(mSpecies)) + { + LL_INFOS() << "Unknown grass species " << mSpecies << LL_ENDL; + return; + } + + if (mDrawable->getNumFaces() < 1) + { + mDrawable->setNumFaces(1, NULL, getTEImage(0)); + } + + LLFace *face = mDrawable->getFace(0); + if (face) + { + face->setTexture(getTEImage(0)); + face->setState(LLFace::GLOBAL); + face->setSize(mNumBlades * 8, mNumBlades * 12); + face->setVertexBuffer(NULL); + face->setTEOffset(0); + face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); + } + + mDepth = (face->mCenterLocal - LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis(); + mDrawable->setPosition(face->mCenterLocal); + mDrawable->movePartition(); + LLPipeline::sCompiles++; } void LLVOGrass::getGeometry(S32 idx, - LLStrider<LLVector4a>& verticesp, - LLStrider<LLVector3>& normalsp, - LLStrider<LLVector2>& texcoordsp, - LLStrider<LLColor4U>& colorsp, - LLStrider<LLColor4U>& emissivep, - LLStrider<U16>& indicesp) + LLStrider<LLVector4a>& verticesp, + LLStrider<LLVector3>& normalsp, + LLStrider<LLVector2>& texcoordsp, + LLStrider<LLColor4U>& colorsp, + LLStrider<LLColor4U>& emissivep, + LLStrider<U16>& indicesp) { - if(!mNumBlades)//stop rendering grass - { - return ; - } - - mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); - if (mPatch) - mLastPatchUpdateTime = mPatch->getLastUpdateTime(); - - LLVector3 position; - // Create random blades of grass with gaussian distribution - F32 x,y,xf,yf,dzx,dzy; - - LLColor4U color(255,255,255,255); - - LLFace *face = mDrawable->getFace(idx); - if (!face) - return; - - F32 width = sSpeciesTable[mSpecies]->mBladeSizeX; - F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; - - U32 index_offset = face->getGeomIndex(); - - for (S32 i = 0; i < mNumBlades; i++) - { - x = exp_x[i] * mScale.mV[VX]; - y = exp_y[i] * mScale.mV[VY]; - xf = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i]; - yf = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i]; - dzx = dz_x [i]; - dzy = dz_y [i]; - - LLVector3 v1,v2,v3; - F32 blade_height= GRASS_BLADE_HEIGHT * height * w_mod[i]; - - *texcoordsp++ = LLVector2(0, 0); - *texcoordsp++ = LLVector2(0, 0); - *texcoordsp++ = LLVector2(0, 0.98f); - *texcoordsp++ = LLVector2(0, 0.98f); - *texcoordsp++ = LLVector2(1, 0); - *texcoordsp++ = LLVector2(1, 0); - *texcoordsp++ = LLVector2(1, 0.98f); - *texcoordsp++ = LLVector2(1, 0.98f); - - position.mV[0] = mPosition.mV[VX] + x + xf; - position.mV[1] = mPosition.mV[VY] + y + yf; - position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); - v1 = position + mRegionp->getOriginAgent(); - (*verticesp++).load3(v1.mV); - (*verticesp++).load3(v1.mV); - - - position.mV[0] += dzx; - position.mV[1] += dzy; - position.mV[2] += blade_height; - v2 = position + mRegionp->getOriginAgent(); - (*verticesp++).load3(v2.mV); - (*verticesp++).load3(v2.mV); - - position.mV[0] = mPosition.mV[VX] + x - xf; - position.mV[1] = mPosition.mV[VY] + y - xf; - position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); - v3 = position + mRegionp->getOriginAgent(); - (*verticesp++).load3(v3.mV); - (*verticesp++).load3(v3.mV); - - LLVector3 normal1 = (v1-v2) % (v2-v3); - normal1.mV[VZ] = 0.75f; - normal1.normalize(); - LLVector3 normal2 = -normal1; - normal2.mV[VZ] = -normal2.mV[VZ]; - - position.mV[0] += dzx; - position.mV[1] += dzy; - position.mV[2] += blade_height; - v1 = position + mRegionp->getOriginAgent(); - (*verticesp++).load3(v1.mV); - (*verticesp++).load3(v1.mV); - - *(normalsp++) = normal1; - *(normalsp++) = normal2; - *(normalsp++) = normal1; - *(normalsp++) = normal2; - - *(normalsp++) = normal1; - *(normalsp++) = normal2; - *(normalsp++) = normal1; - *(normalsp++) = normal2; - - *(colorsp++) = color; - *(colorsp++) = color; - *(colorsp++) = color; - *(colorsp++) = color; - *(colorsp++) = color; - *(colorsp++) = color; - *(colorsp++) = color; - *(colorsp++) = color; - - *indicesp++ = index_offset + 0; - *indicesp++ = index_offset + 2; - *indicesp++ = index_offset + 4; - - *indicesp++ = index_offset + 2; - *indicesp++ = index_offset + 6; - *indicesp++ = index_offset + 4; - - *indicesp++ = index_offset + 1; - *indicesp++ = index_offset + 5; - *indicesp++ = index_offset + 3; - - *indicesp++ = index_offset + 3; - *indicesp++ = index_offset + 5; - *indicesp++ = index_offset + 7; - index_offset += 8; - } - - LLPipeline::sCompiles++; + if(!mNumBlades)//stop rendering grass + { + return ; + } + + mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); + if (mPatch) + mLastPatchUpdateTime = mPatch->getLastUpdateTime(); + + LLVector3 position; + // Create random blades of grass with gaussian distribution + F32 x,y,xf,yf,dzx,dzy; + + LLColor4U color(255,255,255,255); + + LLFace *face = mDrawable->getFace(idx); + if (!face) + return; + + F32 width = sSpeciesTable[mSpecies]->mBladeSizeX; + F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; + + U32 index_offset = face->getGeomIndex(); + + for (S32 i = 0; i < mNumBlades; i++) + { + x = exp_x[i] * mScale.mV[VX]; + y = exp_y[i] * mScale.mV[VY]; + xf = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i]; + yf = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i]; + dzx = dz_x [i]; + dzy = dz_y [i]; + + LLVector3 v1,v2,v3; + F32 blade_height= GRASS_BLADE_HEIGHT * height * w_mod[i]; + + *texcoordsp++ = LLVector2(0, 0); + *texcoordsp++ = LLVector2(0, 0); + *texcoordsp++ = LLVector2(0, 0.98f); + *texcoordsp++ = LLVector2(0, 0.98f); + *texcoordsp++ = LLVector2(1, 0); + *texcoordsp++ = LLVector2(1, 0); + *texcoordsp++ = LLVector2(1, 0.98f); + *texcoordsp++ = LLVector2(1, 0.98f); + + position.mV[0] = mPosition.mV[VX] + x + xf; + position.mV[1] = mPosition.mV[VY] + y + yf; + position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); + v1 = position + mRegionp->getOriginAgent(); + (*verticesp++).load3(v1.mV); + (*verticesp++).load3(v1.mV); + + + position.mV[0] += dzx; + position.mV[1] += dzy; + position.mV[2] += blade_height; + v2 = position + mRegionp->getOriginAgent(); + (*verticesp++).load3(v2.mV); + (*verticesp++).load3(v2.mV); + + position.mV[0] = mPosition.mV[VX] + x - xf; + position.mV[1] = mPosition.mV[VY] + y - xf; + position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); + v3 = position + mRegionp->getOriginAgent(); + (*verticesp++).load3(v3.mV); + (*verticesp++).load3(v3.mV); + + LLVector3 normal1 = (v1-v2) % (v2-v3); + normal1.mV[VZ] = 0.75f; + normal1.normalize(); + LLVector3 normal2 = -normal1; + normal2.mV[VZ] = -normal2.mV[VZ]; + + position.mV[0] += dzx; + position.mV[1] += dzy; + position.mV[2] += blade_height; + v1 = position + mRegionp->getOriginAgent(); + (*verticesp++).load3(v1.mV); + (*verticesp++).load3(v1.mV); + + *(normalsp++) = normal1; + *(normalsp++) = normal2; + *(normalsp++) = normal1; + *(normalsp++) = normal2; + + *(normalsp++) = normal1; + *(normalsp++) = normal2; + *(normalsp++) = normal1; + *(normalsp++) = normal2; + + *(colorsp++) = color; + *(colorsp++) = color; + *(colorsp++) = color; + *(colorsp++) = color; + *(colorsp++) = color; + *(colorsp++) = color; + *(colorsp++) = color; + *(colorsp++) = color; + + *indicesp++ = index_offset + 0; + *indicesp++ = index_offset + 2; + *indicesp++ = index_offset + 4; + + *indicesp++ = index_offset + 2; + *indicesp++ = index_offset + 6; + *indicesp++ = index_offset + 4; + + *indicesp++ = index_offset + 1; + *indicesp++ = index_offset + 5; + *indicesp++ = index_offset + 3; + + *indicesp++ = index_offset + 3; + *indicesp++ = index_offset + 5; + *indicesp++ = index_offset + 7; + index_offset += 8; + } + + LLPipeline::sCompiles++; } U32 LLVOGrass::getPartitionType() const { - return LLViewerRegion::PARTITION_GRASS; + return LLViewerRegion::PARTITION_GRASS; } LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp) : LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, regionp) { - mDrawableType = LLPipeline::RENDER_TYPE_GRASS; - mPartitionType = LLViewerRegion::PARTITION_GRASS; - mLODPeriod = 16; - mDepthMask = TRUE; - mSlopRatio = 0.1f; - mRenderPass = LLRenderPass::PASS_GRASS; + mDrawableType = LLPipeline::RENDER_TYPE_GRASS; + mPartitionType = LLViewerRegion::PARTITION_GRASS; + mLODPeriod = 16; + mDepthMask = TRUE; + mSlopRatio = 0.1f; + mRenderPass = LLRenderPass::PASS_GRASS; } void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) { - mFaceList.clear(); - - LLViewerCamera* camera = LLViewerCamera::getInstance(); - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); - - if (!drawablep || drawablep->isDead()) - { - continue; - } - - LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get(); - obj->mDepth = 0.f; - - U32 count = 0; - for (S32 j = 0; j < drawablep->getNumFaces(); ++j) - { - drawablep->updateFaceSize(j); - - LLFace* facep = drawablep->getFace(j); - if ( !facep || !facep->hasGeometry()) - { - continue; - } - - if ((facep->getGeomCount() + vertex_count) <= 65536) - { - count++; - facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis(); - obj->mDepth += facep->mDistance; - - mFaceList.push_back(facep); - vertex_count += facep->getGeomCount(); - index_count += facep->getIndicesCount(); - llassert(facep->getIndicesCount() < 65536); - } - else - { - facep->clearVertexBuffer(); - } - } - - obj->mDepth /= count; - } + mFaceList.clear(); + + LLViewerCamera* camera = LLViewerCamera::getInstance(); + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); + + if (!drawablep || drawablep->isDead()) + { + continue; + } + + LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get(); + obj->mDepth = 0.f; + + U32 count = 0; + for (S32 j = 0; j < drawablep->getNumFaces(); ++j) + { + drawablep->updateFaceSize(j); + + LLFace* facep = drawablep->getFace(j); + if ( !facep || !facep->hasGeometry()) + { + continue; + } + + if ((facep->getGeomCount() + vertex_count) <= 65536) + { + count++; + facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis(); + obj->mDepth += facep->mDistance; + + mFaceList.push_back(facep); + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + llassert(facep->getIndicesCount() < 65536); + } + else + { + facep->clearVertexBuffer(); + } + } + + obj->mDepth /= count; + } } void LLGrassPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; - std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); - - U32 index_count = 0; - U32 vertex_count = 0; - - group->clearDrawMap(); - - LLVertexBuffer* buffer = group->mVertexBuffer; - - LLStrider<U16> indicesp; - LLStrider<LLVector4a> verticesp; - LLStrider<LLVector3> normalsp; - LLStrider<LLVector2> texcoordsp; - LLStrider<LLColor4U> colorsp; - - buffer->getVertexStrider(verticesp); - buffer->getNormalStrider(normalsp); - buffer->getColorStrider(colorsp); - buffer->getTexCoord0Strider(texcoordsp); - buffer->getIndexStrider(indicesp); - - LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass]; - - for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) - { - LLFace* facep = *i; - LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); - facep->setGeomIndex(vertex_count); - facep->setIndicesIndex(index_count); - facep->setVertexBuffer(buffer); - facep->setPoolType(LLDrawPool::POOL_ALPHA); - - //dummy parameter (unused by this implementation) - LLStrider<LLColor4U> emissivep; - - object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, emissivep, indicesp); - - vertex_count += facep->getGeomCount(); - index_count += facep->getIndicesCount(); - - S32 idx = draw_vec.size()-1; - - bool fullbright = facep->isState(LLFace::FULLBRIGHT); - - if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && - draw_vec[idx]->mTexture == facep->getTexture() && - (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange && - //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && - draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 && - draw_vec[idx]->mFullbright == fullbright) - { - draw_vec[idx]->mCount += facep->getIndicesCount(); - draw_vec[idx]->mEnd += facep->getGeomCount(); - } - else - { - U32 start = facep->getGeomIndex(); - U32 end = start + facep->getGeomCount()-1; - U32 offset = facep->getIndicesStart(); - U32 count = facep->getIndicesCount(); - LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), - //facep->getTexture(), - buffer, object->isSelected(), fullbright); - - draw_vec.push_back(info); - //for alpha sorting - facep->setDrawInfo(info); - } - } - - buffer->unmapBuffer(); - mFaceList.clear(); + std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); + + U32 index_count = 0; + U32 vertex_count = 0; + + group->clearDrawMap(); + + LLVertexBuffer* buffer = group->mVertexBuffer; + + LLStrider<U16> indicesp; + LLStrider<LLVector4a> verticesp; + LLStrider<LLVector3> normalsp; + LLStrider<LLVector2> texcoordsp; + LLStrider<LLColor4U> colorsp; + + buffer->getVertexStrider(verticesp); + buffer->getNormalStrider(normalsp); + buffer->getColorStrider(colorsp); + buffer->getTexCoord0Strider(texcoordsp); + buffer->getIndexStrider(indicesp); + + LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass]; + + for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) + { + LLFace* facep = *i; + LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); + facep->setGeomIndex(vertex_count); + facep->setIndicesIndex(index_count); + facep->setVertexBuffer(buffer); + facep->setPoolType(LLDrawPool::POOL_ALPHA); + + //dummy parameter (unused by this implementation) + LLStrider<LLColor4U> emissivep; + + object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, emissivep, indicesp); + + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + + S32 idx = draw_vec.size()-1; + + bool fullbright = facep->isState(LLFace::FULLBRIGHT); + + if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && + draw_vec[idx]->mTexture == facep->getTexture() && + (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange && + //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && + draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 && + draw_vec[idx]->mFullbright == fullbright) + { + draw_vec[idx]->mCount += facep->getIndicesCount(); + draw_vec[idx]->mEnd += facep->getGeomCount(); + } + else + { + U32 start = facep->getGeomIndex(); + U32 end = start + facep->getGeomCount()-1; + U32 offset = facep->getIndicesStart(); + U32 count = facep->getIndicesCount(); + LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), + //facep->getTexture(), + buffer, object->isSelected(), fullbright); + + draw_vec.push_back(info); + //for alpha sorting + facep->setDrawInfo(info); + } + } + + buffer->unmapBuffer(); + mFaceList.clear(); } // virtual void LLVOGrass::updateDrawable(BOOL force_damped) { - // Force an immediate rebuild on any update - if (mDrawable.notNull()) - { - mDrawable->updateXform(TRUE); - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); - } - clearChanged(SHIFTED); + // Force an immediate rebuild on any update + if (mDrawable.notNull()) + { + mDrawable->updateXform(TRUE); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + } + clearChanged(SHIFTED); } -// virtual +// virtual BOOL LLVOGrass::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) + { - BOOL ret = FALSE; - if (!mbCanSelect || - mDrawable->isDead() || - !gPipeline.hasRenderType(mDrawable->getRenderType())) - { - return FALSE; - } - - LLVector4a dir; - dir.setSub(end, start); - - mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); - - LLVector3 position; - // Create random blades of grass with gaussian distribution - F32 x,y,xf,yf,dzx,dzy; - - LLColor4U color(255,255,255,255); - - F32 width = sSpeciesTable[mSpecies]->mBladeSizeX; - F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; - - LLVector2 tc[4]; - LLVector3 v[4]; - //LLVector3 n[4]; - - F32 closest_t = 1.f; - - for (S32 i = 0; i < mNumBlades; i++) - { - x = exp_x[i] * mScale.mV[VX]; - y = exp_y[i] * mScale.mV[VY]; - xf = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i]; - yf = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i]; - dzx = dz_x [i]; - dzy = dz_y [i]; - - LLVector3 v1,v2,v3; - F32 blade_height= GRASS_BLADE_HEIGHT * height * w_mod[i]; - - tc[0] = LLVector2(0, 0); - tc[1] = LLVector2(0, 0.98f); - tc[2] = LLVector2(1, 0); - tc[3] = LLVector2(1, 0.98f); - - position.mV[0] = mPosition.mV[VX] + x + xf; - position.mV[1] = mPosition.mV[VY] + y + yf; - position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); - v[0] = v1 = position + mRegionp->getOriginAgent(); - - - - position.mV[0] += dzx; - position.mV[1] += dzy; - position.mV[2] += blade_height; - v[1] = v2 = position + mRegionp->getOriginAgent(); - - position.mV[0] = mPosition.mV[VX] + x - xf; - position.mV[1] = mPosition.mV[VY] + y - xf; - position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); - v[2] = v3 = position + mRegionp->getOriginAgent(); - - LLVector3 normal1 = (v1-v2) % (v2-v3); - normal1.normalize(); - - position.mV[0] += dzx; - position.mV[1] += dzy; - position.mV[2] += blade_height; - v[3] = v1 = position + mRegionp->getOriginAgent(); - - F32 a,b,t; - - BOOL hit = FALSE; - - - U32 idx0 = 0,idx1 = 0,idx2 = 0; - - LLVector4a v0a,v1a,v2a,v3a; - - v0a.load3(v[0].mV); - v1a.load3(v[1].mV); - v2a.load3(v[2].mV); - v3a.load3(v[3].mV); - - - if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t)) - { - hit = TRUE; - idx0 = 0; idx1 = 1; idx2 = 2; - } - else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t)) - { - hit = TRUE; - idx0 = 1; idx1 = 3; idx2 = 2; - } - else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t)) - { - normal1 = -normal1; - hit = TRUE; - idx0 = 2; idx1 = 1; idx2 = 0; - } - else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t)) - { - normal1 = -normal1; - hit = TRUE; - idx0 = 2; idx1 = 3; idx2 = 1; - } - - if (hit) - { - if (t >= 0.f && - t <= 1.f && - t < closest_t) - { - - LLVector2 hit_tc = ((1.f - a - b) * tc[idx0] + - a * tc[idx1] + - b * tc[idx2]); - if (pick_transparent || - getTEImage(0)->getMask(hit_tc)) - { - closest_t = t; - if (intersection != NULL) - { - dir.mul(closest_t); - intersection->setAdd(start, dir); - } - - if (tex_coord != NULL) - { - *tex_coord = hit_tc; - } - - if (normal != NULL) - { - normal->load3(normal1.mV); - } - ret = TRUE; - } - } - } - } - - return ret; + BOOL ret = FALSE; + if (!mbCanSelect || + mDrawable->isDead() || + !gPipeline.hasRenderType(mDrawable->getRenderType())) + { + return FALSE; + } + + LLVector4a dir; + dir.setSub(end, start); + + mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); + + LLVector3 position; + // Create random blades of grass with gaussian distribution + F32 x,y,xf,yf,dzx,dzy; + + LLColor4U color(255,255,255,255); + + F32 width = sSpeciesTable[mSpecies]->mBladeSizeX; + F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; + + LLVector2 tc[4]; + LLVector3 v[4]; + //LLVector3 n[4]; + + F32 closest_t = 1.f; + + for (S32 i = 0; i < mNumBlades; i++) + { + x = exp_x[i] * mScale.mV[VX]; + y = exp_y[i] * mScale.mV[VY]; + xf = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i]; + yf = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i]; + dzx = dz_x [i]; + dzy = dz_y [i]; + + LLVector3 v1,v2,v3; + F32 blade_height= GRASS_BLADE_HEIGHT * height * w_mod[i]; + + tc[0] = LLVector2(0, 0); + tc[1] = LLVector2(0, 0.98f); + tc[2] = LLVector2(1, 0); + tc[3] = LLVector2(1, 0.98f); + + position.mV[0] = mPosition.mV[VX] + x + xf; + position.mV[1] = mPosition.mV[VY] + y + yf; + position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); + v[0] = v1 = position + mRegionp->getOriginAgent(); + + + + position.mV[0] += dzx; + position.mV[1] += dzy; + position.mV[2] += blade_height; + v[1] = v2 = position + mRegionp->getOriginAgent(); + + position.mV[0] = mPosition.mV[VX] + x - xf; + position.mV[1] = mPosition.mV[VY] + y - xf; + position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); + v[2] = v3 = position + mRegionp->getOriginAgent(); + + LLVector3 normal1 = (v1-v2) % (v2-v3); + normal1.normalize(); + + position.mV[0] += dzx; + position.mV[1] += dzy; + position.mV[2] += blade_height; + v[3] = v1 = position + mRegionp->getOriginAgent(); + + F32 a,b,t; + + BOOL hit = FALSE; + + + U32 idx0 = 0,idx1 = 0,idx2 = 0; + + LLVector4a v0a,v1a,v2a,v3a; + + v0a.load3(v[0].mV); + v1a.load3(v[1].mV); + v2a.load3(v[2].mV); + v3a.load3(v[3].mV); + + + if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t)) + { + hit = TRUE; + idx0 = 0; idx1 = 1; idx2 = 2; + } + else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t)) + { + hit = TRUE; + idx0 = 1; idx1 = 3; idx2 = 2; + } + else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t)) + { + normal1 = -normal1; + hit = TRUE; + idx0 = 2; idx1 = 1; idx2 = 0; + } + else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t)) + { + normal1 = -normal1; + hit = TRUE; + idx0 = 2; idx1 = 3; idx2 = 1; + } + + if (hit) + { + if (t >= 0.f && + t <= 1.f && + t < closest_t) + { + + LLVector2 hit_tc = ((1.f - a - b) * tc[idx0] + + a * tc[idx1] + + b * tc[idx2]); + if (pick_transparent || + getTEImage(0)->getMask(hit_tc)) + { + closest_t = t; + if (intersection != NULL) + { + dir.mul(closest_t); + intersection->setAdd(start, dir); + } + + if (tex_coord != NULL) + { + *tex_coord = hit_tc; + } + + if (normal != NULL) + { + normal->load3(normal1.mV); + } + ret = TRUE; + } + } + } + } + + return ret; } |