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

Generated on Fri May 16 08:33:21 2008 for SecondLife by  doxygen 1.5.5