diff options
author | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
commit | 89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch) | |
tree | bcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/newview/llvograss.cpp | |
parent | Second Life viewer sources 1.13.3.2 (diff) | |
download | meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2 meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz |
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/newview/llvograss.cpp')
-rw-r--r-- | linden/indra/newview/llvograss.cpp | 211 |
1 files changed, 135 insertions, 76 deletions
diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp index 58e5378..9201549 100644 --- a/linden/indra/newview/llvograss.cpp +++ b/linden/indra/newview/llvograss.cpp | |||
@@ -68,7 +68,7 @@ S32 LLVOGrass::sMaxGrassSpecies = 0; | |||
68 | 68 | ||
69 | 69 | ||
70 | LLVOGrass::LLVOGrass(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) | 70 | LLVOGrass::LLVOGrass(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) |
71 | : LLViewerObject(id, pcode, regionp) | 71 | : LLAlphaObject(id, pcode, regionp) |
72 | { | 72 | { |
73 | mPatch = NULL; | 73 | mPatch = NULL; |
74 | mLastPatchUpdateTime = 0; | 74 | mLastPatchUpdateTime = 0; |
@@ -206,13 +206,13 @@ void LLVOGrass::initClass() | |||
206 | 206 | ||
207 | BOOL have_all_grass = TRUE; | 207 | BOOL have_all_grass = TRUE; |
208 | LLString err; | 208 | LLString err; |
209 | char buffer[10]; | 209 | char buffer[10]; /* Flawfinder: ignore */ |
210 | 210 | ||
211 | for (S32 i=0;i<sMaxGrassSpecies;++i) | 211 | for (S32 i=0;i<sMaxGrassSpecies;++i) |
212 | { | 212 | { |
213 | if (!sSpeciesTable.count(i)) | 213 | if (!sSpeciesTable.count(i)) |
214 | { | 214 | { |
215 | snprintf(buffer,10," %d",i); | 215 | snprintf(buffer,10," %d",i); /* Flawfinder: ignore */ |
216 | err.append(buffer); | 216 | err.append(buffer); |
217 | have_all_grass = FALSE; | 217 | have_all_grass = FALSE; |
218 | } | 218 | } |
@@ -318,38 +318,45 @@ void LLVOGrass::setPixelAreaAndAngle(LLAgent &agent) | |||
318 | { | 318 | { |
319 | // This should be the camera's center, as soon as we move to all region-local. | 319 | // This should be the camera's center, as soon as we move to all region-local. |
320 | LLVector3 relative_position = getPositionAgent() - agent.getCameraPositionAgent(); | 320 | LLVector3 relative_position = getPositionAgent() - agent.getCameraPositionAgent(); |
321 | F32 range = relative_position.magVec(); // ugh, square root | 321 | F32 range = relative_position.magVec(); |
322 | 322 | ||
323 | F32 max_scale = getMaxScale(); | 323 | F32 max_scale = getMaxScale(); |
324 | 324 | ||
325 | mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; | 325 | mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; |
326 | 326 | ||
327 | // Compute pixels per meter at the given range | 327 | // Compute pixels per meter at the given range |
328 | F32 pixels_per_meter = gCamera->getViewHeightInPixels() / | 328 | F32 pixels_per_meter = gCamera->getViewHeightInPixels() / (tan(gCamera->getView()) * range); |
329 | (tan(gCamera->getView()) * range); | ||
330 | 329 | ||
331 | // Assume grass texture is a 1 meter by 1 meter sprite at the grass object's center | 330 | // Assume grass texture is a 5 meter by 5 meter sprite at the grass object's center |
332 | mPixelArea = (pixels_per_meter) * (pixels_per_meter); | 331 | mPixelArea = (pixels_per_meter) * (pixels_per_meter) * 25.f; |
333 | } | 332 | } |
334 | 333 | ||
335 | 334 | ||
336 | // BUG could speed this up by caching the relative_position and range calculations | 335 | // BUG could speed this up by caching the relative_position and range calculations |
337 | void LLVOGrass::updateTextures(LLAgent &agent) | 336 | void LLVOGrass::updateTextures(LLAgent &agent) |
338 | { | 337 | { |
339 | // dot_product = A B cos T | 338 | F32 texel_area_ratio = 1.f; |
340 | // BUT at_axis is unit, so dot_product = B cos T | 339 | F32 cos_angle = 1.f; |
341 | LLVector3 relative_position = getPositionAgent() - agent.getCameraPositionAgent(); | ||
342 | F32 dot_product = relative_position * agent.getFrameAgent().getAtAxis(); | ||
343 | F32 cos_angle = dot_product / relative_position.magVec(); | ||
344 | 340 | ||
345 | if (getTEImage(0)) | 341 | if (getTEImage(0)) |
346 | { | 342 | { |
347 | getTEImage(0)->addTextureStats(mPixelArea*20.f, 1.f, cos_angle); | 343 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) |
344 | { | ||
345 | setDebugText(llformat("%4.0f", fsqrtf(mPixelArea))); | ||
346 | } | ||
347 | getTEImage(0)->addTextureStats(mPixelArea, texel_area_ratio, cos_angle); | ||
348 | } | 348 | } |
349 | } | 349 | } |
350 | 350 | ||
351 | BOOL LLVOGrass::updateLOD() | 351 | BOOL LLVOGrass::updateLOD() |
352 | { | 352 | { |
353 | if (mDrawable->getNumFaces() <= 0) | ||
354 | { | ||
355 | return FALSE; | ||
356 | } | ||
357 | |||
358 | LLFace* face = mDrawable->getFace(0); | ||
359 | |||
353 | F32 tan_angle = 0.f; | 360 | F32 tan_angle = 0.f; |
354 | S32 num_blades = 0; | 361 | S32 num_blades = 0; |
355 | 362 | ||
@@ -363,6 +370,7 @@ BOOL LLVOGrass::updateLOD() | |||
363 | mNumBlades <<= 1; | 370 | mNumBlades <<= 1; |
364 | } | 371 | } |
365 | 372 | ||
373 | face->setSize(mNumBlades*8, mNumBlades*12); | ||
366 | gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); | 374 | gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); |
367 | } | 375 | } |
368 | else if (num_blades <= (mNumBlades >> 1)) | 376 | else if (num_blades <= (mNumBlades >> 1)) |
@@ -372,6 +380,7 @@ BOOL LLVOGrass::updateLOD() | |||
372 | mNumBlades >>=1; | 380 | mNumBlades >>=1; |
373 | } | 381 | } |
374 | 382 | ||
383 | face->setSize(mNumBlades*8, mNumBlades*12); | ||
375 | gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); | 384 | gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); |
376 | return TRUE; | 385 | return TRUE; |
377 | } | 386 | } |
@@ -382,53 +391,20 @@ BOOL LLVOGrass::updateLOD() | |||
382 | LLDrawable* LLVOGrass::createDrawable(LLPipeline *pipeline) | 391 | LLDrawable* LLVOGrass::createDrawable(LLPipeline *pipeline) |
383 | { | 392 | { |
384 | pipeline->allocDrawable(this); | 393 | pipeline->allocDrawable(this); |
385 | // mDrawable->setLit(FALSE); | ||
386 | mDrawable->setRenderType(LLPipeline::RENDER_TYPE_GRASS); | 394 | mDrawable->setRenderType(LLPipeline::RENDER_TYPE_GRASS); |
387 | 395 | ||
388 | LLDrawPool *pool = gPipeline.getPool(LLDrawPool::POOL_ALPHA); | ||
389 | |||
390 | mDrawable->setNumFaces(1, pool, getTEImage(0)); | ||
391 | |||
392 | return mDrawable; | 396 | return mDrawable; |
393 | } | 397 | } |
394 | 398 | ||
395 | BOOL LLVOGrass::updateGeometry(LLDrawable *drawable) | 399 | BOOL LLVOGrass::updateGeometry(LLDrawable *drawable) |
396 | { | 400 | { |
401 | LLFastTimer ftm(LLFastTimer::FTM_UPDATE_GRASS); | ||
397 | plantBlades(); | 402 | plantBlades(); |
398 | return TRUE; | 403 | return TRUE; |
399 | } | 404 | } |
400 | 405 | ||
401 | void LLVOGrass::plantBlades() | 406 | void LLVOGrass::plantBlades() |
402 | { | 407 | { |
403 | mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); | ||
404 | mLastPatchUpdateTime = mPatch->getLastUpdateTime(); | ||
405 | |||
406 | LLVector3 position; | ||
407 | // Create random blades of grass with gaussian distribution | ||
408 | F32 x,y,xf,yf,dzx,dzy; | ||
409 | |||
410 | LLVector3 normal(0,0,1); | ||
411 | LLColor4U color(0,0,0,1); | ||
412 | |||
413 | LLFace *face = mDrawable->getFace(0); | ||
414 | |||
415 | LLStrider<LLVector3> verticesp; | ||
416 | LLStrider<LLVector3> normalsp; | ||
417 | LLStrider<LLVector2> texCoordsp; | ||
418 | LLStrider<LLColor4U> colorsp; | ||
419 | |||
420 | U32 *indicesp; | ||
421 | |||
422 | face->setPool(face->getPool(), getTEImage(0)); | ||
423 | face->setState(LLFace::GLOBAL); | ||
424 | face->setSize(mNumBlades * 4, mNumBlades * 12); | ||
425 | face->setPrimType(LLTriangles); | ||
426 | S32 index_offset = face->getGeometryColors(verticesp,normalsp,texCoordsp,colorsp,indicesp); | ||
427 | if (-1 == index_offset) | ||
428 | { | ||
429 | return; | ||
430 | } | ||
431 | |||
432 | // It is possible that the species of a grass is not defined | 408 | // It is possible that the species of a grass is not defined |
433 | // This is bad, but not the end of the world. | 409 | // This is bad, but not the end of the world. |
434 | if (!sSpeciesTable.count(mSpecies)) | 410 | if (!sSpeciesTable.count(mSpecies)) |
@@ -437,9 +413,49 @@ void LLVOGrass::plantBlades() | |||
437 | return; | 413 | return; |
438 | } | 414 | } |
439 | 415 | ||
416 | if (mDrawable->getNumFaces() < 1) | ||
417 | { | ||
418 | mDrawable->setNumFaces(1, NULL, getTEImage(0)); | ||
419 | } | ||
420 | |||
421 | LLFace *face = mDrawable->getFace(0); | ||
422 | |||
423 | face->setTexture(getTEImage(0)); | ||
424 | face->setState(LLFace::GLOBAL); | ||
425 | face->setSize(mNumBlades * 8, mNumBlades * 12); | ||
426 | face->mVertexBuffer = NULL; | ||
427 | face->setTEOffset(0); | ||
428 | face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); | ||
429 | |||
430 | mDepth = (face->mCenterLocal - gCamera->getOrigin())*gCamera->getAtAxis(); | ||
431 | mDrawable->setPosition(face->mCenterLocal); | ||
432 | mDrawable->movePartition(); | ||
433 | LLPipeline::sCompiles++; | ||
434 | } | ||
435 | |||
436 | void LLVOGrass::getGeometry(S32 idx, | ||
437 | LLStrider<LLVector3>& verticesp, | ||
438 | LLStrider<LLVector3>& normalsp, | ||
439 | LLStrider<LLVector2>& texcoordsp, | ||
440 | LLStrider<LLColor4U>& colorsp, | ||
441 | LLStrider<U32>& indicesp) | ||
442 | { | ||
443 | mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); | ||
444 | mLastPatchUpdateTime = mPatch->getLastUpdateTime(); | ||
445 | |||
446 | LLVector3 position; | ||
447 | // Create random blades of grass with gaussian distribution | ||
448 | F32 x,y,xf,yf,dzx,dzy; | ||
449 | |||
450 | LLColor4U color(255,255,255,255); | ||
451 | |||
452 | LLFace *face = mDrawable->getFace(idx); | ||
453 | |||
440 | F32 width = sSpeciesTable[mSpecies]->mBladeSizeX; | 454 | F32 width = sSpeciesTable[mSpecies]->mBladeSizeX; |
441 | F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; | 455 | F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; |
442 | 456 | ||
457 | U32 index_offset = face->getGeomIndex(); | ||
458 | |||
443 | for (S32 i = 0; i < mNumBlades; i++) | 459 | for (S32 i = 0; i < mNumBlades; i++) |
444 | { | 460 | { |
445 | x = exp_x[i] * mScale.mV[VX]; | 461 | x = exp_x[i] * mScale.mV[VX]; |
@@ -449,70 +465,113 @@ void LLVOGrass::plantBlades() | |||
449 | dzx = dz_x [i]; | 465 | dzx = dz_x [i]; |
450 | dzy = dz_y [i]; | 466 | dzy = dz_y [i]; |
451 | 467 | ||
468 | LLVector3 v1,v2,v3; | ||
452 | F32 blade_height= GRASS_BLADE_HEIGHT * height * w_mod[i]; | 469 | F32 blade_height= GRASS_BLADE_HEIGHT * height * w_mod[i]; |
453 | 470 | ||
454 | *texCoordsp++ = LLVector2(0, 0); | 471 | *texcoordsp++ = LLVector2(0, 0); |
455 | *texCoordsp++ = LLVector2(0, 0.98f); | 472 | *texcoordsp++ = LLVector2(0, 0); |
456 | *texCoordsp++ = LLVector2(1, 0); | 473 | *texcoordsp++ = LLVector2(0, 0.98f); |
457 | *texCoordsp++ = LLVector2(1, 0.98f); | 474 | *texcoordsp++ = LLVector2(0, 0.98f); |
475 | *texcoordsp++ = LLVector2(1, 0); | ||
476 | *texcoordsp++ = LLVector2(1, 0); | ||
477 | *texcoordsp++ = LLVector2(1, 0.98f); | ||
478 | *texcoordsp++ = LLVector2(1, 0.98f); | ||
458 | 479 | ||
459 | position.mV[0] = mPosition.mV[VX] + x + xf; | 480 | position.mV[0] = mPosition.mV[VX] + x + xf; |
460 | position.mV[1] = mPosition.mV[VY] + y + yf; | 481 | position.mV[1] = mPosition.mV[VY] + y + yf; |
461 | position.mV[2] = 0.f; | ||
462 | position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); | 482 | position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); |
463 | *verticesp++ = position + mRegionp->getOriginAgent(); | 483 | *verticesp++ = v1 = position + mRegionp->getOriginAgent(); |
484 | *verticesp++ = v1; | ||
485 | |||
464 | 486 | ||
465 | position.mV[0] += dzx; | 487 | position.mV[0] += dzx; |
466 | position.mV[1] += dzy; | 488 | position.mV[1] += dzy; |
467 | position.mV[2] += blade_height; | 489 | position.mV[2] += blade_height; |
468 | *verticesp++ = position + mRegionp->getOriginAgent(); | 490 | *verticesp++ = v2 = position + mRegionp->getOriginAgent(); |
491 | *verticesp++ = v2; | ||
469 | 492 | ||
470 | position.mV[0] = mPosition.mV[VX] + x - xf; | 493 | position.mV[0] = mPosition.mV[VX] + x - xf; |
471 | position.mV[1] = mPosition.mV[VY] + y - xf; | 494 | position.mV[1] = mPosition.mV[VY] + y - xf; |
472 | position.mV[2] = 0.f; | ||
473 | position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); | 495 | position.mV[2] = mRegionp->getLand().resolveHeightRegion(position); |
474 | *verticesp++ = position + mRegionp->getOriginAgent(); | 496 | *verticesp++ = v3 = position + mRegionp->getOriginAgent(); |
497 | *verticesp++ = v3; | ||
498 | |||
499 | LLVector3 normal1 = (v1-v2) % (v2-v3); | ||
500 | normal1.mV[VZ] = 0.75f; | ||
501 | normal1.normVec(); | ||
502 | LLVector3 normal2 = -normal1; | ||
503 | normal2.mV[VZ] = -normal2.mV[VZ]; | ||
475 | 504 | ||
476 | position.mV[0] += dzx; | 505 | position.mV[0] += dzx; |
477 | position.mV[1] += dzy; | 506 | position.mV[1] += dzy; |
478 | position.mV[2] += blade_height; | 507 | position.mV[2] += blade_height; |
479 | *verticesp++ = position + mRegionp->getOriginAgent(); | 508 | *verticesp++ = v1 = position + mRegionp->getOriginAgent(); |
509 | *verticesp++ = v1; | ||
510 | |||
511 | *(normalsp++) = normal1; | ||
512 | *(normalsp++) = normal2; | ||
513 | *(normalsp++) = normal1; | ||
514 | *(normalsp++) = normal2; | ||
480 | 515 | ||
481 | *(normalsp++) = normal; | 516 | *(normalsp++) = normal1; |
482 | *(normalsp++) = normal; | 517 | *(normalsp++) = normal2; |
483 | *(normalsp++) = normal; | 518 | *(normalsp++) = normal1; |
484 | *(normalsp++) = normal; | 519 | *(normalsp++) = normal2; |
485 | 520 | ||
486 | *(colorsp++) = color; | 521 | *(colorsp++) = color; |
487 | *(colorsp++) = color; | 522 | *(colorsp++) = color; |
488 | *(colorsp++) = color; | 523 | *(colorsp++) = color; |
489 | *(colorsp++) = color; | 524 | *(colorsp++) = color; |
525 | *(colorsp++) = color; | ||
526 | *(colorsp++) = color; | ||
527 | *(colorsp++) = color; | ||
528 | *(colorsp++) = color; | ||
490 | 529 | ||
491 | *indicesp++ = index_offset + 0; | 530 | *indicesp++ = index_offset + 0; |
492 | *indicesp++ = index_offset + 1; | ||
493 | *indicesp++ = index_offset + 2; | 531 | *indicesp++ = index_offset + 2; |
532 | *indicesp++ = index_offset + 4; | ||
494 | 533 | ||
495 | *indicesp++ = index_offset + 1; | ||
496 | *indicesp++ = index_offset + 3; | ||
497 | *indicesp++ = index_offset + 2; | 534 | *indicesp++ = index_offset + 2; |
535 | *indicesp++ = index_offset + 6; | ||
536 | *indicesp++ = index_offset + 4; | ||
498 | 537 | ||
499 | *indicesp++ = index_offset + 0; | ||
500 | *indicesp++ = index_offset + 2; | ||
501 | *indicesp++ = index_offset + 1; | 538 | *indicesp++ = index_offset + 1; |
539 | *indicesp++ = index_offset + 5; | ||
540 | *indicesp++ = index_offset + 3; | ||
502 | 541 | ||
503 | *indicesp++ = index_offset + 1; | ||
504 | *indicesp++ = index_offset + 2; | ||
505 | *indicesp++ = index_offset + 3; | 542 | *indicesp++ = index_offset + 3; |
506 | index_offset += 4; | 543 | *indicesp++ = index_offset + 5; |
544 | *indicesp++ = index_offset + 7; | ||
545 | index_offset += 8; | ||
507 | } | 546 | } |
508 | 547 | ||
509 | LLPipeline::sCompiles++; | 548 | LLPipeline::sCompiles++; |
510 | |||
511 | face->mCenterLocal = mPosition; | ||
512 | |||
513 | } | 549 | } |
514 | 550 | ||
551 | U32 LLVOGrass::getPartitionType() const | ||
552 | { | ||
553 | return LLPipeline::PARTITION_GRASS; | ||
554 | } | ||
515 | 555 | ||
556 | LLGrassPartition::LLGrassPartition() | ||
557 | { | ||
558 | mDrawableType = LLPipeline::RENDER_TYPE_GRASS; | ||
559 | mPartitionType = LLPipeline::PARTITION_GRASS; | ||
560 | mLODPeriod = 16; | ||
561 | mDepthMask = TRUE; | ||
562 | mSlopRatio = 0.1f; | ||
563 | mRenderPass = LLRenderPass::PASS_GRASS; | ||
564 | mBufferUsage = GL_DYNAMIC_DRAW_ARB; | ||
565 | } | ||
516 | 566 | ||
517 | 567 | // virtual | |
518 | 568 | void LLVOGrass::updateDrawable(BOOL force_damped) | |
569 | { | ||
570 | // Force an immediate rebuild on any update | ||
571 | if (mDrawable.notNull()) | ||
572 | { | ||
573 | mDrawable->updateXform(TRUE); | ||
574 | gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); | ||
575 | } | ||
576 | clearChanged(SHIFTED); | ||
577 | } | ||