00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "lldrawable.h"
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;
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
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 void planarProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec)
00077 {
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 {
00104
00105
00106
00107
00108
00109
00110
00111 }
00112
00113 void cylindricalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec)
00114 {
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 }
00135
00137
00138
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
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
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
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
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
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
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
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
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
00640 static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 offT, F32 magS, F32 magT)
00641 {
00642
00643 F32 s = tex_coord.mV[0];
00644 F32 t = tex_coord.mV[1];
00645
00646
00647 s -= 0.5;
00648 t -= 0.5;
00649
00650
00651 F32 temp = s;
00652 s = s * cosAng + t * sinAng;
00653 t = -temp * sinAng + t * cosAng;
00654
00655
00656 s *= magS;
00657 t *= magT;
00658
00659
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
00674 if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
00675 {
00676 if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
00677 {
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
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
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 {
00813 if (mLastGeomCount == mGeomCount &&
00814 mLastGeomIndex == mGeomIndex &&
00815 mLastIndicesCount == mIndicesCount &&
00816 mLastIndicesIndex == mIndicesIndex)
00817 {
00818 moved = FALSE;
00819 }
00820
00821 if (!moved && !mDrawablep->isState(LLDrawable::REBUILD_ALL))
00822 {
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
00913
00914
00915
00916
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 {
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
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
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
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:
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
01011
01012
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 {
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
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;
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
01282
01283 S32 LLFace::getColors(LLStrider<LLColor4U> &colors)
01284 {
01285 if (!mGeomCount)
01286 {
01287 return -1;
01288 }
01289
01290
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 }