llface.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "lldrawable.h" // lldrawable needs to be included before llface
00035 #include "llface.h"
00036 #include "llviewertextureanim.h"
00037 
00038 #include "llviewercontrol.h"
00039 #include "llvolume.h"
00040 #include "m3math.h"
00041 #include "v3color.h"
00042 
00043 #include "lldrawpoolsimple.h"
00044 #include "lldrawpoolbump.h"
00045 #include "llgl.h"
00046 #include "lllightconstants.h"
00047 #include "llsky.h"
00048 #include "llviewercamera.h"
00049 #include "llviewerimagelist.h"
00050 #include "llvosky.h"
00051 #include "llvovolume.h"
00052 #include "pipeline.h"
00053 
00054 #define LL_MAX_INDICES_COUNT 1000000
00055 
00056 extern BOOL gPickFaces;
00057 
00058 BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE
00059 
00060 #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2])
00061 
00062 
00063 /*
00064 For each vertex, given:
00065         B - binormal
00066         T - tangent
00067         N - normal
00068         P - position
00069 
00070 The resulting texture coordinate <u,v> is:
00071 
00072         u = 2(B dot P)
00073         v = 2(T dot P)
00074 */
00075 void planarProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec)
00076 {       //DONE!
00077         LLVector3 binormal;
00078         float d = vd.mNormal * LLVector3(1,0,0);
00079         if (d >= 0.5f || d <= -0.5f)
00080         {
00081                 binormal = LLVector3(0,1,0);
00082                 if (vd.mNormal.mV[0] < 0)
00083                 {
00084                         binormal = -binormal;
00085                 }
00086         }
00087         else
00088         {
00089         binormal = LLVector3(1,0,0);
00090                 if (vd.mNormal.mV[1] > 0)
00091                 {
00092                         binormal = -binormal;
00093                 }
00094         }
00095         LLVector3 tangent = binormal % vd.mNormal;
00096 
00097         tc.mV[1] = -((tangent*vec)*2 - 0.5f);
00098         tc.mV[0] = 1.0f+((binormal*vec)*2 - 0.5f);
00099 }
00100 
00101 void sphericalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec)
00102 {       //BROKEN
00103         /*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f;
00104         
00105         tc.mV[1] = acosf(vd.mNormal * LLVector3(0,0,1))/6.284f;
00106         if (vd.mNormal.mV[1] > 0)
00107         {
00108                 tc.mV[1] = 1.0f-tc.mV[1];
00109         }*/
00110 }
00111 
00112 void cylindricalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec)
00113 {       //BROKEN
00114         /*LLVector3 binormal;
00115         float d = vd.mNormal * LLVector3(1,0,0);
00116         if (d >= 0.5f || d <= -0.5f)
00117         {
00118                 binormal = LLVector3(0,1,0);
00119         }
00120         else{
00121                 binormal = LLVector3(1,0,0);
00122         }
00123         LLVector3 tangent = binormal % vd.mNormal;
00124 
00125         tc.mV[1] = -((tangent*vec)*2 - 0.5f);
00126 
00127         tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/6.284f;
00128 
00129         if (vd.mNormal.mV[1] < 0)
00130         {
00131                 tc.mV[0] = 1.0f-tc.mV[0];
00132         }*/
00133 }
00134 
00136 //
00137 // LLFace implementation
00138 //
00139 
00140 void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
00141 {
00142         mLastUpdateTime = gFrameTimeSeconds;
00143         mVSize = 0.f;
00144         mPixelArea = 1024.f;
00145         mState      = GLOBAL;
00146         mDrawPoolp  = NULL;
00147         mPoolType = 0;
00148         mGeomIndex  = -1;
00149         // mCenterLocal
00150         // mCenterAgent
00151         mDistance       = 0.f;
00152 
00153         mGeomCount              = 0;
00154         mIndicesCount   = 0;
00155         mIndicesIndex   = -1;
00156         mTexture                = NULL;
00157         mTEOffset               = -1;
00158 
00159         setDrawable(drawablep);
00160         mVObjp = objp;
00161 
00162         mReferenceIndex = -1;
00163         mAlphaFade = 0.f;
00164 
00165         mFaceColor = LLColor4(1,0,0,1);
00166 
00167         mLastVertexBuffer = mVertexBuffer;
00168         mLastGeomCount = mGeomCount;
00169         mLastGeomIndex = mGeomIndex;
00170         mLastIndicesCount = mIndicesCount;
00171         mLastIndicesIndex = mIndicesIndex;
00172 }
00173 
00174 
00175 void LLFace::destroy()
00176 {
00177         mDrawablep = NULL;
00178         mVObjp = NULL;
00179 
00180         if (mDrawPoolp)
00181         {
00182                 mDrawPoolp->removeFace(this);
00183                 mDrawPoolp = NULL;
00184         }
00185 }
00186 
00187 
00188 // static
00189 void LLFace::initClass()
00190 {
00191 }
00192 
00193 void LLFace::setWorldMatrix(const LLMatrix4 &mat)
00194 {
00195         llerrs << "Faces on this drawable are not independently modifiable\n" << llendl;
00196 }
00197 
00198 void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep)
00199 {
00200         LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
00201         
00202         if (!new_pool)
00203         {
00204                 llerrs << "Setting pool to null!" << llendl;
00205         }
00206 
00207         if (new_pool != mDrawPoolp)
00208         {
00209                 // Remove from old pool
00210                 if (mDrawPoolp)
00211                 {
00212                         mDrawPoolp->removeFace(this);
00213 
00214                         if (mDrawablep)
00215                         {
00216                                 gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_ALL, TRUE);
00217                         }
00218                 }
00219                 mGeomIndex = -1;
00220 
00221                 // Add to new pool
00222                 if (new_pool)
00223                 {
00224                         new_pool->addFace(this);
00225                 }
00226                 mDrawPoolp = new_pool;
00227         }
00228         mTexture = texturep;
00229 }
00230 
00231 
00232 void LLFace::setTEOffset(const S32 te_offset)
00233 {
00234         mTEOffset = te_offset;
00235 }
00236 
00237 
00238 void LLFace::setFaceColor(const LLColor4& color)
00239 {
00240         mFaceColor = color;
00241         setState(USE_FACE_COLOR);
00242 }
00243 
00244 void LLFace::unsetFaceColor()
00245 {
00246         clearState(USE_FACE_COLOR);
00247 }
00248 
00249 void LLFace::setDrawable(LLDrawable *drawable)
00250 {
00251         mDrawablep  = drawable;
00252         mXform      = &drawable->mXform;
00253 }
00254 
00255 void LLFace::setSize(const S32 num_vertices, const S32 num_indices)
00256 {
00257         mGeomCount    = num_vertices;
00258         mIndicesCount = num_indices;
00259 }
00260 
00261 //============================================================================
00262 
00263 S32 LLFace::getGeometryAvatar(
00264                                                 LLStrider<LLVector3> &vertices,
00265                                                 LLStrider<LLVector3> &normals,
00266                                                 LLStrider<LLVector3> &binormals,
00267                                                 LLStrider<LLVector2> &tex_coords,
00268                                                 LLStrider<F32>           &vertex_weights,
00269                                                 LLStrider<LLVector4> &clothing_weights)
00270 {
00271         LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
00272 
00273         if (mVertexBuffer.notNull())
00274         {
00275                 mVertexBuffer->getVertexStrider      (vertices, mGeomIndex);
00276                 mVertexBuffer->getNormalStrider      (normals, mGeomIndex);
00277                 mVertexBuffer->getBinormalStrider    (binormals, mGeomIndex);
00278                 mVertexBuffer->getTexCoordStrider    (tex_coords, mGeomIndex);
00279                 mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex);
00280                 mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex);
00281         }
00282         else
00283         {
00284                 mGeomIndex = -1;
00285         }
00286 
00287         return mGeomIndex;
00288 }
00289 
00290 S32 LLFace::getGeometryTerrain(
00291                                                 LLStrider<LLVector3> &vertices,
00292                                                 LLStrider<LLVector3> &normals,
00293                                                 LLStrider<LLColor4U> &colors,
00294                                                 LLStrider<LLVector2> &texcoords0,
00295                                                 LLStrider<LLVector2> &texcoords1,
00296                                                 LLStrider<U32> &indicesp)
00297 {
00298         LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
00299         
00300         if (mVertexBuffer.notNull())
00301         {
00302                 mVertexBuffer->getVertexStrider(vertices, mGeomIndex);
00303                 mVertexBuffer->getNormalStrider(normals, mGeomIndex);
00304                 mVertexBuffer->getColorStrider(colors, mGeomIndex);
00305                 mVertexBuffer->getTexCoordStrider(texcoords0, mGeomIndex);
00306                 mVertexBuffer->getTexCoord2Strider(texcoords1, mGeomIndex);
00307                 mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
00308         }
00309         else
00310         {
00311                 mGeomIndex = -1;
00312         }
00313         
00314         return mGeomIndex;
00315 }
00316 
00317 S32 LLFace::getGeometry(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &normals,
00318                                             LLStrider<LLVector2> &tex_coords, LLStrider<U32> &indicesp)
00319 {
00320         LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
00321         
00322         if (mGeomCount <= 0)
00323         {
00324                 return -1;
00325         }
00326         
00327         if (mVertexBuffer.notNull())
00328         {
00329                 mVertexBuffer->getVertexStrider(vertices,   mGeomIndex);
00330                 if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))
00331                 {
00332                         mVertexBuffer->getNormalStrider(normals,    mGeomIndex);
00333                 }
00334                 if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD))
00335                 {
00336                         mVertexBuffer->getTexCoordStrider(tex_coords, mGeomIndex);
00337                 }
00338 
00339                 mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
00340         }
00341         else
00342         {
00343                 mGeomIndex = -1;
00344         }
00345         
00346         return mGeomIndex;
00347 }
00348 
00349 S32 LLFace::getGeometryColors(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &normals,
00350                                                           LLStrider<LLVector2> &tex_coords, LLStrider<LLColor4U> &colors,
00351                                                           LLStrider<U32> &indicesp)
00352 {
00353         S32 res = getGeometry(vertices, normals, tex_coords, indicesp);
00354         if (res >= 0)
00355         {
00356                 getColors(colors);
00357         }
00358         return res;
00359 }
00360 
00361 void LLFace::updateCenterAgent()
00362 {
00363         if (mDrawablep->isActive())
00364         {
00365                 mCenterAgent = mCenterLocal * getRenderMatrix();
00366         }
00367         else
00368         {
00369                 mCenterAgent = mCenterLocal;
00370         }
00371 }
00372 
00373 void LLFace::renderForSelect(U32 data_mask)
00374 {
00375         if(mGeomIndex < 0 || mDrawablep.isNull() || mVertexBuffer.isNull())
00376         {
00377                 return;
00378         }
00379 
00380         if (mVObjp->mGLName)
00381         {
00382                 S32 name = mVObjp->mGLName;
00383 
00384                 LLColor4U color((U8)(name >> 16), (U8)(name >> 8), (U8)name);
00385 #if 0 // *FIX: Postponing this fix until we have texcoord pick info...
00386                 if (mTEOffset != -1)
00387                 {
00388                         color.mV[VALPHA] = (U8)(getTextureEntry()->getColor().mV[VALPHA] * 255.f);
00389                 }
00390 #endif
00391                 glColor4ubv(color.mV);
00392 
00393                 if (!getPool())
00394                 {
00395                         switch (getPoolType())
00396                         {
00397                         case LLDrawPool::POOL_ALPHA:
00398                                 getTexture()->bind();
00399                                 break;
00400                         default:
00401                                 LLImageGL::unbindTexture(0);
00402                                 break;
00403                         }
00404                 }
00405 
00406                 mVertexBuffer->setBuffer(data_mask);
00407 #if !LL_RELEASE_FOR_DOWNLOAD
00408                 LLGLState::checkClientArrays(data_mask);
00409 #endif
00410                 U32* indicesp = (U32*) mVertexBuffer->getIndicesPointer() + mIndicesIndex;
00411 
00412                 if (gPickFaces && mTEOffset != -1)
00413                 {
00414                         // mask off high 4 bits (16 total possible faces)
00415                         color.mV[0] &= 0x0f;
00416                         color.mV[0] |= (mTEOffset & 0x0f) << 4;
00417                         glColor4ubv(color.mV);
00418                 }
00419 
00420                 if (mIndicesCount)
00421                 {
00422                         if (isState(GLOBAL))
00423                         {
00424                                 glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, indicesp); 
00425                         }
00426                         else
00427                         {
00428                                 glPushMatrix();
00429                                 glMultMatrixf((float*)getRenderMatrix().mMatrix);
00430                                 glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, indicesp); 
00431                                 glPopMatrix();
00432                         }
00433                 }
00434                 else if (mGeomCount > 0)
00435                 {
00436                         if (isState(GLOBAL))
00437                         {
00438                                 glDrawArrays(GL_TRIANGLES, mGeomIndex, mGeomCount); 
00439                         }
00440                         else
00441                         {
00442                                 glPushMatrix();
00443                                 glMultMatrixf((float*)getRenderMatrix().mMatrix);
00444                                 glDrawArrays(GL_TRIANGLES, mGeomIndex, mGeomCount); 
00445                                 glPopMatrix();
00446                         }
00447                 }
00448         }
00449 }
00450 
00451 void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color, const S32 offset, const S32 count)
00452 {
00453         if(mGeomIndex < 0 || mDrawablep.isNull() || mVertexBuffer.isNull())
00454         {
00455                 return;
00456         }
00457 
00458         if (mGeomCount > 0 && mIndicesCount > 0)
00459         {
00460                 LLGLSPipelineAlpha gls_pipeline_alpha;
00461                 glColor4fv(color.mV);
00462 
00463                 LLViewerImage::bindTexture(imagep);
00464                 if (!isState(GLOBAL))
00465                 {
00466                         // Apply the proper transform for non-global objects.
00467                         glPushMatrix();
00468                         glMultMatrixf((float*)getRenderMatrix().mMatrix);
00469                 }
00470 
00471                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00472                 glEnableClientState(GL_VERTEX_ARRAY);
00473                 glEnableClientState(GL_NORMAL_ARRAY);
00474 
00475                 mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD);
00476 #if !LL_RELEASE_FOR_DOWNLOAD
00477                 LLGLState::checkClientArrays(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD);
00478 #endif
00479                 U32* indicesp = ((U32*) mVertexBuffer->getIndicesPointer()) + mIndicesIndex;
00480 
00481                 if (count)
00482                 {
00483                         glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, indicesp + offset); 
00484                 }
00485                 else
00486                 {
00487                         glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, indicesp); 
00488                 }
00489                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00490                 glDisableClientState(GL_NORMAL_ARRAY);
00491                 
00492                 if (!isState(GLOBAL))
00493                 {
00494                         // Restore the tranform for non-global objects
00495                         glPopMatrix();
00496                 }
00497         }
00498 }
00499 
00500 void LLFace::renderSelectedUV(const S32 offset, const S32 count)
00501 {
00502 #if 0
00503         LLUUID uv_img_red_blue_id(gViewerArt.getString("uv_test1.tga"));
00504         LLUUID uv_img_green_id(gViewerArt.getString("uv_test2.tga"));
00505         LLViewerImage* red_blue_imagep = gImageList.getImage(uv_img_red_blue_id, TRUE, TRUE);
00506         LLViewerImage* green_imagep = gImageList.getImage(uv_img_green_id, TRUE, TRUE);
00507 
00508         LLGLSObjectSelect object_select;
00509         LLGLEnable blend(GL_BLEND);
00510         LLGLEnable texture(GL_TEXTURE_2D);
00511 
00512         if (!mDrawPoolp || !getIndicesCount() || getIndicesStart() < 0)
00513         {
00514                 return;
00515         }
00516         for (S32 pass = 0; pass < 2; pass++)
00517         {
00518                 static F32 bias = 0.f;
00519                 static F32 factor = -10.f;
00520                 if (mGeomCount > 0)
00521                 {
00522                         glColor4fv(LLColor4::white.mV);
00523 
00524                         if (pass == 0)
00525                         {
00526                                 LLViewerImage::bindTexture(red_blue_imagep);
00527                         }
00528                         else // pass == 1
00529                         {
00530                                 glBlendFunc(GL_ONE, GL_ONE);
00531                                 LLViewerImage::bindTexture(green_imagep);
00532                                 glMatrixMode(GL_TEXTURE);
00533                                 glPushMatrix();
00534                                 glScalef(256.f, 256.f, 1.f);
00535                         }
00536                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00537                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00538 
00539 
00540                         if (!isState(GLOBAL))
00541                         {
00542                                 // Apply the proper transform for non-global objects.
00543                                 glMatrixMode(GL_MODELVIEW);
00544                                 glPushMatrix();
00545                                 glMultMatrixf((float*)getRenderMatrix().mMatrix);
00546                         }
00547 
00548                         glEnable(GL_POLYGON_OFFSET_FILL);
00549                         glPolygonOffset(factor, bias);
00550                         if (sSafeRenderSelect)
00551                         {
00552                                 glBegin(GL_TRIANGLES);
00553                                 if (count)
00554                                 {
00555                                         for (S32 i = offset; i < offset + count; i++)
00556                                         {
00557                                                 LLVector2 tc = mDrawPoolp->getTexCoord(mDrawPoolp->getIndex(getIndicesStart() + i), 0);
00558                                                 glTexCoord2fv(tc.mV);
00559                                                 LLVector3 vertex = mDrawPoolp->getVertex(mDrawPoolp->getIndex(getIndicesStart() + i));
00560                                                 glVertex3fv(vertex.mV);
00561                                         }
00562                                 }
00563                                 else
00564                                 {
00565                                         for (U32 i = 0; i < getIndicesCount(); i++)
00566                                         {
00567                                                 LLVector2 tc = mDrawPoolp->getTexCoord(mDrawPoolp->getIndex(getIndicesStart() + i), 0);
00568                                                 glTexCoord2fv(tc.mV);
00569                                                 LLVector3 vertex = mDrawPoolp->getVertex(mDrawPoolp->getIndex(getIndicesStart() + i));
00570                                                 glVertex3fv(vertex.mV);
00571                                         }
00572                                 }
00573                                 glEnd();
00574                         }
00575                         else
00576                         {
00577                                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00578                                 glEnableClientState(GL_VERTEX_ARRAY);
00579                                 llassert(mGeomIndex >= 0);
00580                                 if (count)
00581                                 {
00582                                         if (mIndicesCount > 0)
00583                                         {
00584                                                 glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, getRawIndices() + offset); 
00585                                         }
00586                                         else
00587                                         {
00588                                                 llerrs << "Rendering non-indexed volume face!" << llendl;
00589                                                 glDrawArrays(mPrimType, mGeomIndex, mGeomCount); 
00590                                         }
00591                                 }
00592                                 else
00593                                 {
00594                                         if (mIndicesCount > 0)
00595                                         {
00596                                                 glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, getRawIndices()); 
00597                                         }
00598                                         else
00599                                         {
00600                                                 glDrawArrays(GL_TRIANGLES, mGeomIndex, mGeomCount); 
00601                                         }
00602                                 }
00603                                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00604                         }
00605 
00606                         glDisable(GL_POLYGON_OFFSET_FILL);
00607                         if (!isState(GLOBAL))
00608                         {
00609                                 // Restore the tranform for non-global objects
00610                                 glPopMatrix();
00611                         }
00612                         if (pass == 1)
00613                         {
00614                                 glMatrixMode(GL_TEXTURE);
00615                                 glPopMatrix();
00616                                 glMatrixMode(GL_MODELVIEW);
00617                                 glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
00618                         }
00619                 }
00620         }
00621         
00622         //restore blend func
00623         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00624 #endif
00625 }
00626 
00627 
00628 void LLFace::printDebugInfo() const
00629 {
00630         LLFacePool *poolp = getPool();
00631         llinfos << "Object: " << getViewerObject()->mID << llendl;
00632         if (getDrawable())
00633         {
00634                 llinfos << "Type: " << LLPrimitive::pCodeToString(getDrawable()->getVObj()->getPCode()) << llendl;
00635         }
00636         if (getTexture())
00637         {
00638                 llinfos << "Texture: " << getTexture() << " Comps: " << (U32)getTexture()->getComponents() << llendl;
00639         }
00640         else
00641         {
00642                 llinfos << "No texture: " << llendl;
00643         }
00644 
00645         llinfos << "Face: " << this << llendl;
00646         llinfos << "State: " << getState() << llendl;
00647         llinfos << "Geom Index Data:" << llendl;
00648         llinfos << "--------------------" << llendl;
00649         llinfos << "GI: " << mGeomIndex << " Count:" << mGeomCount << llendl;
00650         llinfos << "Face Index Data:" << llendl;
00651         llinfos << "--------------------" << llendl;
00652         llinfos << "II: " << mIndicesIndex << " Count:" << mIndicesCount << llendl;
00653         llinfos << llendl;
00654 
00655         poolp->printDebugInfo();
00656 
00657         S32 pool_references = 0;
00658         for (std::vector<LLFace*>::iterator iter = poolp->mReferences.begin();
00659                  iter != poolp->mReferences.end(); iter++)
00660         {
00661                 LLFace *facep = *iter;
00662                 if (facep == this)
00663                 {
00664                         llinfos << "Pool reference: " << pool_references << llendl;
00665                         pool_references++;
00666                 }
00667         }
00668 
00669         if (pool_references != 1)
00670         {
00671                 llinfos << "Incorrect number of pool references!" << llendl;
00672         }
00673 
00674 #if 0
00675         llinfos << "Indices:" << llendl;
00676         llinfos << "--------------------" << llendl;
00677 
00678         const U32 *indicesp = getRawIndices();
00679         S32 indices_count = getIndicesCount();
00680         S32 geom_start = getGeomStart();
00681 
00682         for (S32 i = 0; i < indices_count; i++)
00683         {
00684                 llinfos << i << ":" << indicesp[i] << ":" << (S32)(indicesp[i] - geom_start) << llendl;
00685         }
00686         llinfos << llendl;
00687 
00688         llinfos << "Vertices:" << llendl;
00689         llinfos << "--------------------" << llendl;
00690         for (S32 i = 0; i < mGeomCount; i++)
00691         {
00692                 llinfos << mGeomIndex + i << ":" << poolp->getVertex(mGeomIndex + i) << llendl;
00693         }
00694         llinfos << llendl;
00695 #endif
00696 }
00697 
00698 // Transform the texture coordinates for this face.
00699 static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 offT, F32 magS, F32 magT)
00700 {
00701         // New, good way
00702         F32 s = tex_coord.mV[0];
00703         F32 t = tex_coord.mV[1];
00704 
00705         // Texture transforms are done about the center of the face.
00706         s -= 0.5; 
00707         t -= 0.5;
00708 
00709         // Handle rotation
00710         F32 temp = s;
00711         s  = s     * cosAng + t * sinAng;
00712         t  = -temp * sinAng + t * cosAng;
00713 
00714         // Then scale
00715         s *= magS;
00716         t *= magT;
00717 
00718         // Then offset
00719         s += offS + 0.5f; 
00720         t += offT + 0.5f;
00721 
00722         tex_coord.mV[0] = s;
00723         tex_coord.mV[1] = t;
00724 }
00725 
00726 
00727 BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
00728                                                                 const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, BOOL global_volume)
00729 {
00730         LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
00731 
00732         //get bounding box
00733         if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
00734         {
00735                 if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
00736                 { //vertex buffer no longer valid
00737                         mVertexBuffer = NULL;
00738                         mLastVertexBuffer = NULL;
00739                 }
00740 
00741                 LLVector3 min,max;
00742         
00743                 if (f >= volume.getNumVolumeFaces())
00744                 {
00745                         min = LLVector3(-1,-1,-1);
00746                         max = LLVector3(1,1,1);
00747                 }
00748                 else
00749                 {
00750                         const LLVolumeFace &face = volume.getVolumeFace(f);
00751                         min = face.mExtents[0];
00752                         max = face.mExtents[1];
00753                 }
00754 
00755                 //min, max are in volume space, convert to drawable render space
00756                 LLVector3 center = ((min + max) * 0.5f)*mat_vert;
00757                 LLVector3 size = ((max-min) * 0.5f);
00758                 if (!global_volume)
00759                 {
00760                         size.scaleVec(mDrawablep->getVObj()->getScale());
00761                 }
00762 
00763                 LLMatrix3 mat = mat_normal;
00764                 LLVector3 x = mat.getFwdRow();
00765                 LLVector3 y = mat.getLeftRow();
00766                 LLVector3 z = mat.getUpRow();
00767                 x.normVec();
00768                 y.normVec();
00769                 z.normVec();
00770 
00771                 mat.setRows(x,y,z);
00772 
00773                 LLQuaternion rotation = LLQuaternion(mat);
00774                 
00775                 LLVector3 v[4];
00776                 //get 4 corners of bounding box
00777                 v[0] = (size * rotation);
00778                 v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation);
00779                 v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation);
00780                 v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation);
00781 
00782                 LLVector3& newMin = mExtents[0];
00783                 LLVector3& newMax = mExtents[1];
00784                 
00785                 newMin = newMax = center;
00786                 
00787                 for (U32 i = 0; i < 4; i++)
00788                 {
00789                         for (U32 j = 0; j < 3; j++)
00790                         {
00791                                 F32 delta = fabsf(v[i].mV[j]);
00792                                 F32 min = center.mV[j] - delta;
00793                                 F32 max = center.mV[j] + delta;
00794                                 
00795                                 if (min < newMin.mV[j])
00796                                 {
00797                                         newMin.mV[j] = min;
00798                                 }
00799                                 
00800                                 if (max > newMax.mV[j])
00801                                 {
00802                                         newMax.mV[j] = max;
00803                                 }
00804                         }
00805                 }
00806 
00807                 mCenterLocal = (newMin+newMax)*0.5f;
00808                 updateCenterAgent();
00809         }
00810 
00811         return TRUE;
00812 }
00813 
00814 
00815 BOOL LLFace::getGeometryVolume(const LLVolume& volume,
00816                                                            S32 f,
00817                                                                 LLStrider<LLVector3>& vertices, 
00818                                                                 LLStrider<LLVector3>& normals,
00819                                                                 LLStrider<LLVector2>& tex_coords,
00820                                                                 LLStrider<LLVector2>& tex_coords2,
00821                                                                 LLStrider<LLColor4U>& colors,
00822                                                                 LLStrider<U32>& indicesp,
00823                                                                 const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,
00824                                                                 U32& index_offset)
00825 {
00826         const LLVolumeFace &vf = volume.getVolumeFace(f);
00827         S32 num_vertices = (S32)vf.mVertices.size();
00828         S32 num_indices = (S32)vf.mIndices.size();
00829         
00830         LLStrider<LLVector3> old_verts;
00831         LLStrider<LLVector2> old_texcoords;
00832         LLStrider<LLVector2> old_texcoords2;
00833         LLStrider<LLVector3> old_normals;
00834         LLStrider<LLColor4U> old_colors;
00835 
00836         BOOL full_rebuild = mDrawablep->isState(LLDrawable::REBUILD_VOLUME);
00837         BOOL moved = TRUE;
00838 
00839         BOOL global_volume = mDrawablep->getVOVolume()->isVolumeGlobal();
00840         LLVector3 scale;
00841         if (global_volume)
00842         {
00843                 scale.setVec(1,1,1);
00844         }
00845         else
00846         {
00847                 scale = mVObjp->getScale();
00848         }
00849 
00850         if (!full_rebuild)
00851         {   
00852                 if (mLastVertexBuffer == mVertexBuffer && 
00853                         !mVertexBuffer->isEmpty())
00854                 {       //this face really doesn't need to be regenerated, try real hard not to do so
00855                         if (mLastGeomCount == mGeomCount &&
00856                                 mLastGeomIndex == mGeomIndex &&
00857                                 mLastIndicesCount == mIndicesCount &&
00858                                 mLastIndicesIndex == mIndicesIndex)
00859                         { //data is in same location in vertex buffer
00860                                 moved = FALSE;
00861                         }
00862 
00863                         if (!moved && !mDrawablep->isState(LLDrawable::REBUILD_ALL))
00864                         { //nothing needs to be done
00865                                 vertices += mGeomCount;
00866                                 normals += mGeomCount;
00867                                 tex_coords += mGeomCount;
00868                                 colors += mGeomCount;
00869                                 tex_coords2 += mGeomCount;
00870                                 index_offset += mGeomCount;
00871                                 indicesp += mIndicesCount;
00872                                 return FALSE;
00873                         }
00874 
00875                         if (mLastGeomCount == mGeomCount)
00876                         {
00877                                 if (mLastGeomIndex >= mGeomIndex && 
00878                                         mLastGeomIndex + mGeomCount+1 < mVertexBuffer->getNumVerts())
00879                                 {
00880                                         //copy from further down the buffer
00881                                         mVertexBuffer->getVertexStrider(old_verts, mLastGeomIndex);
00882                                         mVertexBuffer->getTexCoordStrider(old_texcoords, mLastGeomIndex);
00883                                         mVertexBuffer->getTexCoord2Strider(old_texcoords2, mLastGeomIndex);
00884                                         mVertexBuffer->getNormalStrider(old_normals, mLastGeomIndex);
00885                                         mVertexBuffer->getColorStrider(old_colors, mLastGeomIndex);
00886 
00887                                         if (!mDrawablep->isState(LLDrawable::REBUILD_ALL))
00888                                         {
00889                                                 //quick copy
00890                                                 for (S32 i = 0; i < mGeomCount; i++)
00891                                                 {
00892                                                         *vertices++ = *old_verts++;
00893                                                         *tex_coords++ = *old_texcoords++;
00894                                                         *tex_coords2++ = *old_texcoords2++;
00895                                                         *colors++ = *old_colors++;
00896                                                         *normals++ = *old_normals++;
00897                                                 }
00898 
00899                                                 for (U32 i = 0; i < mIndicesCount; i++)
00900                                                 {
00901                                                         *indicesp++ = vf.mIndices[i] + index_offset;
00902                                                 }
00903 
00904                                                 index_offset += mGeomCount;
00905                                                 mLastGeomIndex = mGeomIndex;
00906                                                 mLastIndicesCount = mIndicesCount;
00907                                                 mLastIndicesIndex = mIndicesIndex;
00908 
00909                                                 return TRUE;
00910                                         }
00911                                 }
00912                                 else
00913                                 {
00914                                         full_rebuild = TRUE;
00915                                 }
00916                         }
00917                         else
00918                         {
00919                                 full_rebuild = TRUE;
00920                         }
00921                 }
00922                 else
00923                 {
00924                         full_rebuild = TRUE;
00925                 }
00926         }
00927         else
00928         {
00929                 mLastUpdateTime = gFrameTimeSeconds;
00930         }
00931 
00932 
00933         BOOL rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION);
00934         BOOL rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR);
00935         BOOL rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
00936 
00937         F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
00938         
00939         BOOL is_static = mDrawablep->isStatic();
00940         BOOL is_global = is_static;
00941 
00942         if (index_offset == (U32) -1)
00943         {
00944                 return TRUE;
00945         }
00946         
00947         LLVector3 center_sum(0.f, 0.f, 0.f);
00948         
00949         if (is_global)
00950         {
00951                 setState(GLOBAL);
00952         }
00953         else
00954         {
00955                 clearState(GLOBAL);
00956         }
00957 
00958         LLVector2 tmin, tmax;
00959         
00960         const LLTextureEntry *tep = mVObjp->getTE(f);
00961         U8  bump_code = tep ? tep->getBumpmap() : 0;
00962 
00963         if (rebuild_tcoord)
00964         {
00965                 if (tep)
00966                 {
00967                         r  = tep->getRotation();
00968                         os = tep->mOffsetS;
00969                         ot = tep->mOffsetT;
00970                         ms = tep->mScaleS;
00971                         mt = tep->mScaleT;
00972                         cos_ang = cos(r);
00973                         sin_ang = sin(r);
00974                 }
00975                 else
00976                 {
00977                         cos_ang = 1.0f;
00978                         sin_ang = 0.0f;
00979                         os = 0.0f;
00980                         ot = 0.0f;
00981                         ms = 1.0f;
00982                         mt = 1.0f;
00983                 }
00984         }
00985 
00986         if (isState(TEXTURE_ANIM))
00987         {
00988                 LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
00989                 U8 mode = vobj->mTexAnimMode;
00990                 if (!mode)
00991                 {
00992                         clearState(TEXTURE_ANIM);
00993                 }
00994                 else
00995                 {
00996                         os = ot = 0.f;
00997                         r = 0.f;
00998                         cos_ang = 1.f;
00999                         sin_ang = 0.f;
01000                         ms = mt = 1.f;
01001                 }
01002         }
01003 
01004         LLColor4U color = tep->getColor();
01005 
01006         if (rebuild_color)
01007         {
01008                 GLfloat alpha[4] =
01009                 {
01010                         0.00f,
01011                         0.25f,
01012                         0.5f,
01013                         0.75f
01014                 };
01015 
01016                 if (gPipeline.getPoolTypeFromTE(tep, getTexture()) == LLDrawPool::POOL_BUMP)
01017                 {
01018                         color.mV[3] = U8 (alpha[tep->getShiny()] * 255);
01019                 }
01020         }
01021 
01022     // INDICES
01023         if (full_rebuild || moved)
01024         {
01025                 for (S32 i = 0; i < num_indices; i++)
01026                 {
01027                         *indicesp++ = vf.mIndices[i] + index_offset;
01028                 }
01029         }
01030         else
01031         {
01032                 indicesp += num_indices;
01033         }
01034         
01035         //bump setup
01036         LLVector3 binormal_dir( -sin_ang, cos_ang, 0 );
01037         LLVector3 bump_s_primary_light_ray;
01038         LLVector3 bump_t_primary_light_ray;
01039         
01040         if (bump_code)
01041         {
01042                 F32 offset_multiple; 
01043                 switch( bump_code )
01044                 {
01045                         case BE_NO_BUMP:
01046                         offset_multiple = 0.f;
01047                         break;
01048                         case BE_BRIGHTNESS:
01049                         case BE_DARKNESS:
01050                         if( mTexture.notNull() && mTexture->getHasGLTexture())
01051                         {
01052                                 // Offset by approximately one texel
01053                                 S32 cur_discard = mTexture->getDiscardLevel();
01054                                 S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
01055                                 max_size <<= cur_discard;
01056                                 const F32 ARTIFICIAL_OFFSET = 2.f;
01057                                 offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
01058                         }
01059                         else
01060                         {
01061                                 offset_multiple = 1.f/256;
01062                         }
01063                         break;
01064 
01065                         default:  // Standard bumpmap textures.  Assumed to be 256x256
01066                         offset_multiple = 1.f / 256;
01067                         break;
01068                 }
01069 
01070                 F32 s_scale = 1.f;
01071                 F32 t_scale = 1.f;
01072                 if( tep )
01073                 {
01074                         tep->getScale( &s_scale, &t_scale );
01075                 }
01076                 LLVector3   sun_ray  = gSky.getSunDirection();
01077                 LLVector3   moon_ray = gSky.getMoonDirection();
01078                 LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
01079                 bump_s_primary_light_ray = offset_multiple * s_scale * primary_light_ray;
01080                 bump_t_primary_light_ray = offset_multiple * t_scale * primary_light_ray;
01081         }
01082                 
01083         U8 texgen = getTextureEntry()->getTexGen();
01084 
01085         for (S32 i = 0; i < num_vertices; i++)
01086         {
01087                 if (rebuild_tcoord)
01088                 {
01089                         LLVector2 tc = vf.mVertices[i].mTexCoord;
01090                 
01091                         if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
01092                         {
01093                                 LLVector3 vec = vf.mVertices[i].mPosition; 
01094                         
01095                                 vec.scaleVec(scale);
01096 
01097                                 switch (texgen)
01098                                 {
01099                                         case LLTextureEntry::TEX_GEN_PLANAR:
01100                                                 planarProjection(tc, vf.mVertices[i], vf.mCenter, vec);
01101                                                 break;
01102                                         case LLTextureEntry::TEX_GEN_SPHERICAL:
01103                                                 sphericalProjection(tc, vf.mVertices[i], vf.mCenter, vec);
01104                                                 break;
01105                                         case LLTextureEntry::TEX_GEN_CYLINDRICAL:
01106                                                 cylindricalProjection(tc, vf.mVertices[i], vf.mCenter, vec);
01107                                                 break;
01108                                         default:
01109                                                 break;
01110                                 }               
01111                         }
01112 
01113                         xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
01114                         *tex_coords++ = tc;
01115                 
01116                         if (bump_code)
01117                         {
01118                                 LLVector3 tangent = vf.mVertices[i].mBinormal % vf.mVertices[i].mNormal;
01119                                 LLMatrix3 tangent_to_object;
01120                                 tangent_to_object.setRows(tangent, vf.mVertices[i].mBinormal, vf.mVertices[i].mNormal);
01121                                 LLVector3 binormal = binormal_dir * tangent_to_object;
01122 
01123                                 binormal = binormal * mat_normal;
01124                                 binormal.normVec();
01125 
01126                                 tc += LLVector2( bump_s_primary_light_ray * tangent, bump_t_primary_light_ray * binormal );
01127                                 *tex_coords2++ = tc;
01128                         }       
01129                 }
01130                 else if (moved)
01131                 {
01132                         *tex_coords++ = *old_texcoords++;
01133                         if (bump_code)
01134                         {
01135                                 *tex_coords2++ = *old_texcoords2++;
01136                         }
01137                 }
01138                         
01139                 if (rebuild_pos)
01140                 {
01141                         *vertices++ = vf.mVertices[i].mPosition * mat_vert;
01142 
01143                         LLVector3 normal = vf.mVertices[i].mNormal * mat_normal;
01144                         normal.normVec();
01145                         
01146                         *normals++ = normal;
01147                 }
01148                 else if (moved)
01149                 {
01150                         *normals++ = *old_normals++;
01151                         *vertices++ = *old_verts++;
01152                 }
01153 
01154                 if (rebuild_color)
01155                 {
01156                         *colors++ = color;              
01157                 }
01158                 else if (moved)
01159                 {
01160                         *colors++ = *old_colors++;
01161                 }
01162         }
01163 
01164         if (!rebuild_pos && !moved)
01165         {
01166                 vertices += num_vertices;
01167         }
01168 
01169         if (!rebuild_tcoord && !moved)
01170         {
01171                 tex_coords2 += num_vertices;
01172                 tex_coords += num_vertices;
01173         }
01174         else if (!bump_code)
01175         {
01176                 tex_coords2 += num_vertices;
01177         }
01178 
01179         if (!rebuild_color && !moved)
01180         {
01181                 colors += num_vertices;
01182         }
01183 
01184         if (rebuild_tcoord)
01185         {
01186                 mTexExtents[0].setVec(0,0);
01187                 mTexExtents[1].setVec(1,1);
01188                 xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt);
01189                 xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);                
01190         }
01191 
01192         index_offset += num_vertices;
01193 
01194         mLastVertexBuffer = mVertexBuffer;
01195         mLastGeomCount = mGeomCount;
01196         mLastGeomIndex = mGeomIndex;
01197         mLastIndicesCount = mIndicesCount;
01198         mLastIndicesIndex = mIndicesIndex;
01199 
01200         return TRUE;
01201 }
01202 
01203 #if 0
01204 BOOL LLFace::genLighting(const LLVolume* volume, const LLDrawable* drawablep, S32 fstart, S32 fend, 
01205                                                  const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, BOOL do_lighting)
01206 {
01207         if (drawablep->isLight())
01208         {
01209                 do_lighting = FALSE;
01210         }
01211         
01212         if (!((mDrawPoolp->mDataMaskIL) & LLDrawPool::DATA_COLORS_MASK))
01213         {
01214                 return FALSE;
01215         }
01216         if (mGeomIndex < 0)
01217         {
01218                 return FALSE; // no geometry
01219         }
01220         LLStrider<LLColor4U> colorsp;
01221         S32 idx = getColors(colorsp);
01222         if (idx < 0)
01223         {
01224                 return FALSE;
01225         }
01226         
01227         for (S32 vol_face = fstart; vol_face <= fend; vol_face++)
01228         {
01229                 const LLVolumeFace &vf = volume->getVolumeFace(vol_face);
01230                 S32 num_vertices = (S32)vf.mVertices.size();
01231 
01232                 if (isState(FULLBRIGHT) || !do_lighting)
01233                 {
01234                         for (S32 i = 0; i < num_vertices; i++)
01235                         {
01236                                 (*colorsp++).setToBlack();
01237                         }
01238                 }
01239                 else
01240                 {
01241                         for (S32 i = 0; i < num_vertices; i++)
01242                         {
01243                                 LLVector3 vertex = vf.mVertices[i].mPosition * mat_vert;
01244                                 LLVector3 normal = vf.mVertices[i].mNormal * mat_normal;
01245                                 normal.normVec();
01246                 
01247                                 LLColor4 color;
01248                                 for (LLDrawable::drawable_set_t::const_iterator iter = drawablep->mLightSet.begin();
01249                                          iter != drawablep->mLightSet.end(); ++iter)
01250                                 {
01251                                         LLDrawable* light_drawable = *iter;
01252                                         LLVOVolume* light = light_drawable->getVOVolume();
01253                                         if (!light)
01254                                         {
01255                                                 continue;
01256                                         }
01257                                         LLColor4 light_color;
01258                                         light->calcLightAtPoint(vertex, normal, light_color);
01259                                         color += light_color;
01260                                 }
01261 
01262                                 color.mV[3] = 1.0f;
01263 
01264                                 (*colorsp++).setVecScaleClamp(color);
01265                         }
01266                 }
01267         }
01268         return TRUE;
01269 }
01270 
01271 BOOL LLFace::genShadows(const LLVolume* volume, const LLDrawable* drawablep, S32 fstart, S32 fend, 
01272                                                  const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, BOOL use_shadow_factor)
01273 {
01274         if (drawablep->isLight())
01275         {
01276                 return FALSE;
01277         }
01278         
01279         if (!((mDrawPoolp->mDataMaskIL) & LLDrawPool::DATA_COLORS_MASK))
01280         {
01281                 return FALSE;
01282         }
01283         if (mGeomIndex < 0)
01284         {
01285                 return FALSE; // no geometry
01286         }
01287         LLStrider<LLColor4U> colorsp;
01288         S32 idx = getColors(colorsp);
01289         if (idx < 0)
01290         {
01291                 return FALSE;
01292         }
01293         
01294         for (S32 vol_face = fstart; vol_face <= fend; vol_face++)
01295         {
01296                 const LLVolumeFace &vf = volume->getVolumeFace(vol_face);
01297                 S32 num_vertices = (S32)vf.mVertices.size();
01298 
01299                 if (isState(FULLBRIGHT))
01300                 {
01301                         continue;
01302                 }
01303 
01304                 for (S32 i = 0; i < num_vertices; i++)
01305                 {
01306                         LLVector3 vertex = vf.mVertices[i].mPosition * mat_vert;
01307                         LLVector3 normal = vf.mVertices[i].mNormal * mat_normal;
01308                         normal.normVec();
01309                                 
01310                         U8 shadow;
01311 
01312                         if (use_shadow_factor)
01313                         {
01314                                 shadow = (U8) (drawablep->getSunShadowFactor() * 255);
01315                         }
01316                         else
01317                         {
01318                                 shadow = 255;
01319                         }
01320                 
01321                         (*colorsp++).mV[3] = shadow;    
01322                 }
01323         }
01324         return TRUE;
01325 }
01326 #endif
01327 
01328 BOOL LLFace::verify(const U32* indices_array) const
01329 {
01330         BOOL ok = TRUE;
01331         // First, check whether the face data fits within the pool's range.
01332         if ((mGeomIndex < 0) || (mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts())
01333         {
01334                 ok = FALSE;
01335                 llinfos << "Face not within pool range!" << llendl;
01336         }
01337 
01338         S32 indices_count = (S32)getIndicesCount();
01339         
01340         if (!indices_count)
01341         {
01342                 return TRUE;
01343         }
01344         
01345         if (indices_count > LL_MAX_INDICES_COUNT)
01346         {
01347                 ok = FALSE;
01348                 llinfos << "Face has bogus indices count" << llendl;
01349         }
01350         
01351 #if 0
01352         S32 geom_start = getGeomStart();
01353         S32 geom_count = mGeomCount;
01354 
01355         const U32 *indicesp = indices_array ? indices_array + mIndicesIndex : getRawIndices();
01356 
01357         for (S32 i = 0; i < indices_count; i++)
01358         {
01359                 S32 delta = indicesp[i] - geom_start;
01360                 if (0 > delta)
01361                 {
01362                         llwarns << "Face index too low!" << llendl;
01363                         llinfos << "i:" << i << " Index:" << indicesp[i] << " GStart: " << geom_start << llendl;
01364                         ok = FALSE;
01365                 }
01366                 else if (delta >= geom_count)
01367                 {
01368                         llwarns << "Face index too high!" << llendl;
01369                         llinfos << "i:" << i << " Index:" << indicesp[i] << " GEnd: " << geom_start + geom_count << llendl;
01370                         ok = FALSE;
01371                 }
01372         }
01373 #endif
01374 
01375         if (!ok)
01376         {
01377                 printDebugInfo();
01378         }
01379         return ok;
01380 }
01381 
01382 
01383 void LLFace::setViewerObject(LLViewerObject* objp)
01384 {
01385         mVObjp = objp;
01386 }
01387 
01388 void LLFace::enableLights() const
01389 {
01390         if (isState(FULLBRIGHT|HUD_RENDER))
01391         {
01392                 gPipeline.enableLightsFullbright(LLColor4::white);
01393         }
01394         else if (mDrawablep->isState(LLDrawable::LIGHTING_BUILT))
01395         {
01396                 gPipeline.enableLightsStatic(1.f);
01397         }
01398         else
01399         {
01400                 gPipeline.enableLightsDynamic(1.f);
01401         }
01402         if (isState(LIGHT))
01403         {
01404                 const LLVOVolume* vovolume = (const LLVOVolume*)mDrawablep->getVObj();
01405                 gPipeline.setAmbient(vovolume->getLightColor());
01406         }
01407 }
01408 
01409 const LLColor4& LLFace::getRenderColor() const
01410 {
01411         if (isState(USE_FACE_COLOR))
01412         {
01413                   return mFaceColor; // Face Color
01414         }
01415         else
01416         {
01417                 const LLTextureEntry* tep = getTextureEntry();
01418                 return (tep ? tep->getColor() : LLColor4::white);
01419         }
01420 }
01421         
01422 void LLFace::renderSetColor() const
01423 {
01424         if (!LLFacePool::LLOverrideFaceColor::sOverrideFaceColor)
01425         {
01426                 const LLColor4* color = &(getRenderColor());
01427                 
01428                 if ((mDrawPoolp->mVertexShaderLevel > 0) && (mDrawPoolp->getMaterialAttribIndex() != 0))
01429                 {
01430                         glVertexAttrib4fvARB(mDrawPoolp->getMaterialAttribIndex(), color->mV);
01431                 }
01432                 else
01433                 {
01434                         glColor4fv(color->mV);
01435                 }
01436         }
01437 }
01438 
01439 S32 LLFace::pushVertices(const U32* index_array) const
01440 {
01441         if (mIndicesCount)
01442         {
01443                 if (mGeomCount <= gGLManager.mGLMaxVertexRange && 
01444                         mIndicesCount <= (U32) gGLManager.mGLMaxIndexRange)
01445                 {
01446                         glDrawRangeElements(GL_TRIANGLES, mGeomIndex, mGeomIndex + mGeomCount-1, mIndicesCount, 
01447                                                                         GL_UNSIGNED_INT, index_array + mIndicesIndex); 
01448                 }
01449                 else
01450                 {
01451                         glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, index_array+mIndicesIndex);
01452                 }
01453         }
01454         
01455         return mIndicesCount;
01456 }
01457 
01458 const LLMatrix4& LLFace::getRenderMatrix() const
01459 {
01460         return mDrawablep->getRenderMatrix();
01461 }
01462 
01463 S32 LLFace::renderElements(const U32 *index_array) const
01464 {
01465         S32 ret = 0;
01466         
01467         if (isState(GLOBAL))
01468         {       
01469                 ret = pushVertices(index_array);
01470         }
01471         else
01472         {
01473                 glPushMatrix();
01474                 glMultMatrixf((float*)getRenderMatrix().mMatrix);
01475                 ret = pushVertices(index_array);
01476                 glPopMatrix();
01477         }
01478         
01479         return ret;
01480 }
01481 
01482 S32 LLFace::renderIndexed()
01483 {
01484         if(mGeomIndex < 0 || mDrawablep.isNull() || mDrawPoolp == NULL)
01485         {
01486                 return 0;
01487         }
01488         
01489         return renderIndexed(mDrawPoolp->getVertexDataMask());
01490 }
01491 
01492 S32 LLFace::renderIndexed(U32 mask)
01493 {
01494         if (mVertexBuffer.isNull())
01495         {
01496                 return 0;
01497         }
01498 
01499         mVertexBuffer->setBuffer(mask);
01500         U32* index_array = (U32*) mVertexBuffer->getIndicesPointer();
01501         return renderElements(index_array);
01502 }
01503 
01504 //============================================================================
01505 // From llface.inl
01506 
01507 S32 LLFace::getVertices(LLStrider<LLVector3> &vertices)
01508 {
01509         if (!mGeomCount)
01510         {
01511                 return -1;
01512         }
01513         
01514         if (mGeomIndex >= 0) // flexible objects may not have geometry
01515         {
01516                 mVertexBuffer->getVertexStrider(vertices, mGeomIndex);
01517                 
01518         }
01519         return mGeomIndex;
01520 }
01521 
01522 S32 LLFace::getColors(LLStrider<LLColor4U> &colors)
01523 {
01524         if (!mGeomCount)
01525         {
01526                 return -1;
01527         }
01528         
01529         llassert(mGeomIndex >= 0);
01530         mVertexBuffer->getColorStrider(colors, mGeomIndex);
01531         return mGeomIndex;
01532 }
01533 
01534 S32     LLFace::getIndices(LLStrider<U32> &indicesp)
01535 {
01536         mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
01537         llassert(mGeomIndex >= 0 && indicesp[0] != indicesp[1]);
01538         return mIndicesIndex;
01539 }
01540 
01541 LLVector3 LLFace::getPositionAgent() const
01542 {
01543         if (mDrawablep->isStatic())
01544         {
01545                 return mCenterAgent;
01546         }
01547         else
01548         {
01549                 return mCenterLocal * getRenderMatrix();
01550         }
01551 }

Generated on Thu Jul 1 06:08:29 2010 for Second Life Viewer by  doxygen 1.4.7