diff options
author | Jacek Antonelli | 2008-09-06 18:24:57 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-09-06 18:25:07 -0500 |
commit | 798d367d54a6c6379ad355bd8345fa40e31e7fe9 (patch) | |
tree | 1921f1708cd0240648c97bc02df2c2ab5f2fc41e /linden/indra/newview/llface.cpp | |
parent | Second Life viewer sources 1.20.15 (diff) | |
download | meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.zip meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.gz meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.bz2 meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.xz |
Second Life viewer sources 1.21.0-RC
Diffstat (limited to 'linden/indra/newview/llface.cpp')
-rw-r--r-- | linden/indra/newview/llface.cpp | 243 |
1 files changed, 110 insertions, 133 deletions
diff --git a/linden/indra/newview/llface.cpp b/linden/indra/newview/llface.cpp index 3e0c5b2..9a74446 100644 --- a/linden/indra/newview/llface.cpp +++ b/linden/indra/newview/llface.cpp | |||
@@ -54,8 +54,6 @@ | |||
54 | 54 | ||
55 | #define LL_MAX_INDICES_COUNT 1000000 | 55 | #define LL_MAX_INDICES_COUNT 1000000 |
56 | 56 | ||
57 | extern BOOL gPickFaces; | ||
58 | |||
59 | BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE | 57 | BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE |
60 | 58 | ||
61 | #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]) | 59 | #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]) |
@@ -73,14 +71,15 @@ The resulting texture coordinate <u,v> is: | |||
73 | u = 2(B dot P) | 71 | u = 2(B dot P) |
74 | v = 2(T dot P) | 72 | v = 2(T dot P) |
75 | */ | 73 | */ |
76 | void planarProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec) | 74 | void planarProjection(LLVector2 &tc, const LLVector3& normal, |
75 | const LLVector3 &mCenter, const LLVector3& vec) | ||
77 | { //DONE! | 76 | { //DONE! |
78 | LLVector3 binormal; | 77 | LLVector3 binormal; |
79 | float d = vd.mNormal * LLVector3(1,0,0); | 78 | float d = normal * LLVector3(1,0,0); |
80 | if (d >= 0.5f || d <= -0.5f) | 79 | if (d >= 0.5f || d <= -0.5f) |
81 | { | 80 | { |
82 | binormal = LLVector3(0,1,0); | 81 | binormal = LLVector3(0,1,0); |
83 | if (vd.mNormal.mV[0] < 0) | 82 | if (normal.mV[0] < 0) |
84 | { | 83 | { |
85 | binormal = -binormal; | 84 | binormal = -binormal; |
86 | } | 85 | } |
@@ -88,18 +87,19 @@ void planarProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const L | |||
88 | else | 87 | else |
89 | { | 88 | { |
90 | binormal = LLVector3(1,0,0); | 89 | binormal = LLVector3(1,0,0); |
91 | if (vd.mNormal.mV[1] > 0) | 90 | if (normal.mV[1] > 0) |
92 | { | 91 | { |
93 | binormal = -binormal; | 92 | binormal = -binormal; |
94 | } | 93 | } |
95 | } | 94 | } |
96 | LLVector3 tangent = binormal % vd.mNormal; | 95 | LLVector3 tangent = binormal % normal; |
97 | 96 | ||
98 | tc.mV[1] = -((tangent*vec)*2 - 0.5f); | 97 | tc.mV[1] = -((tangent*vec)*2 - 0.5f); |
99 | tc.mV[0] = 1.0f+((binormal*vec)*2 - 0.5f); | 98 | tc.mV[0] = 1.0f+((binormal*vec)*2 - 0.5f); |
100 | } | 99 | } |
101 | 100 | ||
102 | void sphericalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec) | 101 | void sphericalProjection(LLVector2 &tc, const LLVector3& normal, |
102 | const LLVector3 &mCenter, const LLVector3& vec) | ||
103 | { //BROKEN | 103 | { //BROKEN |
104 | /*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f; | 104 | /*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f; |
105 | 105 | ||
@@ -110,7 +110,7 @@ void sphericalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, cons | |||
110 | }*/ | 110 | }*/ |
111 | } | 111 | } |
112 | 112 | ||
113 | void cylindricalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec) | 113 | void cylindricalProjection(LLVector2 &tc, const LLVector3& normal, const LLVector3 &mCenter, const LLVector3& vec) |
114 | { //BROKEN | 114 | { //BROKEN |
115 | /*LLVector3 binormal; | 115 | /*LLVector3 binormal; |
116 | float d = vd.mNormal * LLVector3(1,0,0); | 116 | float d = vd.mNormal * LLVector3(1,0,0); |
@@ -372,9 +372,9 @@ void LLFace::renderForSelect(U32 data_mask) | |||
372 | 372 | ||
373 | mVertexBuffer->setBuffer(data_mask); | 373 | mVertexBuffer->setBuffer(data_mask); |
374 | #if !LL_RELEASE_FOR_DOWNLOAD | 374 | #if !LL_RELEASE_FOR_DOWNLOAD |
375 | LLGLState::checkClientArrays(data_mask); | 375 | LLGLState::checkClientArrays("", data_mask); |
376 | #endif | 376 | #endif |
377 | if (gPickFaces && mTEOffset != -1) | 377 | if (mTEOffset != -1) |
378 | { | 378 | { |
379 | // mask off high 4 bits (16 total possible faces) | 379 | // mask off high 4 bits (16 total possible faces) |
380 | color.mV[0] &= 0x0f; | 380 | color.mV[0] &= 0x0f; |
@@ -419,12 +419,11 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) | |||
419 | 419 | ||
420 | if (mGeomCount > 0 && mIndicesCount > 0) | 420 | if (mGeomCount > 0 && mIndicesCount > 0) |
421 | { | 421 | { |
422 | LLGLSPipelineAlpha gls_pipeline_alpha; | 422 | gGL.color4fv(color.mV); |
423 | glColor4fv(color.mV); | ||
424 | 423 | ||
425 | LLViewerImage::bindTexture(imagep); | 424 | LLViewerImage::bindTexture(imagep); |
426 | 425 | ||
427 | glPushMatrix(); | 426 | gGL.pushMatrix(); |
428 | if (mDrawablep->isActive()) | 427 | if (mDrawablep->isActive()) |
429 | { | 428 | { |
430 | glMultMatrixf((GLfloat*)mDrawablep->getRenderMatrix().mMatrix); | 429 | glMultMatrixf((GLfloat*)mDrawablep->getRenderMatrix().mMatrix); |
@@ -434,137 +433,49 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) | |||
434 | glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); | 433 | glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); |
435 | } | 434 | } |
436 | 435 | ||
437 | mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD); | 436 | mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD); |
438 | #if !LL_RELEASE_FOR_DOWNLOAD | 437 | #if !LL_RELEASE_FOR_DOWNLOAD |
439 | LLGLState::checkClientArrays(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD); | 438 | LLGLState::checkClientArrays("", LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD); |
440 | #endif | 439 | #endif |
441 | mVertexBuffer->draw(LLVertexBuffer::TRIANGLES, mIndicesCount, mIndicesIndex); | 440 | mVertexBuffer->draw(LLVertexBuffer::TRIANGLES, mIndicesCount, mIndicesIndex); |
442 | 441 | ||
443 | glPopMatrix(); | 442 | gGL.popMatrix(); |
444 | } | 443 | } |
445 | } | 444 | } |
446 | 445 | ||
447 | void LLFace::renderSelectedUV(const S32 offset, const S32 count) | 446 | |
447 | /* removed in lieu of raycast uv detection | ||
448 | void LLFace::renderSelectedUV() | ||
448 | { | 449 | { |
449 | #if 0 | ||
450 | LLViewerImage* red_blue_imagep = gImageList.getImageFromFile("uv_test1.j2c", TRUE, TRUE); | 450 | LLViewerImage* red_blue_imagep = gImageList.getImageFromFile("uv_test1.j2c", TRUE, TRUE); |
451 | LLViewerImage* green_imagep = gImageList.getImageFromFile("uv_test2.tga", TRUE, TRUE); | 451 | LLViewerImage* green_imagep = gImageList.getImageFromFile("uv_test2.tga", TRUE, TRUE); |
452 | 452 | ||
453 | LLGLSObjectSelect object_select; | 453 | LLGLSUVSelect object_select; |
454 | LLGLEnable blend(GL_BLEND); | ||
455 | |||
456 | if (!mDrawPoolp || !getIndicesCount() || getIndicesStart() < 0) | ||
457 | { | ||
458 | return; | ||
459 | } | ||
460 | for (S32 pass = 0; pass < 2; pass++) | ||
461 | { | ||
462 | static F32 bias = 0.f; | ||
463 | static F32 factor = -10.f; | ||
464 | if (mGeomCount > 0) | ||
465 | { | ||
466 | gGL.color4fv(LLColor4::white.mV); | ||
467 | |||
468 | if (pass == 0) | ||
469 | { | ||
470 | LLViewerImage::bindTexture(red_blue_imagep); | ||
471 | red_blue_imagep->setMipFilterNearest (TRUE, TRUE); | ||
472 | } | ||
473 | else // pass == 1 | ||
474 | { | ||
475 | gGL.blendFunc(GL_ONE, GL_ONE); | ||
476 | LLViewerImage::bindTexture(green_imagep); | ||
477 | glMatrixMode(GL_TEXTURE); | ||
478 | glPushMatrix(); | ||
479 | glScalef(256.f, 256.f, 1.f); | ||
480 | green_imagep->setMipFilterNearest (TRUE, TRUE); | ||
481 | } | ||
482 | |||
483 | 454 | ||
484 | if (!isState(GLOBAL)) | 455 | // use red/blue gradient to get coarse UV coordinates |
485 | { | 456 | renderSelected(red_blue_imagep, LLColor4::white); |
486 | // Apply the proper transform for non-global objects. | ||
487 | glMatrixMode(GL_MODELVIEW); | ||
488 | glPushMatrix(); | ||
489 | glMultMatrixf((float*)getRenderMatrix().mMatrix); | ||
490 | } | ||
491 | |||
492 | glEnable(GL_POLYGON_OFFSET_FILL); | ||
493 | glPolygonOffset(factor, bias); | ||
494 | if (sSafeRenderSelect) | ||
495 | { | ||
496 | gGL.begin(LLVertexBuffer::TRIANGLES); | ||
497 | if (count) | ||
498 | { | ||
499 | for (S32 i = offset; i < offset + count; i++) | ||
500 | { | ||
501 | LLVector2 tc = mDrawPoolp->getTexCoord(mDrawPoolp->getIndex(getIndicesStart() + i), 0); | ||
502 | gGL.texCoord2fv(tc.mV); | ||
503 | LLVector3 vertex = mDrawPoolp->getVertex(mDrawPoolp->getIndex(getIndicesStart() + i)); | ||
504 | gGL.vertex3fv(vertex.mV); | ||
505 | } | ||
506 | } | ||
507 | else | ||
508 | { | ||
509 | for (U32 i = 0; i < getIndicesCount(); i++) | ||
510 | { | ||
511 | LLVector2 tc = mDrawPoolp->getTexCoord(mDrawPoolp->getIndex(getIndicesStart() + i), 0); | ||
512 | gGL.texCoord2fv(tc.mV); | ||
513 | LLVector3 vertex = mDrawPoolp->getVertex(mDrawPoolp->getIndex(getIndicesStart() + i)); | ||
514 | gGL.vertex3fv(vertex.mV); | ||
515 | } | ||
516 | } | ||
517 | gGL.end(); | ||
518 | } | ||
519 | else | ||
520 | { | ||
521 | llassert(mGeomIndex >= 0); | ||
522 | if (count) | ||
523 | { | ||
524 | if (mIndicesCount > 0) | ||
525 | { | ||
526 | glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, getRawIndices() + offset); | ||
527 | } | ||
528 | else | ||
529 | { | ||
530 | llerrs << "Rendering non-indexed volume face!" << llendl; | ||
531 | glDrawArrays(mPrimType, mGeomIndex, mGeomCount); | ||
532 | } | ||
533 | } | ||
534 | else | ||
535 | { | ||
536 | if (mIndicesCount > 0) | ||
537 | { | ||
538 | glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_SHORT, getRawIndices()); | ||
539 | } | ||
540 | else | ||
541 | { | ||
542 | glDrawArrays(GL_TRIANGLES, mGeomIndex, mGeomCount); | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | |||
547 | glDisable(GL_POLYGON_OFFSET_FILL); | ||
548 | if (!isState(GLOBAL)) | ||
549 | { | ||
550 | // Restore the tranform for non-global objects | ||
551 | glPopMatrix(); | ||
552 | } | ||
553 | if (pass == 1) | ||
554 | { | ||
555 | glMatrixMode(GL_TEXTURE); | ||
556 | glPopMatrix(); | ||
557 | glMatrixMode(GL_MODELVIEW); | ||
558 | gGL.blendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); | ||
559 | } | ||
560 | } | ||
561 | } | ||
562 | 457 | ||
563 | //restore blend func | 458 | static F32 bias = 0.f; |
564 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 459 | static F32 factor = -10.f; |
565 | #endif | 460 | glPolygonOffset(factor, bias); |
461 | |||
462 | // add green dither pattern on top of red/blue gradient | ||
463 | gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_ONE); | ||
464 | glMatrixMode(GL_TEXTURE); | ||
465 | glPushMatrix(); | ||
466 | // make green pattern repeat once per texel in red/blue texture | ||
467 | glScalef(256.f, 256.f, 1.f); | ||
468 | glMatrixMode(GL_MODELVIEW); | ||
469 | |||
470 | renderSelected(green_imagep, LLColor4::white); | ||
471 | |||
472 | glMatrixMode(GL_TEXTURE); | ||
473 | glPopMatrix(); | ||
474 | glMatrixMode(GL_MODELVIEW); | ||
475 | gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); | ||
566 | } | 476 | } |
567 | 477 | ||
478 | */ | ||
568 | 479 | ||
569 | void LLFace::printDebugInfo() const | 480 | void LLFace::printDebugInfo() const |
570 | { | 481 | { |
@@ -760,6 +671,72 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, | |||
760 | return TRUE; | 671 | return TRUE; |
761 | } | 672 | } |
762 | 673 | ||
674 | |||
675 | |||
676 | // convert surface coordinates to texture coordinates, based on | ||
677 | // the values in the texture entry. probably should be | ||
678 | // integrated with getGeometryVolume() for its texture coordinate | ||
679 | // generation - but i'll leave that to someone more familiar | ||
680 | // with the implications. | ||
681 | LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal) | ||
682 | { | ||
683 | LLVector2 tc = surface_coord; | ||
684 | |||
685 | const LLTextureEntry *tep = getTextureEntry(); | ||
686 | |||
687 | if (tep == NULL) | ||
688 | { | ||
689 | // can't do much without the texture entry | ||
690 | return surface_coord; | ||
691 | } | ||
692 | |||
693 | // see if we have a non-default mapping | ||
694 | U8 texgen = getTextureEntry()->getTexGen(); | ||
695 | if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) | ||
696 | { | ||
697 | LLVector3 center = mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter; | ||
698 | |||
699 | LLVector3 scale = (mDrawablep->getVOVolume()->isVolumeGlobal()) ? LLVector3(1,1,1) : mVObjp->getScale(); | ||
700 | LLVector3 volume_position = mDrawablep->getVOVolume()->agentPositionToVolume(position); | ||
701 | volume_position.scaleVec(scale); | ||
702 | |||
703 | LLVector3 volume_normal = mDrawablep->getVOVolume()->agentDirectionToVolume(normal); | ||
704 | volume_normal.normalize(); | ||
705 | |||
706 | switch (texgen) | ||
707 | { | ||
708 | case LLTextureEntry::TEX_GEN_PLANAR: | ||
709 | planarProjection(tc, volume_normal, center, volume_position); | ||
710 | break; | ||
711 | case LLTextureEntry::TEX_GEN_SPHERICAL: | ||
712 | sphericalProjection(tc, volume_normal, center, volume_position); | ||
713 | break; | ||
714 | case LLTextureEntry::TEX_GEN_CYLINDRICAL: | ||
715 | cylindricalProjection(tc, volume_normal, center, volume_position); | ||
716 | break; | ||
717 | default: | ||
718 | break; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | if (mTextureMatrix) // if we have a texture matrix, use it | ||
723 | { | ||
724 | LLVector3 tc3(tc); | ||
725 | tc3 = tc3 * *mTextureMatrix; | ||
726 | tc = LLVector2(tc3); | ||
727 | } | ||
728 | |||
729 | else // otherwise use the texture entry parameters | ||
730 | { | ||
731 | xform(tc, cos(tep->getRotation()), sin(tep->getRotation()), | ||
732 | tep->mOffsetS, tep->mOffsetT, tep->mScaleS, tep->mScaleT); | ||
733 | } | ||
734 | |||
735 | |||
736 | return tc; | ||
737 | } | ||
738 | |||
739 | |||
763 | BOOL LLFace::getGeometryVolume(const LLVolume& volume, | 740 | BOOL LLFace::getGeometryVolume(const LLVolume& volume, |
764 | const S32 &f, | 741 | const S32 &f, |
765 | const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, | 742 | const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, |
@@ -1039,13 +1016,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, | |||
1039 | switch (texgen) | 1016 | switch (texgen) |
1040 | { | 1017 | { |
1041 | case LLTextureEntry::TEX_GEN_PLANAR: | 1018 | case LLTextureEntry::TEX_GEN_PLANAR: |
1042 | planarProjection(tc, vf.mVertices[i], vf.mCenter, vec); | 1019 | planarProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec); |
1043 | break; | 1020 | break; |
1044 | case LLTextureEntry::TEX_GEN_SPHERICAL: | 1021 | case LLTextureEntry::TEX_GEN_SPHERICAL: |
1045 | sphericalProjection(tc, vf.mVertices[i], vf.mCenter, vec); | 1022 | sphericalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec); |
1046 | break; | 1023 | break; |
1047 | case LLTextureEntry::TEX_GEN_CYLINDRICAL: | 1024 | case LLTextureEntry::TEX_GEN_CYLINDRICAL: |
1048 | cylindricalProjection(tc, vf.mVertices[i], vf.mCenter, vec); | 1025 | cylindricalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec); |
1049 | break; | 1026 | break; |
1050 | default: | 1027 | default: |
1051 | break; | 1028 | break; |