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 "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;
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
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 void planarProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec)
00076 {
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 {
00103
00104
00105
00106
00107
00108
00109
00110 }
00111
00112 void cylindricalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec)
00113 {
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 }
00134
00136
00137
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
00150
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
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
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
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
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
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
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
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
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
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
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
00699 static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 offT, F32 magS, F32 magT)
00700 {
00701
00702 F32 s = tex_coord.mV[0];
00703 F32 t = tex_coord.mV[1];
00704
00705
00706 s -= 0.5;
00707 t -= 0.5;
00708
00709
00710 F32 temp = s;
00711 s = s * cosAng + t * sinAng;
00712 t = -temp * sinAng + t * cosAng;
00713
00714
00715 s *= magS;
00716 t *= magT;
00717
00718
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
00733 if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
00734 {
00735 if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
00736 {
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
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
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 {
00855 if (mLastGeomCount == mGeomCount &&
00856 mLastGeomIndex == mGeomIndex &&
00857 mLastIndicesCount == mIndicesCount &&
00858 mLastIndicesIndex == mIndicesIndex)
00859 {
00860 moved = FALSE;
00861 }
00862
00863 if (!moved && !mDrawablep->isState(LLDrawable::REBUILD_ALL))
00864 {
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
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
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
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
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
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:
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;
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;
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
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;
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
01506
01507 S32 LLFace::getVertices(LLStrider<LLVector3> &vertices)
01508 {
01509 if (!mGeomCount)
01510 {
01511 return -1;
01512 }
01513
01514 if (mGeomIndex >= 0)
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 }