Unstaged changes cleanup. Further vectorization. Change in binormal/bitangent calculation.
This commit is contained in:
@@ -1302,6 +1302,57 @@ BOOL LLPolyMesh::saveOBJ(LLFILE *fp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Finds binormal based on three vertices with texture coordinates.
|
||||
// Fills in dummy values if the triangle has degenerate texture coordinates.
|
||||
void calc_binormal_from_triangle(LLVector4a& binormal,
|
||||
|
||||
const LLVector4a& pos0,
|
||||
const LLVector2& tex0,
|
||||
const LLVector4a& pos1,
|
||||
const LLVector2& tex1,
|
||||
const LLVector4a& pos2,
|
||||
const LLVector2& tex2)
|
||||
{
|
||||
LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] );
|
||||
LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] );
|
||||
LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] );
|
||||
|
||||
LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] );
|
||||
LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] );
|
||||
LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] );
|
||||
|
||||
LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] );
|
||||
LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] );
|
||||
LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] );
|
||||
|
||||
LLVector4a lhs, rhs;
|
||||
|
||||
LLVector4a r0;
|
||||
lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2);
|
||||
r0.setCross3(lhs, rhs);
|
||||
|
||||
LLVector4a r1;
|
||||
lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2);
|
||||
r1.setCross3(lhs, rhs);
|
||||
|
||||
LLVector4a r2;
|
||||
lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2);
|
||||
r2.setCross3(lhs, rhs);
|
||||
|
||||
if( r0[VX] && r1[VX] && r2[VX] )
|
||||
{
|
||||
binormal.set(
|
||||
-r0[VZ] / r0[VX],
|
||||
-r1[VZ] / r1[VX],
|
||||
-r2[VZ] / r2[VX]);
|
||||
// binormal.normVec();
|
||||
}
|
||||
else
|
||||
{
|
||||
binormal.set( 0, 1 , 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLPolyMesh::loadOBJ()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -116,6 +116,7 @@ set(llcommon_HEADER_FILES
|
||||
linden_common.h
|
||||
linked_lists.h
|
||||
llaccountingcost.h
|
||||
llalignedarray.h
|
||||
llagentconstants.h
|
||||
llallocator.h
|
||||
llallocator_heap_profile.h
|
||||
|
||||
139
indra/llcommon/llalignedarray.h
Normal file
139
indra/llcommon/llalignedarray.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* @file llalignedarray.h
|
||||
* @brief A static array which obeys alignment restrictions and mimics std::vector accessors.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLALIGNEDARRAY_H
|
||||
#define LL_LLALIGNEDARRAY_H
|
||||
|
||||
#include "llmemory.h"
|
||||
|
||||
template <class T, U32 alignment>
|
||||
class LLAlignedArray
|
||||
{
|
||||
public:
|
||||
T* mArray;
|
||||
U32 mElementCount;
|
||||
U32 mCapacity;
|
||||
|
||||
LLAlignedArray();
|
||||
~LLAlignedArray();
|
||||
|
||||
void push_back(const T& elem);
|
||||
U32 size() const { return mElementCount; }
|
||||
void resize(U32 size);
|
||||
T* append(S32 N);
|
||||
T& operator[](int idx);
|
||||
const T& operator[](int idx) const;
|
||||
};
|
||||
|
||||
template <class T, U32 alignment>
|
||||
LLAlignedArray<T, alignment>::LLAlignedArray()
|
||||
{
|
||||
llassert(alignment >= 16);
|
||||
mArray = NULL;
|
||||
mElementCount = 0;
|
||||
mCapacity = 0;
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
LLAlignedArray<T, alignment>::~LLAlignedArray()
|
||||
{
|
||||
ll_aligned_free(mArray);
|
||||
mArray = NULL;
|
||||
mElementCount = 0;
|
||||
mCapacity = 0;
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
void LLAlignedArray<T, alignment>::push_back(const T& elem)
|
||||
{
|
||||
T* old_buf = NULL;
|
||||
if (mCapacity <= mElementCount)
|
||||
{
|
||||
mCapacity++;
|
||||
mCapacity *= 2;
|
||||
T* new_buf = (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment);
|
||||
if (mArray)
|
||||
{
|
||||
ll_memcpy_nonaliased_aligned_16((char*)new_buf, (char*)mArray, sizeof(T)*mElementCount);
|
||||
}
|
||||
old_buf = mArray;
|
||||
mArray = new_buf;
|
||||
}
|
||||
|
||||
mArray[mElementCount++] = elem;
|
||||
|
||||
//delete old array here to prevent error on a.push_back(a[0])
|
||||
ll_aligned_free(old_buf);
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
void LLAlignedArray<T, alignment>::resize(U32 size)
|
||||
{
|
||||
if (mCapacity < size)
|
||||
{
|
||||
mCapacity = size+mCapacity*2;
|
||||
T* new_buf = mCapacity > 0 ? (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment) : NULL;
|
||||
if (mArray)
|
||||
{
|
||||
ll_memcpy_nonaliased_aligned_16((char*) new_buf, (char*) mArray, sizeof(T)*mElementCount);
|
||||
ll_aligned_free(mArray);
|
||||
}
|
||||
|
||||
/*for (U32 i = mElementCount; i < mCapacity; ++i)
|
||||
{
|
||||
new(new_buf+i) T();
|
||||
}*/
|
||||
mArray = new_buf;
|
||||
}
|
||||
|
||||
mElementCount = size;
|
||||
}
|
||||
|
||||
|
||||
template <class T, U32 alignment>
|
||||
T& LLAlignedArray<T, alignment>::operator[](int idx)
|
||||
{
|
||||
llassert(idx < mElementCount);
|
||||
return mArray[idx];
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
const T& LLAlignedArray<T, alignment>::operator[](int idx) const
|
||||
{
|
||||
llassert(idx < mElementCount);
|
||||
return mArray[idx];
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
T* LLAlignedArray<T, alignment>::append(S32 N)
|
||||
{
|
||||
U32 sz = size();
|
||||
resize(sz+N);
|
||||
return &((*this)[sz]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,27 +42,77 @@ class LLMutex ;
|
||||
#define LL_CHECK_MEMORY
|
||||
#endif
|
||||
|
||||
LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
|
||||
#else
|
||||
#define ll_assert_aligned(ptr,alignment)
|
||||
#endif
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)
|
||||
{
|
||||
return reinterpret_cast<T*>(
|
||||
(reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF);
|
||||
}
|
||||
|
||||
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
|
||||
{
|
||||
return reinterpret_cast<T*>(
|
||||
(reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F);
|
||||
}
|
||||
|
||||
#if LL_LINUX || LL_DARWIN
|
||||
|
||||
#define LL_ALIGN_PREFIX(x)
|
||||
#define LL_ALIGN_POSTFIX(x) __attribute__((aligned(x)))
|
||||
|
||||
#elif LL_WINDOWS
|
||||
|
||||
#define LL_ALIGN_PREFIX(x) __declspec(align(x))
|
||||
#define LL_ALIGN_POSTFIX(x)
|
||||
|
||||
#else
|
||||
#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined"
|
||||
#endif
|
||||
|
||||
#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
|
||||
|
||||
inline void* ll_aligned_malloc( size_t size, int align )
|
||||
{
|
||||
#if defined(LL_WINDOWS)
|
||||
return _aligned_malloc(size, align);
|
||||
#else
|
||||
void* mem = malloc( size + (align - 1) + sizeof(void*) );
|
||||
char* aligned = ((char*)mem) + sizeof(void*);
|
||||
aligned += align - ((uintptr_t)aligned & (align - 1));
|
||||
|
||||
((void**)aligned)[-1] = mem;
|
||||
return aligned;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void ll_aligned_free( void* ptr )
|
||||
{
|
||||
free( ((void**)ptr)[-1] );
|
||||
#if defined(LL_WINDOWS)
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
if (ptr)
|
||||
{
|
||||
free( ((void**)ptr)[-1] );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !LL_USE_TCMALLOC
|
||||
inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16().
|
||||
{
|
||||
#if (LL_DARWIN || LL_USE_TCMALLOC)
|
||||
return malloc(size); // default osx malloc is 16 byte aligned.
|
||||
#elif LL_WINDOWS
|
||||
#if defined(LL_WINDOWS)
|
||||
return _aligned_malloc(size, 16);
|
||||
#elif defined(LL_DARWIN)
|
||||
return malloc(size); // default osx malloc is 16 byte aligned.
|
||||
#else
|
||||
void *rtn;
|
||||
if (LL_LIKELY(0 == posix_memalign(&rtn, 16, size)))
|
||||
@@ -74,10 +124,10 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi
|
||||
|
||||
inline void ll_aligned_free_16(void *p)
|
||||
{
|
||||
#if (LL_DARWIN || LL_USE_TCMALLOC)
|
||||
free(p);
|
||||
#elif LL_WINDOWS
|
||||
#if defined(LL_WINDOWS)
|
||||
_aligned_free(p);
|
||||
#elif defined(LL_DARWIN)
|
||||
return free(p);
|
||||
#else
|
||||
free(p); // posix_memalign() is compatible with heap deallocator
|
||||
#endif
|
||||
@@ -85,10 +135,10 @@ inline void ll_aligned_free_16(void *p)
|
||||
|
||||
inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16().
|
||||
{
|
||||
#if (LL_DARWIN || LL_USE_TCMALLOC)
|
||||
return realloc(ptr,size); // default osx malloc is 16 byte aligned.
|
||||
#elif LL_WINDOWS
|
||||
#if defined(LL_WINDOWS)
|
||||
return _aligned_realloc(ptr, size, 16);
|
||||
#elif defined(LL_DARWIN)
|
||||
return realloc(ptr,size); // default osx malloc is 16 byte aligned.
|
||||
#else
|
||||
//FIXME: memcpy is SLOW
|
||||
void* ret = ll_aligned_malloc_16(size);
|
||||
@@ -105,11 +155,18 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r
|
||||
#endif
|
||||
}
|
||||
|
||||
#else // USE_TCMALLOC
|
||||
// ll_aligned_foo_16 are not needed with tcmalloc
|
||||
#define ll_aligned_malloc_16 malloc
|
||||
#define ll_aligned_realloc_16(a,b,c) realloc(a,b)
|
||||
#define ll_aligned_free_16 free
|
||||
#endif // USE_TCMALLOC
|
||||
|
||||
inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32().
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
#if defined(LL_WINDOWS)
|
||||
return _aligned_malloc(size, 32);
|
||||
#elif LL_DARWIN
|
||||
#elif defined(LL_DARWIN)
|
||||
return ll_aligned_malloc( size, 32 );
|
||||
#else
|
||||
void *rtn;
|
||||
@@ -122,15 +179,87 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi
|
||||
|
||||
inline void ll_aligned_free_32(void *p)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
#if defined(LL_WINDOWS)
|
||||
_aligned_free(p);
|
||||
#elif LL_DARWIN
|
||||
#elif defined(LL_DARWIN)
|
||||
ll_aligned_free( p );
|
||||
#else
|
||||
free(p); // posix_memalign() is compatible with heap deallocator
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Copy words 16-byte blocks from src to dst. Source and destination MUST NOT OVERLAP.
|
||||
// Source and dest must be 16-byte aligned and size must be multiple of 16.
|
||||
//
|
||||
inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
|
||||
{
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
assert(bytes > 0);
|
||||
assert((bytes % sizeof(F32))== 0);
|
||||
ll_assert_aligned(src,16);
|
||||
ll_assert_aligned(dst,16);
|
||||
assert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src));
|
||||
assert(bytes%16==0);
|
||||
|
||||
char* end = dst + bytes;
|
||||
|
||||
if (bytes > 64)
|
||||
{
|
||||
|
||||
// Find start of 64b aligned area within block
|
||||
//
|
||||
void* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
|
||||
|
||||
//at least 64 bytes before the end of the destination, switch to 16 byte copies
|
||||
void* end_64 = end-64;
|
||||
|
||||
// Prefetch the head of the 64b area now
|
||||
//
|
||||
_mm_prefetch((char*)begin_64, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
|
||||
|
||||
// Copy 16b chunks until we're 64b aligned
|
||||
//
|
||||
while (dst < begin_64)
|
||||
{
|
||||
|
||||
_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
|
||||
dst += 16;
|
||||
src += 16;
|
||||
}
|
||||
|
||||
// Copy 64b chunks up to your tail
|
||||
//
|
||||
// might be good to shmoo the 512b prefetch offset
|
||||
// (characterize performance for various values)
|
||||
//
|
||||
while (dst < end_64)
|
||||
{
|
||||
_mm_prefetch((char*)src + 512, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)dst + 512, _MM_HINT_NTA);
|
||||
_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
|
||||
_mm_store_ps((F32*)(dst + 16), _mm_load_ps((F32*)(src + 16)));
|
||||
_mm_store_ps((F32*)(dst + 32), _mm_load_ps((F32*)(src + 32)));
|
||||
_mm_store_ps((F32*)(dst + 48), _mm_load_ps((F32*)(src + 48)));
|
||||
dst += 64;
|
||||
src += 64;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy remainder 16b tail chunks (or ALL 16b chunks for sub-64b copies)
|
||||
//
|
||||
while (dst < end)
|
||||
{
|
||||
_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
|
||||
dst += 16;
|
||||
src += 16;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __DEBUG_PRIVATE_MEM__
|
||||
#define __DEBUG_PRIVATE_MEM__ 0
|
||||
#endif
|
||||
|
||||
@@ -60,7 +60,7 @@ inline void LLMatrix3a::setTranspose(const LLMatrix3a& src)
|
||||
const LLQuad srcCol1 = src.mColumns[1];
|
||||
const LLQuad unpacklo = _mm_unpacklo_ps( srcCol0, srcCol1 );
|
||||
mColumns[0] = _mm_movelh_ps( unpacklo, src.mColumns[2] );
|
||||
mColumns[1] = _mm_shuffle_ps( unpacklo, src.mColumns[2], _MM_SHUFFLE(0, 1, 3, 2) );
|
||||
mColumns[1] = _mm_shuffle_ps( _mm_movehl_ps( srcCol0, unpacklo ), src.mColumns[2], _MM_SHUFFLE(0, 1, 1, 0) );
|
||||
mColumns[2] = _mm_shuffle_ps( _mm_unpackhi_ps( srcCol0, srcCol1 ), src.mColumns[2], _MM_SHUFFLE(0, 2, 1, 0) );
|
||||
}
|
||||
|
||||
|
||||
@@ -39,34 +39,6 @@
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)
|
||||
{
|
||||
return reinterpret_cast<T*>(
|
||||
(reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF);
|
||||
}
|
||||
|
||||
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
|
||||
{
|
||||
return reinterpret_cast<T*>(
|
||||
(reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F);
|
||||
}
|
||||
|
||||
#if LL_LINUX || LL_DARWIN
|
||||
|
||||
#define LL_ALIGN_PREFIX(x)
|
||||
#define LL_ALIGN_POSTFIX(x) __attribute__((aligned(x)))
|
||||
|
||||
#elif LL_WINDOWS
|
||||
|
||||
#define LL_ALIGN_PREFIX(x) __declspec(align(x))
|
||||
#define LL_ALIGN_POSTFIX(x)
|
||||
|
||||
#else
|
||||
#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined"
|
||||
#endif
|
||||
|
||||
#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
|
||||
@@ -41,55 +41,7 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast<const LLVector4a&> ( F
|
||||
|
||||
/*static */void LLVector4a::memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes)
|
||||
{
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
assert(bytes > 0);
|
||||
assert((bytes % sizeof(F32))== 0);
|
||||
ll_assert_aligned(src,16);
|
||||
ll_assert_aligned(dst,16);
|
||||
assert(bytes%16==0);
|
||||
|
||||
F32* end = dst + (bytes / sizeof(F32) );
|
||||
|
||||
if (bytes > 64)
|
||||
{
|
||||
F32* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
|
||||
|
||||
//at least 64 (16*4) bytes before the end of the destination, switch to 16 byte copies
|
||||
F32* end_64 = end-16;
|
||||
|
||||
_mm_prefetch((char*)begin_64, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
|
||||
|
||||
while (dst < begin_64)
|
||||
{
|
||||
copy4a(dst, src);
|
||||
dst += 4;
|
||||
src += 4;
|
||||
}
|
||||
|
||||
while (dst < end_64)
|
||||
{
|
||||
_mm_prefetch((char*)src + 512, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)dst + 512, _MM_HINT_NTA);
|
||||
copy4a(dst, src);
|
||||
copy4a(dst+4, src+4);
|
||||
copy4a(dst+8, src+8);
|
||||
copy4a(dst+12, src+12);
|
||||
|
||||
dst += 16;
|
||||
src += 16;
|
||||
}
|
||||
}
|
||||
|
||||
while (dst < end)
|
||||
{
|
||||
copy4a(dst, src);
|
||||
dst += 4;
|
||||
src += 4;
|
||||
}
|
||||
ll_memcpy_nonaliased_aligned_16((char*)dst, (char*)src, bytes);
|
||||
}
|
||||
|
||||
void LLVector4a::setRotated( const LLRotation& rot, const LLVector4a& vec )
|
||||
|
||||
@@ -46,6 +46,7 @@ class LLRotation;
|
||||
// of this writing, July 08, 2010) about getting it implemented before you resort to
|
||||
// LLVector3/LLVector4.
|
||||
/////////////////////////////////
|
||||
class LLVector4a;
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLVector4a
|
||||
@@ -235,6 +236,11 @@ public:
|
||||
// Note that this does not consider zero length vectors!
|
||||
inline void normalize3fast();
|
||||
|
||||
// Normalize this vector with respect to the x, y, and z components only. Accurate only to 10-12 bits of precision. W component is destroyed
|
||||
// Same as above except substitutes default vector contents if the vector is non-finite or degenerate due to zero length.
|
||||
//
|
||||
inline void normalize3fast_checked(LLVector4a* d = 0);
|
||||
|
||||
// Return true if this vector is normalized with respect to x,y,z up to tolerance
|
||||
inline LLBool32 isNormalized3( F32 tolerance = 1e-3 ) const;
|
||||
|
||||
|
||||
@@ -409,6 +409,26 @@ inline void LLVector4a::normalize3fast()
|
||||
mQ = _mm_mul_ps( mQ, approxRsqrt );
|
||||
}
|
||||
|
||||
inline void LLVector4a::normalize3fast_checked(LLVector4a* d)
|
||||
{
|
||||
if (!isFinite3())
|
||||
{
|
||||
*this = d ? *d : LLVector4a(0,1,0,1);
|
||||
return;
|
||||
}
|
||||
|
||||
LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this );
|
||||
|
||||
if (lenSqrd.getF32ptr()[0] <= FLT_EPSILON)
|
||||
{
|
||||
*this = d ? *d : LLVector4a(0,1,0,1);
|
||||
return;
|
||||
}
|
||||
|
||||
const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ);
|
||||
mQ = _mm_mul_ps( mQ, approxRsqrt );
|
||||
}
|
||||
|
||||
// Return true if this vector is normalized with respect to x,y,z up to tolerance
|
||||
inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const
|
||||
{
|
||||
@@ -460,21 +480,19 @@ inline void LLVector4a::setMax(const LLVector4a& lhs, const LLVector4a& rhs)
|
||||
mQ = _mm_max_ps(lhs.mQ, rhs.mQ);
|
||||
}
|
||||
|
||||
// Set this to (c * lhs) + rhs * ( 1 - c)
|
||||
// Set this to lhs + (rhs-lhs)*c
|
||||
inline void LLVector4a::setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F32 c)
|
||||
{
|
||||
LLVector4a a = lhs;
|
||||
a.mul(c);
|
||||
|
||||
LLVector4a b = rhs;
|
||||
b.mul(1.f-c);
|
||||
|
||||
setAdd(a, b);
|
||||
LLVector4a t;
|
||||
t.setSub(rhs,lhs);
|
||||
t.mul(c);
|
||||
setAdd(lhs, t);
|
||||
}
|
||||
|
||||
inline LLBool32 LLVector4a::isFinite3() const
|
||||
{
|
||||
static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 };
|
||||
ll_assert_aligned(nanOrInfMask,16);
|
||||
const __m128i nanOrInfMaskV = *reinterpret_cast<const __m128i*> (nanOrInfMask);
|
||||
const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV );
|
||||
const LLVector4Logical equalityCheck = _mm_castsi128_ps(_mm_cmpeq_epi32( maskResult, nanOrInfMaskV ));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,6 @@ class LLPath;
|
||||
|
||||
template <class T> class LLOctreeNode;
|
||||
|
||||
class LLVector4a;
|
||||
class LLVolumeFace;
|
||||
class LLVolume;
|
||||
class LLVolumeTriangle;
|
||||
@@ -50,12 +49,15 @@ class LLVolumeTriangle;
|
||||
#include "v3math.h"
|
||||
#include "v3dmath.h"
|
||||
#include "v4math.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "llquaternion.h"
|
||||
#include "llstrider.h"
|
||||
#include "v4coloru.h"
|
||||
#include "llrefcount.h"
|
||||
#include "llpointer.h"
|
||||
#include "llfile.h"
|
||||
#include "llalignedarray.h"
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -709,16 +711,16 @@ public:
|
||||
LLFaceID mFaceID;
|
||||
};
|
||||
|
||||
std::vector<LLVector3> mProfile;
|
||||
std::vector<LLVector2> mNormals;
|
||||
LLAlignedArray<LLVector4a, 64> mProfile;
|
||||
//LLAlignedArray<LLVector4a, 64> mNormals;
|
||||
std::vector<Face> mFaces;
|
||||
std::vector<LLVector3> mEdgeNormals;
|
||||
std::vector<LLVector3> mEdgeCenters;
|
||||
|
||||
//LLAlignedArray<LLVector4a, 64> mEdgeNormals;
|
||||
//LLAlignedArray<LLVector4a, 64> mEdgeCenters;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
|
||||
|
||||
protected:
|
||||
void genNormals(const LLProfileParams& params);
|
||||
static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
|
||||
void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
|
||||
|
||||
@@ -742,13 +744,29 @@ protected:
|
||||
class LLPath
|
||||
{
|
||||
public:
|
||||
struct PathPt
|
||||
class PathPt
|
||||
{
|
||||
LLVector3 mPos;
|
||||
LLVector2 mScale;
|
||||
LLQuaternion mRot;
|
||||
public:
|
||||
LLMatrix4a mRot;
|
||||
LLVector4a mPos;
|
||||
|
||||
LLVector4a mScale;
|
||||
F32 mTexT;
|
||||
PathPt() { mPos.setVec(0,0,0); mTexT = 0; mScale.setVec(0,0); mRot.loadIdentity(); }
|
||||
F32 pad[3]; //for alignment
|
||||
PathPt()
|
||||
{
|
||||
mPos.clear();
|
||||
mTexT = 0;
|
||||
mScale.clear();
|
||||
mRot.setRows(LLVector4a(1,0,0,0),
|
||||
LLVector4a(0,1,0,0),
|
||||
LLVector4a(0,0,1,0));
|
||||
|
||||
//distinguished data in the pad for debugging
|
||||
pad[0] = 3.14159f;
|
||||
pad[1] = -3.14159f;
|
||||
pad[2] = 0.585f;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -780,7 +798,7 @@ public:
|
||||
friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
|
||||
|
||||
public:
|
||||
std::vector<PathPt> mPath;
|
||||
LLAlignedArray<PathPt, 64> mPath;
|
||||
|
||||
protected:
|
||||
BOOL mOpen;
|
||||
@@ -845,12 +863,12 @@ private:
|
||||
public:
|
||||
|
||||
BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
void createBinormals();
|
||||
void createTangents();
|
||||
|
||||
void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform);
|
||||
|
||||
void resizeVertices(S32 num_verts);
|
||||
void allocateBinormals(S32 num_verts);
|
||||
void allocateTangents(S32 num_verts);
|
||||
void allocateWeights(S32 num_verts);
|
||||
void resizeIndices(S32 num_indices);
|
||||
void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx);
|
||||
@@ -913,11 +931,12 @@ public:
|
||||
LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
|
||||
|
||||
S32 mNumVertices;
|
||||
S32 mNumAllocatedVertices;
|
||||
S32 mNumIndices;
|
||||
|
||||
LLVector4a* mPositions;
|
||||
LLVector4a* mNormals;
|
||||
LLVector4a* mBinormals;
|
||||
LLVector4a* mTangents;
|
||||
LLVector2* mTexCoords;
|
||||
U16* mIndices;
|
||||
|
||||
@@ -931,9 +950,12 @@ public:
|
||||
// format is mWeights[vertex_index].mV[influence] = <joint_index>.<weight>
|
||||
// mWeights.size() should be empty or match mVertices.size()
|
||||
LLVector4a* mWeights;
|
||||
|
||||
|
||||
LLOctreeNode<LLVolumeTriangle>* mOctree;
|
||||
|
||||
//whether or not face has been cache optimized
|
||||
BOOL mOptimized;
|
||||
|
||||
private:
|
||||
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
@@ -945,15 +967,10 @@ class LLVolume : public LLRefCount
|
||||
friend class LLVolumeLODGroup;
|
||||
|
||||
protected:
|
||||
LLVolume(const LLVolume&); // Don't implement
|
||||
~LLVolume(); // use unref
|
||||
|
||||
public:
|
||||
struct Point
|
||||
{
|
||||
LLVector3 mPos;
|
||||
};
|
||||
|
||||
|
||||
struct FaceParams
|
||||
{
|
||||
LLFaceID mFaceID;
|
||||
@@ -976,13 +993,13 @@ public:
|
||||
const LLProfile& getProfile() const { return *mProfilep; }
|
||||
LLPath& getPath() const { return *mPathp; }
|
||||
void resizePath(S32 length);
|
||||
const std::vector<Point>& getMesh() const { return mMesh; }
|
||||
const LLVector3& getMeshPt(const U32 i) const { return mMesh[i].mPos; }
|
||||
const LLAlignedArray<LLVector4a,64>& getMesh() const { return mMesh; }
|
||||
const LLVector4a& getMeshPt(const U32 i) const { return mMesh[i]; }
|
||||
|
||||
void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
|
||||
|
||||
void regen();
|
||||
void genBinormals(S32 face);
|
||||
void genTangents(S32 face);
|
||||
|
||||
BOOL isConvex() const;
|
||||
BOOL isCap(S32 face);
|
||||
@@ -992,10 +1009,7 @@ public:
|
||||
S32 getSculptLevel() const { return mSculptLevel; }
|
||||
void setSculptLevel(S32 level) { mSculptLevel = level; }
|
||||
|
||||
S32 *getTriangleIndices(U32 &num_indices) const;
|
||||
|
||||
// returns number of triangle indeces required for path/profile mesh
|
||||
S32 getNumTriangleIndices() const;
|
||||
|
||||
static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
|
||||
|
||||
S32 getNumTriangles(S32* vcount = NULL) const;
|
||||
@@ -1010,21 +1024,14 @@ public:
|
||||
//get the face index of the face that intersects with the given line segment at the point
|
||||
//closest to start. Moves end to the point of intersection. Returns -1 if no intersection.
|
||||
//Line segment must be in volume space.
|
||||
S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
|
||||
S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = 1,
|
||||
LLVector3* intersection = NULL,
|
||||
LLVector2* tex_coord = NULL,
|
||||
LLVector3* normal = NULL,
|
||||
LLVector3* bi_normal = NULL);
|
||||
|
||||
LLFaceID generateFaceMask();
|
||||
|
||||
BOOL isFaceMaskValid(LLFaceID face_mask);
|
||||
@@ -1068,7 +1075,8 @@ public:
|
||||
LLVolumeParams mParams;
|
||||
LLPath *mPathp;
|
||||
LLProfile *mProfilep;
|
||||
std::vector<Point> mMesh;
|
||||
LLAlignedArray<LLVector4a,64> mMesh;
|
||||
|
||||
|
||||
BOOL mGenerateSingleFace;
|
||||
typedef std::vector<LLVolumeFace> face_list_t;
|
||||
@@ -1083,21 +1091,12 @@ public:
|
||||
|
||||
std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
|
||||
|
||||
void calc_binormal_from_triangle(
|
||||
LLVector4a& binormal,
|
||||
const LLVector4a& pos0,
|
||||
const LLVector2& tex0,
|
||||
const LLVector4a& pos1,
|
||||
const LLVector2& tex1,
|
||||
const LLVector4a& pos2,
|
||||
const LLVector2& tex2);
|
||||
|
||||
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);
|
||||
BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);
|
||||
BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size);
|
||||
|
||||
BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
|
||||
F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
|
||||
//BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
|
||||
// F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
|
||||
|
||||
BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
|
||||
F32& intersection_a, F32& intersection_b, F32& intersection_t);
|
||||
|
||||
@@ -94,14 +94,14 @@ void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTria
|
||||
|
||||
LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
|
||||
const LLVolumeFace* face, F32* closest_t,
|
||||
LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
|
||||
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
|
||||
: mFace(face),
|
||||
mStart(start),
|
||||
mDir(dir),
|
||||
mIntersection(intersection),
|
||||
mTexCoord(tex_coord),
|
||||
mNormal(normal),
|
||||
mBinormal(bi_normal),
|
||||
mTangent(tangent),
|
||||
mClosestT(closest_t),
|
||||
mHitFace(false)
|
||||
{
|
||||
@@ -112,13 +112,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
|
||||
{
|
||||
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0);
|
||||
|
||||
/*const F32* start = mStart.getF32();
|
||||
const F32* end = mEnd.getF32();
|
||||
const F32* center = vl->mBounds[0].getF32();
|
||||
const F32* size = vl->mBounds[1].getF32();*/
|
||||
|
||||
//if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
|
||||
if (LLLineSegmentBoxIntersect(mStart.getF32ptr(), mEnd.getF32ptr(), vl->mBounds[0].getF32ptr(), vl->mBounds[1].getF32ptr()))
|
||||
if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
|
||||
{
|
||||
node->accept(this);
|
||||
for (U32 i = 0; i < node->getChildCount(); ++i)
|
||||
@@ -152,34 +146,60 @@ void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* n
|
||||
LLVector4a intersect = mDir;
|
||||
intersect.mul(*mClosestT);
|
||||
intersect.add(mStart);
|
||||
mIntersection->set(intersect.getF32ptr());
|
||||
*mIntersection = intersect;
|
||||
}
|
||||
|
||||
U32 idx0 = tri->mIndex[0];
|
||||
U32 idx1 = tri->mIndex[1];
|
||||
U32 idx2 = tri->mIndex[2];
|
||||
|
||||
if (mTexCoord != NULL)
|
||||
{
|
||||
LLVector2* tc = (LLVector2*) mFace->mTexCoords;
|
||||
*mTexCoord = ((1.f - a - b) * tc[tri->mIndex[0]] +
|
||||
a * tc[tri->mIndex[1]] +
|
||||
b * tc[tri->mIndex[2]]);
|
||||
*mTexCoord = ((1.f - a - b) * tc[idx0] +
|
||||
a * tc[idx1] +
|
||||
b * tc[idx2]);
|
||||
|
||||
}
|
||||
|
||||
if (mNormal != NULL)
|
||||
{
|
||||
LLVector4* norm = (LLVector4*) mFace->mNormals;
|
||||
LLVector4a* norm = mFace->mNormals;
|
||||
|
||||
LLVector4a n1,n2,n3;
|
||||
n1 = norm[idx0];
|
||||
n1.mul(1.f-a-b);
|
||||
|
||||
n2 = norm[idx1];
|
||||
n2.mul(a);
|
||||
|
||||
n3 = norm[idx2];
|
||||
n3.mul(b);
|
||||
|
||||
*mNormal = ((1.f - a - b) * LLVector3(norm[tri->mIndex[0]]) +
|
||||
a * LLVector3(norm[tri->mIndex[1]]) +
|
||||
b * LLVector3(norm[tri->mIndex[2]]));
|
||||
n1.add(n2);
|
||||
n1.add(n3);
|
||||
|
||||
*mNormal = n1;
|
||||
}
|
||||
|
||||
if (mBinormal != NULL)
|
||||
if (mTangent != NULL)
|
||||
{
|
||||
LLVector4* binormal = (LLVector4*) mFace->mBinormals;
|
||||
*mBinormal = ((1.f - a - b) * LLVector3(binormal[tri->mIndex[0]]) +
|
||||
a * LLVector3(binormal[tri->mIndex[1]]) +
|
||||
b * LLVector3(binormal[tri->mIndex[2]]));
|
||||
LLVector4a* tangents = mFace->mTangents;
|
||||
|
||||
LLVector4a t1,t2,t3;
|
||||
t1 = tangents[idx0];
|
||||
t1.mul(1.f-a-b);
|
||||
|
||||
t2 = tangents[idx1];
|
||||
t2.mul(a);
|
||||
|
||||
t3 = tangents[idx2];
|
||||
t3.mul(b);
|
||||
|
||||
t1.add(t2);
|
||||
t1.add(t3);
|
||||
|
||||
*mTangent = t1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,16 +134,16 @@ public:
|
||||
LLVector4a mStart;
|
||||
LLVector4a mDir;
|
||||
LLVector4a mEnd;
|
||||
LLVector3* mIntersection;
|
||||
LLVector4a* mIntersection;
|
||||
LLVector2* mTexCoord;
|
||||
LLVector3* mNormal;
|
||||
LLVector3* mBinormal;
|
||||
LLVector4a* mNormal;
|
||||
LLVector4a* mTangent;
|
||||
F32* mClosestT;
|
||||
bool mHitFace;
|
||||
|
||||
LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
|
||||
const LLVolumeFace* face, F32* closest_t,
|
||||
LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal);
|
||||
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
|
||||
|
||||
void traverse(const LLOctreeNode<LLVolumeTriangle>* node);
|
||||
|
||||
|
||||
@@ -263,13 +263,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//l_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
@@ -294,13 +294,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
@@ -482,13 +482,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
@@ -516,13 +516,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
@@ -716,13 +716,13 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!n)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!t)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
@@ -996,6 +996,43 @@ void LLModel::getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& tra
|
||||
translation_out = mNormalizedTranslation;
|
||||
}
|
||||
|
||||
LLVector3 LLModel::getTransformedCenter(const LLMatrix4& mat)
|
||||
{
|
||||
LLVector3 ret;
|
||||
|
||||
if (!mVolumeFaces.empty())
|
||||
{
|
||||
LLMatrix4a m;
|
||||
m.loadu(mat);
|
||||
|
||||
LLVector4a minv,maxv;
|
||||
|
||||
LLVector4a t;
|
||||
m.affineTransform(mVolumeFaces[0].mPositions[0], t);
|
||||
minv = maxv = t;
|
||||
|
||||
for (S32 i = 0; i < (S32)mVolumeFaces.size(); ++i)
|
||||
{
|
||||
LLVolumeFace& face = mVolumeFaces[i];
|
||||
|
||||
for (U32 j = 0; j < (U32)face.mNumVertices; ++j)
|
||||
{
|
||||
m.affineTransform(face.mPositions[j],t);
|
||||
update_min_max(minv, maxv, t);
|
||||
}
|
||||
}
|
||||
|
||||
minv.add(maxv);
|
||||
minv.mul(0.5f);
|
||||
|
||||
ret.set(minv.getF32ptr());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLModel::setNumVolumeFaces(S32 count)
|
||||
{
|
||||
mVolumeFaces.resize(count);
|
||||
@@ -1022,7 +1059,7 @@ void LLModel::setVolumeFaceData(
|
||||
}
|
||||
else
|
||||
{
|
||||
ll_aligned_free_16(face.mNormals);
|
||||
//ll_aligned_free_16(face.mNormals);
|
||||
face.mNormals = NULL;
|
||||
}
|
||||
|
||||
@@ -1033,7 +1070,7 @@ void LLModel::setVolumeFaceData(
|
||||
}
|
||||
else
|
||||
{
|
||||
ll_aligned_free_16(face.mTexCoords);
|
||||
//ll_aligned_free_16(face.mTexCoords);
|
||||
face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
@@ -1232,7 +1269,7 @@ void LLModel::generateNormals(F32 angle_cutoff)
|
||||
}
|
||||
else
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,8 @@ public:
|
||||
void optimizeVolumeFaces();
|
||||
void offsetMesh( const LLVector3& pivotPoint );
|
||||
void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out);
|
||||
|
||||
LLVector3 getTransformedCenter(const LLMatrix4& mat);
|
||||
|
||||
//reorder face list based on mMaterialList in this and reference so
|
||||
//order matches that of reference (material ordering touchup)
|
||||
bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
|
||||
|
||||
@@ -1035,7 +1035,7 @@ void LLShaderMgr::initAttribsAndUniforms()
|
||||
mReservedAttribs.push_back("texcoord3");
|
||||
mReservedAttribs.push_back("diffuse_color");
|
||||
mReservedAttribs.push_back("emissive");
|
||||
mReservedAttribs.push_back("binormal");
|
||||
mReservedAttribs.push_back("tangent");
|
||||
mReservedAttribs.push_back("weight");
|
||||
mReservedAttribs.push_back("weight4");
|
||||
mReservedAttribs.push_back("clothing");
|
||||
|
||||
@@ -342,13 +342,32 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
|
||||
sizeof(LLVector2), // TYPE_TEXCOORD3,
|
||||
sizeof(LLColor4U), // TYPE_COLOR,
|
||||
sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently
|
||||
sizeof(LLVector4), // TYPE_BINORMAL,
|
||||
sizeof(LLVector4), // TYPE_TANGENT,
|
||||
sizeof(F32), // TYPE_WEIGHT,
|
||||
sizeof(LLVector4), // TYPE_WEIGHT4,
|
||||
sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
|
||||
sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
|
||||
};
|
||||
|
||||
static std::string vb_type_name[] =
|
||||
{
|
||||
"TYPE_VERTEX",
|
||||
"TYPE_NORMAL",
|
||||
"TYPE_TEXCOORD0",
|
||||
"TYPE_TEXCOORD1",
|
||||
"TYPE_TEXCOORD2",
|
||||
"TYPE_TEXCOORD3",
|
||||
"TYPE_COLOR",
|
||||
"TYPE_EMISSIVE",
|
||||
"TYPE_TANGENT",
|
||||
"TYPE_WEIGHT",
|
||||
"TYPE_WEIGHT4",
|
||||
"TYPE_CLOTHWEIGHT",
|
||||
"TYPE_TEXTURE_INDEX",
|
||||
"TYPE_MAX",
|
||||
"TYPE_INDEX",
|
||||
};
|
||||
|
||||
U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
|
||||
{
|
||||
GL_TRIANGLES,
|
||||
@@ -523,16 +542,16 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
||||
}
|
||||
}
|
||||
|
||||
if (sLastMask & MAP_BINORMAL)
|
||||
if (sLastMask & MAP_TANGENT)
|
||||
{
|
||||
if (!(data_mask & MAP_BINORMAL))
|
||||
if (!(data_mask & MAP_TANGENT))
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
else if (data_mask & MAP_BINORMAL)
|
||||
else if (data_mask & MAP_TANGENT)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
@@ -1320,7 +1339,7 @@ void LLVertexBuffer::setupVertexArray()
|
||||
2, //TYPE_TEXCOORD3,
|
||||
4, //TYPE_COLOR,
|
||||
4, //TYPE_EMISSIVE,
|
||||
3, //TYPE_BINORMAL,
|
||||
4, //TYPE_TANGENT,
|
||||
1, //TYPE_WEIGHT,
|
||||
4, //TYPE_WEIGHT4,
|
||||
4, //TYPE_CLOTHWEIGHT,
|
||||
@@ -1337,7 +1356,7 @@ void LLVertexBuffer::setupVertexArray()
|
||||
GL_FLOAT, //TYPE_TEXCOORD3,
|
||||
GL_UNSIGNED_BYTE, //TYPE_COLOR,
|
||||
GL_UNSIGNED_BYTE, //TYPE_EMISSIVE,
|
||||
GL_FLOAT, //TYPE_BINORMAL,
|
||||
GL_FLOAT, //TYPE_TANGENT,
|
||||
GL_FLOAT, //TYPE_WEIGHT,
|
||||
GL_FLOAT, //TYPE_WEIGHT4,
|
||||
GL_FLOAT, //TYPE_CLOTHWEIGHT,
|
||||
@@ -1354,7 +1373,7 @@ void LLVertexBuffer::setupVertexArray()
|
||||
false, //TYPE_TEXCOORD3,
|
||||
false, //TYPE_COLOR,
|
||||
false, //TYPE_EMISSIVE,
|
||||
false, //TYPE_BINORMAL,
|
||||
false, //TYPE_TANGENT,
|
||||
false, //TYPE_WEIGHT,
|
||||
false, //TYPE_WEIGHT4,
|
||||
false, //TYPE_CLOTHWEIGHT,
|
||||
@@ -1371,7 +1390,7 @@ void LLVertexBuffer::setupVertexArray()
|
||||
GL_FALSE, //TYPE_TEXCOORD3,
|
||||
GL_TRUE, //TYPE_COLOR,
|
||||
GL_TRUE, //TYPE_EMISSIVE,
|
||||
GL_FALSE, //TYPE_BINORMAL,
|
||||
GL_FALSE, //TYPE_TANGENT,
|
||||
GL_FALSE, //TYPE_WEIGHT,
|
||||
GL_FALSE, //TYPE_WEIGHT4,
|
||||
GL_FALSE, //TYPE_CLOTHWEIGHT,
|
||||
@@ -2033,9 +2052,13 @@ bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index,
|
||||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
|
||||
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range);
|
||||
return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
|
||||
}
|
||||
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
@@ -2308,6 +2331,14 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
|
||||
|
||||
if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
|
||||
{
|
||||
for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i)
|
||||
{
|
||||
U32 mask = 1 << i;
|
||||
if (mask & data_mask && !(mask & mTypeMask))
|
||||
{ //bit set in data_mask, but not set in mTypeMask
|
||||
llwarns << "Missing required component " << vb_type_name[i] << llendl;
|
||||
}
|
||||
}
|
||||
llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
|
||||
}
|
||||
|
||||
@@ -2337,11 +2368,11 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
|
||||
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
|
||||
glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
|
||||
}
|
||||
if (data_mask & MAP_BINORMAL)
|
||||
if (data_mask & MAP_TANGENT)
|
||||
{
|
||||
S32 loc = TYPE_BINORMAL;
|
||||
void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]);
|
||||
glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr);
|
||||
S32 loc = TYPE_TANGENT;
|
||||
void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
|
||||
glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD0)
|
||||
{
|
||||
@@ -2419,10 +2450,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
|
||||
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_BINORMAL)
|
||||
if (data_mask & MAP_TANGENT)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD0)
|
||||
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
TYPE_TEXCOORD3,
|
||||
TYPE_COLOR,
|
||||
TYPE_EMISSIVE,
|
||||
TYPE_BINORMAL,
|
||||
TYPE_TANGENT,
|
||||
TYPE_WEIGHT,
|
||||
TYPE_WEIGHT4,
|
||||
TYPE_CLOTHWEIGHT,
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
MAP_COLOR = (1<<TYPE_COLOR),
|
||||
MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
|
||||
// These use VertexAttribPointer and should possibly be made generic
|
||||
MAP_BINORMAL = (1<<TYPE_BINORMAL),
|
||||
MAP_TANGENT = (1<<TYPE_TANGENT),
|
||||
MAP_WEIGHT = (1<<TYPE_WEIGHT),
|
||||
MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
|
||||
MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
|
||||
@@ -251,7 +251,8 @@ public:
|
||||
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
|
||||
@@ -30,7 +30,7 @@ ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
ATTRIBUTE vec3 binormal;
|
||||
ATTRIBUTE vec4 tangent;
|
||||
|
||||
VARYING vec3 vary_mat0;
|
||||
VARYING vec3 vary_mat1;
|
||||
@@ -52,8 +52,8 @@ void main()
|
||||
|
||||
|
||||
vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
|
||||
vec3 b = normalize((mat * vec4(binormal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
|
||||
vec3 t = cross(b, n);
|
||||
vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
|
||||
vec3 b = cross(n, t) * tangent.w;
|
||||
|
||||
vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
|
||||
@@ -31,7 +31,7 @@ ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
ATTRIBUTE vec3 binormal;
|
||||
ATTRIBUTE vec4 tangent;
|
||||
|
||||
VARYING vec3 vary_mat0;
|
||||
VARYING vec3 vary_mat1;
|
||||
@@ -46,8 +46,8 @@ void main()
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
vec3 n = normalize(normal_matrix * normal);
|
||||
vec3 b = normalize(normal_matrix * binormal);
|
||||
vec3 t = cross(b, n);
|
||||
vec3 t = normalize(normal_matrix * tangent.xyz);
|
||||
vec3 b = cross(n, t) * tangent.w;
|
||||
|
||||
vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
|
||||
@@ -2093,7 +2093,6 @@ uniform sampler2D diffuseMap;
|
||||
uniform vec2 rcp_screen_res;
|
||||
uniform vec4 rcp_frame_opt;
|
||||
uniform vec4 rcp_frame_opt2;
|
||||
uniform vec2 screen_res;
|
||||
VARYING vec2 vary_fragcoord;
|
||||
VARYING vec2 vary_tc;
|
||||
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
uniform mat3 normal_matrix;
|
||||
|
||||
ATTRIBUTE vec3 binormal;
|
||||
ATTRIBUTE vec4 tangent;
|
||||
|
||||
VARYING vec4 binormal_out;
|
||||
VARYING vec4 tangent_out;
|
||||
|
||||
void main()
|
||||
{
|
||||
binormal_out = vec4(normal_matrix * binormal, 0.0);
|
||||
tangent_out = vec4(normal_matrix * tangent.xyz, tangent.w);
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ public:
|
||||
RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_BINORMAL |
|
||||
LLVertexBuffer::MAP_TANGENT |
|
||||
LLVertexBuffer::MAP_COLOR |
|
||||
LLVertexBuffer::MAP_WEIGHT4,
|
||||
RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |
|
||||
|
||||
@@ -851,7 +851,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
|
||||
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
|
||||
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
|
||||
|
||||
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
|
||||
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
|
||||
|
||||
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
|
||||
{
|
||||
|
||||
@@ -511,7 +511,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
|
||||
{
|
||||
LLGLEnable poly_offset(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.f,-1.f);
|
||||
mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
mVertexBuffer->setBuffer(mVertexBuffer->getTypeMask());
|
||||
mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
|
||||
}
|
||||
|
||||
@@ -789,6 +789,12 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
|
||||
size.mul(scale);
|
||||
}
|
||||
|
||||
// Catch potential badness from normalization before it happens
|
||||
//
|
||||
llassert(mat_normal.mMatrix[0].isFinite3() && (mat_normal.mMatrix[0].dot3(mat_normal.mMatrix[0]).getF32() > F_APPROXIMATELY_ZERO));
|
||||
llassert(mat_normal.mMatrix[1].isFinite3() && (mat_normal.mMatrix[1].dot3(mat_normal.mMatrix[1]).getF32() > F_APPROXIMATELY_ZERO));
|
||||
llassert(mat_normal.mMatrix[2].isFinite3() && (mat_normal.mMatrix[2].dot3(mat_normal.mMatrix[2]).getF32() > F_APPROXIMATELY_ZERO));
|
||||
|
||||
mat_normal.mMatrix[0].normalize3fast();
|
||||
mat_normal.mMatrix[1].normalize3fast();
|
||||
mat_normal.mMatrix[2].normalize3fast();
|
||||
@@ -874,7 +880,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
|
||||
// integrated with getGeometryVolume() for its texture coordinate
|
||||
// generation - but i'll leave that to someone more familiar
|
||||
// with the implications.
|
||||
LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal)
|
||||
LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal)
|
||||
{
|
||||
LLVector2 tc = surface_coord;
|
||||
|
||||
@@ -894,7 +900,9 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,
|
||||
LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);
|
||||
|
||||
LLVector4a volume_position;
|
||||
volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV);
|
||||
LLVector3 v_position(position.getF32ptr());
|
||||
|
||||
volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV);
|
||||
|
||||
if (!mDrawablep->getVOVolume()->isVolumeGlobal())
|
||||
{
|
||||
@@ -904,7 +912,8 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,
|
||||
}
|
||||
|
||||
LLVector4a volume_normal;
|
||||
volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV);
|
||||
LLVector3 v_normal(normal.getF32ptr());
|
||||
volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV);
|
||||
volume_normal.normalize3fast();
|
||||
|
||||
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
|
||||
@@ -937,7 +946,12 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po
|
||||
const LLMatrix4& vol_mat = getWorldMatrix();
|
||||
const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
|
||||
const LLVector4a& normal4a = vf.mNormals[0];
|
||||
const LLVector4a& binormal4a = vf.mBinormals[0];
|
||||
const LLVector4a& tangent = vf.mTangents[0];
|
||||
|
||||
LLVector4a binormal4a;
|
||||
binormal4a.setCross3(normal4a, tangent);
|
||||
binormal4a.mul(tangent.getF32ptr()[3]);
|
||||
|
||||
LLVector2 projected_binormal;
|
||||
planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);
|
||||
projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform()
|
||||
@@ -1067,7 +1081,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
|
||||
{
|
||||
LLFastTimer t(FTM_FACE_GEOM_VOLUME);
|
||||
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL;
|
||||
LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;
|
||||
|
||||
if (vf.mWeights)
|
||||
{
|
||||
@@ -1080,11 +1094,11 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
|
||||
buff->allocateBuffer(vf.mNumVertices, 0, true);
|
||||
|
||||
LLStrider<LLVector4a> f_vert;
|
||||
LLStrider<LLVector3> f_binorm;
|
||||
LLStrider<LLVector4a> f_tangent;
|
||||
LLStrider<LLVector3> f_norm;
|
||||
LLStrider<LLVector2> f_tc;
|
||||
|
||||
buff->getBinormalStrider(f_binorm);
|
||||
buff->getTangentStrider(f_tangent);
|
||||
buff->getVertexStrider(f_vert);
|
||||
buff->getNormalStrider(f_norm);
|
||||
buff->getTexCoord0Strider(f_tc);
|
||||
@@ -1092,7 +1106,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
|
||||
for (U32 i = 0; i < (U32)vf.mNumVertices; ++i)
|
||||
{
|
||||
*f_vert++ = vf.mPositions[i];
|
||||
(*f_binorm++).set(vf.mBinormals[i].getF32ptr());
|
||||
*f_tangent++ = vf.mTangents[i];
|
||||
*f_tc++ = vf.mTexCoords[i];
|
||||
(*f_norm++).set(vf.mNormals[i].getF32ptr());
|
||||
}
|
||||
@@ -1133,7 +1147,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TEXTURE("Texture");
|
||||
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");
|
||||
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");
|
||||
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights");
|
||||
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal");
|
||||
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TANGENT("Binormal");
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK("Face Feedback");
|
||||
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_POSITION("Feedback Position");
|
||||
@@ -1207,7 +1221,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
LLStrider<LLVector2> tex_coords1;
|
||||
LLStrider<LLVector3> norm;
|
||||
LLStrider<LLColor4U> colors;
|
||||
LLStrider<LLVector3> binorm;
|
||||
LLStrider<LLVector3> tangent;
|
||||
LLStrider<U16> indicesp;
|
||||
LLStrider<LLVector4> wght;
|
||||
|
||||
@@ -1229,7 +1243,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);
|
||||
bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
|
||||
bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
|
||||
bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL);
|
||||
bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);
|
||||
bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);
|
||||
|
||||
const LLTextureEntry *tep = mVObjp->getTE(f);
|
||||
@@ -1374,7 +1388,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
|
||||
{
|
||||
mVObjp->getVolume()->genBinormals(f);
|
||||
mVObjp->getVolume()->genTangents(f);
|
||||
LLFace::cacheFaceInVRAM(vf);
|
||||
buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
|
||||
}
|
||||
@@ -1459,15 +1473,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
glEndTransformFeedback();
|
||||
}
|
||||
|
||||
if (rebuild_binormal)
|
||||
if (rebuild_tangent)
|
||||
{
|
||||
LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_BINORMAL);
|
||||
gTransformBinormalProgram.bind();
|
||||
LLFastTimer t(FTM_FACE_GEOM_TANGENT);
|
||||
gTransformTangentProgram.bind();
|
||||
|
||||
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount);
|
||||
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);
|
||||
|
||||
glBeginTransformFeedback(GL_POINTS);
|
||||
buff->setBuffer(LLVertexBuffer::MAP_BINORMAL);
|
||||
buff->setBuffer(LLVertexBuffer::MAP_TANGENT);
|
||||
push_for_transform(buff, vf.mNumVertices, mGeomCount);
|
||||
glEndTransformFeedback();
|
||||
}
|
||||
@@ -1529,7 +1543,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
if (bump_code)
|
||||
{
|
||||
mVObjp->getVolume()->genBinormals(f);
|
||||
mVObjp->getVolume()->genTangents(f);
|
||||
F32 offset_multiple;
|
||||
switch( bump_code )
|
||||
{
|
||||
@@ -1578,7 +1592,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
U8 texgen = getTextureEntry()->getTexGen();
|
||||
if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
|
||||
{ //planar texgen needs binormals
|
||||
mVObjp->getVolume()->genBinormals(f);
|
||||
mVObjp->getVolume()->genTangents(f);
|
||||
}
|
||||
|
||||
U8 tex_mode = 0;
|
||||
@@ -1789,11 +1803,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector4a tangent;
|
||||
tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]);
|
||||
LLVector4a tangent = vf.mTangents[i];
|
||||
|
||||
LLVector4a binorm;
|
||||
binorm.setCross3(vf.mNormals[i], tangent);
|
||||
binorm.mul(tangent.getF32ptr()[3]);
|
||||
|
||||
LLMatrix4a tangent_to_object;
|
||||
tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]);
|
||||
tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]);
|
||||
LLVector4a t;
|
||||
tangent_to_object.rotate(binormal_dir, t);
|
||||
LLVector4a binormal;
|
||||
@@ -1899,7 +1916,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
LLFastTimer t(FTM_FACE_GEOM_NORMAL);
|
||||
mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
|
||||
F32* normals = (F32*) norm.get();
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector4a normal;
|
||||
@@ -1915,19 +1931,27 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
}
|
||||
}
|
||||
|
||||
if (rebuild_binormal)
|
||||
if (rebuild_tangent)
|
||||
{
|
||||
LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
|
||||
mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
|
||||
F32* binormals = (F32*) binorm.get();
|
||||
|
||||
LLFastTimer t(FTM_FACE_GEOM_TANGENT);
|
||||
mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
|
||||
F32* tangents = (F32*) tangent.get();
|
||||
|
||||
mVObjp->getVolume()->genTangents(f);
|
||||
|
||||
LLVector4Logical mask;
|
||||
mask.clear();
|
||||
mask.setElement<3>();
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector4a binormal;
|
||||
mat_normal.rotate(vf.mBinormals[i], binormal);
|
||||
binormal.normalize3fast();
|
||||
binormal.store4a(binormals);
|
||||
binormals += 4;
|
||||
{
|
||||
LLVector4a tangent_out;
|
||||
mat_normal.rotate(vf.mTangents[i], tangent_out);
|
||||
tangent_out.normalize3fast();
|
||||
tangent_out.setSelectWithMask(mask, vf.mTangents[i], tangent_out);
|
||||
tangent_out.store4a(tangents);
|
||||
|
||||
tangents += 4;
|
||||
}
|
||||
|
||||
if (map_range)
|
||||
|
||||
@@ -121,7 +121,7 @@ public:
|
||||
LLXformMatrix* getXform() const { return mXform; }
|
||||
BOOL hasGeometry() const { return mGeomCount > 0; }
|
||||
LLVector3 getPositionAgent() const;
|
||||
LLVector2 surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal);
|
||||
LLVector2 surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal);
|
||||
void getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const;
|
||||
bool calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset,
|
||||
LLVector2* st_scale, F32* st_rot) const;
|
||||
|
||||
@@ -293,6 +293,9 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons
|
||||
|
||||
void LLVolumeImplFlexible::updateRenderRes()
|
||||
{
|
||||
if (!mAttributes)
|
||||
return;
|
||||
|
||||
LLDrawable* drawablep = mVO->mDrawable;
|
||||
|
||||
S32 new_res = mAttributes->getSimulateLOD();
|
||||
@@ -424,7 +427,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
if(!mInitialized)
|
||||
if(!mInitialized || !mAttributes)
|
||||
{
|
||||
//the object is not visible
|
||||
return ;
|
||||
@@ -682,15 +685,17 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
|
||||
new_point = &path->mPath[i];
|
||||
LLVector3 pos = newSection[i].mPosition * rel_xform;
|
||||
LLQuaternion rot = mSection[i].mAxisRotation * newSection[i].mRotation * delta_rot;
|
||||
|
||||
if (!mUpdated || (new_point->mPos-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f)
|
||||
|
||||
LLVector3 np(new_point->mPos.getF32ptr());
|
||||
|
||||
if (!mUpdated || (np-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f)
|
||||
{
|
||||
new_point->mPos = newSection[i].mPosition * rel_xform;
|
||||
new_point->mPos.load3((newSection[i].mPosition * rel_xform).mV);
|
||||
mUpdated = FALSE;
|
||||
}
|
||||
|
||||
new_point->mRot = rot;
|
||||
new_point->mScale = newSection[i].mScale;
|
||||
new_point->mRot.loadu(LLMatrix3(rot));
|
||||
new_point->mScale.set(newSection[i].mScale.mV[0], newSection[i].mScale.mV[1], 0,1);
|
||||
new_point->mTexT = ((F32)i)/(num_render_sections);
|
||||
}
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ void LLHUDIcon::render()
|
||||
renderIcon(FALSE);
|
||||
}
|
||||
|
||||
BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection)
|
||||
BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
|
||||
{
|
||||
if (mHidden)
|
||||
return FALSE;
|
||||
@@ -281,23 +281,18 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
|
||||
LLVector4a upper_right;
|
||||
upper_right.setAdd(lower_right, y_scalea);
|
||||
|
||||
LLVector4a enda;
|
||||
enda.load3(end.mV);
|
||||
LLVector4a starta;
|
||||
starta.load3(start.mV);
|
||||
LLVector4a dir;
|
||||
dir.setSub(enda, starta);
|
||||
dir.setSub(end, start);
|
||||
|
||||
F32 a,b,t;
|
||||
|
||||
if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, a,b,t) ||
|
||||
LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, a,b,t))
|
||||
if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, a,b,t) ||
|
||||
LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, a,b,t))
|
||||
{
|
||||
if (intersection)
|
||||
{
|
||||
dir.mul(t);
|
||||
starta.add(dir);
|
||||
*intersection = LLVector3(starta.getF32ptr());
|
||||
intersection->setAdd(start, dir);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -337,12 +332,12 @@ LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)
|
||||
}
|
||||
|
||||
//static
|
||||
LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection)
|
||||
LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
|
||||
{
|
||||
icon_instance_t::iterator icon_it;
|
||||
|
||||
LLVector3 local_end = end;
|
||||
LLVector3 position;
|
||||
LLVector4a local_end = end;
|
||||
LLVector4a position;
|
||||
|
||||
LLHUDIcon* ret = NULL;
|
||||
for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
static S32 generatePickIDs(S32 start_id, S32 step_size);
|
||||
static LLHUDIcon* handlePick(S32 pick_id);
|
||||
static LLHUDIcon* lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection);
|
||||
static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);
|
||||
|
||||
static void updateAll();
|
||||
static void cleanupDeadIcons();
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
BOOL getHidden() const { return mHidden; }
|
||||
void setHidden( BOOL hide ) { mHidden = hide; }
|
||||
|
||||
BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection);
|
||||
BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);
|
||||
|
||||
protected:
|
||||
LLHUDIcon(const U8 type);
|
||||
|
||||
@@ -120,7 +120,7 @@ LLHUDNameTag::~LLHUDNameTag()
|
||||
}
|
||||
|
||||
|
||||
BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render)
|
||||
BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render)
|
||||
{
|
||||
if (!mVisible || mHidden)
|
||||
{
|
||||
@@ -218,16 +218,23 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
|
||||
gGL.vertex3fv(v[2].mV);
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
LLVector3 dir = end-start;
|
||||
LLVector4a dir;
|
||||
dir.setSub(end,start);
|
||||
F32 a, b, t;
|
||||
|
||||
if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
|
||||
LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
|
||||
LLVector4a v0,v1,v2,v3;
|
||||
v0.load3(v[0].mV);
|
||||
v1.load3(v[1].mV);
|
||||
v2.load3(v[2].mV);
|
||||
v3.load3(v[3].mV);
|
||||
|
||||
if (LLTriangleRayIntersect(v0, v1, v2, start, dir, a, b, t) ||
|
||||
LLTriangleRayIntersect(v2, v3, v0, start, dir, a, b, t) )
|
||||
{
|
||||
if (t <= 1.f)
|
||||
{
|
||||
intersection = start + dir*t;
|
||||
dir.mul(t);
|
||||
intersection.setAdd(start, dir);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
void setHidden( BOOL hide ) { mHidden = hide; }
|
||||
void shift(const LLVector3& offset);
|
||||
|
||||
BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE);
|
||||
BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render = FALSE);
|
||||
|
||||
static void shiftAll(const LLVector3& offset);
|
||||
static void addPickable(std::set<LLViewerObject*> &pick_list);
|
||||
|
||||
@@ -2944,9 +2944,9 @@ void renderNormals(LLDrawable* drawablep)
|
||||
gGL.vertex3fv(face.mPositions[j].getF32ptr());
|
||||
gGL.vertex3fv(p.getF32ptr());
|
||||
|
||||
if (face.mBinormals)
|
||||
if (face.mTangents)
|
||||
{
|
||||
n.setMul(face.mBinormals[j], scale);
|
||||
n.setMul(face.mTangents[j], scale);
|
||||
p.setAdd(face.mPositions[j], n);
|
||||
|
||||
gGL.diffuseColor4f(0,1,1,1);
|
||||
@@ -3694,11 +3694,17 @@ void renderRaycast(LLDrawable* drawablep)
|
||||
gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
|
||||
gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
|
||||
|
||||
LLVector3 start, end;
|
||||
LLVector4a start, end;
|
||||
if (transform)
|
||||
{
|
||||
start = vobj->agentPositionToVolume(gDebugRaycastStart);
|
||||
end = vobj->agentPositionToVolume(gDebugRaycastEnd);
|
||||
LLVector3 v_start(gDebugRaycastStart.getF32ptr());
|
||||
LLVector3 v_end(gDebugRaycastEnd.getF32ptr());
|
||||
|
||||
v_start = vobj->agentPositionToVolume(v_start);
|
||||
v_end = vobj->agentPositionToVolume(v_end);
|
||||
|
||||
start.load3(v_start.mV);
|
||||
end.load3(v_end.mV);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3706,11 +3712,8 @@ void renderRaycast(LLDrawable* drawablep)
|
||||
end = gDebugRaycastEnd;
|
||||
}
|
||||
|
||||
LLVector4a starta, enda;
|
||||
starta.load3(start.mV);
|
||||
enda.load3(end.mV);
|
||||
LLVector4a dir;
|
||||
dir.setSub(enda, starta);
|
||||
dir.setSub(end, start);
|
||||
|
||||
gGL.flush();
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
@@ -3733,10 +3736,11 @@ void renderRaycast(LLDrawable* drawablep)
|
||||
((LLVolumeFace*) &face)->createOctree();
|
||||
}
|
||||
|
||||
LLRenderOctreeRaycast render(starta, dir, &t);
|
||||
LLRenderOctreeRaycast render(start, dir, &t);
|
||||
|
||||
render.traverse(face.mOctree);
|
||||
}
|
||||
|
||||
gGL.popMatrix();
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
@@ -3757,10 +3761,18 @@ void renderRaycast(LLDrawable* drawablep)
|
||||
// draw intersection point
|
||||
gGL.pushMatrix();
|
||||
gGL.loadMatrix(gGLModelView);
|
||||
LLVector3 translate = gDebugRaycastIntersection;
|
||||
LLVector3 translate(gDebugRaycastIntersection.getF32ptr());
|
||||
gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);
|
||||
LLCoordFrame orient;
|
||||
orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal);
|
||||
LLVector4a debug_binormal;
|
||||
|
||||
debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent);
|
||||
debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]);
|
||||
|
||||
LLVector3 normal(gDebugRaycastNormal.getF32ptr());
|
||||
LLVector3 binormal(debug_binormal.getF32ptr());
|
||||
|
||||
orient.lookDir(normal, binormal);
|
||||
LLMatrix4 rotation;
|
||||
orient.getRotMatrixToParent(rotation);
|
||||
gGL.multMatrix((float*)rotation.mMatrix);
|
||||
@@ -4261,28 +4273,30 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
|
||||
{
|
||||
public:
|
||||
LLVector3 mStart;
|
||||
LLVector3 mEnd;
|
||||
LL_ALIGN_16(LLVector4a mStart);
|
||||
LL_ALIGN_16(LLVector4a mEnd);
|
||||
|
||||
S32 *mFaceHit;
|
||||
LLVector3 *mIntersection;
|
||||
LLVector4a *mIntersection;
|
||||
LLVector2 *mTexCoord;
|
||||
LLVector3 *mNormal;
|
||||
LLVector3 *mBinormal;
|
||||
LLVector4a *mNormal;
|
||||
LLVector4a *mTangent;
|
||||
LLDrawable* mHit;
|
||||
BOOL mPickTransparent;
|
||||
|
||||
LLOctreeIntersect(LLVector3 start, LLVector3 end, BOOL pick_transparent,
|
||||
S32* face_hit, LLVector3* intersection, LLVector2* tex_coord, LLVector3* normal, LLVector3* binormal)
|
||||
LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent,
|
||||
S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
|
||||
: mStart(start),
|
||||
mEnd(end),
|
||||
mFaceHit(face_hit),
|
||||
mIntersection(intersection),
|
||||
mTexCoord(tex_coord),
|
||||
mNormal(normal),
|
||||
mBinormal(binormal),
|
||||
mTangent(tangent),
|
||||
mHit(NULL),
|
||||
mPickTransparent(pick_transparent)
|
||||
{
|
||||
@@ -4315,23 +4329,22 @@ public:
|
||||
size = group->mBounds[1];
|
||||
center = group->mBounds[0];
|
||||
|
||||
LLVector3 local_start = mStart;
|
||||
LLVector3 local_end = mEnd;
|
||||
LLVector4a local_start = mStart;
|
||||
LLVector4a local_end = mEnd;
|
||||
|
||||
if (group->mSpatialPartition->isBridge())
|
||||
{
|
||||
LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix();
|
||||
local_matrix.invert();
|
||||
|
||||
local_start = mStart * local_matrix;
|
||||
local_end = mEnd * local_matrix;
|
||||
|
||||
LLMatrix4a local_matrix4a;
|
||||
local_matrix4a.loadu(local_matrix);
|
||||
|
||||
local_matrix4a.affineTransform(mStart, local_start);
|
||||
local_matrix4a.affineTransform(mEnd, local_end);
|
||||
}
|
||||
|
||||
LLVector4a start, end;
|
||||
start.load3(local_start.mV);
|
||||
end.load3(local_end.mV);
|
||||
|
||||
if (LLLineSegmentBoxIntersect(start, end, center, size))
|
||||
if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))
|
||||
{
|
||||
check(child);
|
||||
}
|
||||
@@ -4362,14 +4375,14 @@ public:
|
||||
|
||||
if (vobj)
|
||||
{
|
||||
LLVector3 intersection;
|
||||
LLVector4a intersection;
|
||||
bool skip_check = false;
|
||||
if (vobj->isAvatar())
|
||||
{
|
||||
LLVOAvatar* avatar = (LLVOAvatar*) vobj;
|
||||
if (avatar->isSelf() && gFloaterTools->getVisible())
|
||||
{
|
||||
LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal);
|
||||
LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
|
||||
if (hit)
|
||||
{
|
||||
mEnd = intersection;
|
||||
@@ -4389,7 +4402,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))
|
||||
if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
|
||||
{
|
||||
mEnd = intersection; // shorten ray so we only find CLOSER hits
|
||||
if (mIntersection)
|
||||
@@ -4404,19 +4417,19 @@ public:
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit, // return the face hit
|
||||
LLVector3* intersection, // return the intersection point
|
||||
LLVector4a* intersection, // return the intersection point
|
||||
LLVector2* tex_coord, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent // return the surface tangent at the intersection point
|
||||
)
|
||||
|
||||
{
|
||||
LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
|
||||
LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
|
||||
LLDrawable* drawable = intersect.check(mOctree);
|
||||
|
||||
return drawable;
|
||||
|
||||
@@ -457,13 +457,13 @@ public:
|
||||
LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);
|
||||
BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp);
|
||||
|
||||
LLDrawable* lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit, // return the face hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
|
||||
|
||||
@@ -695,7 +695,7 @@ class LLVolumeGeometryManager: public LLGeometryManager
|
||||
virtual void rebuildGeom(LLSpatialGroup* group);
|
||||
virtual void rebuildMesh(LLSpatialGroup* group);
|
||||
virtual void getGeometry(LLSpatialGroup* group);
|
||||
void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE);
|
||||
void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);
|
||||
void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
|
||||
};
|
||||
|
||||
|
||||
@@ -3904,19 +3904,19 @@ LLViewerObject* LLViewerObject::getRootEdit() const
|
||||
}
|
||||
|
||||
|
||||
BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit,
|
||||
LLVector3* intersection,
|
||||
LLVector4a* intersection,
|
||||
LLVector2* tex_coord,
|
||||
LLVector3* normal,
|
||||
LLVector3* bi_normal)
|
||||
LLVector4a* normal,
|
||||
LLVector4a* tangent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end)
|
||||
BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end)
|
||||
{
|
||||
if (mDrawable.isNull() || mDrawable->isDead())
|
||||
{
|
||||
@@ -3933,11 +3933,7 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
LLVector4a starta, enda;
|
||||
starta.load3(start.mV);
|
||||
enda.load3(end.mV);
|
||||
|
||||
return LLLineSegmentBoxIntersect(starta, enda, center, size);
|
||||
return LLLineSegmentBoxIntersect(start, end, center, size);
|
||||
}
|
||||
|
||||
U8 LLViewerObject::getMediaType() const
|
||||
|
||||
@@ -262,17 +262,17 @@ public:
|
||||
|
||||
//detect if given line segment (in agent space) intersects with this viewer object.
|
||||
//returns TRUE if intersection detected and returns information about intersection
|
||||
virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
BOOL pick_transparent = FALSE,
|
||||
S32* face_hit = NULL, // which face was hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
|
||||
virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end);
|
||||
virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end);
|
||||
|
||||
virtual const LLVector3d getPositionGlobal() const;
|
||||
virtual const LLVector3 &getPositionRegion() const;
|
||||
|
||||
@@ -77,7 +77,7 @@ LLGLSLShader gTransformPositionProgram(LLViewerShaderMgr::SHADER_TRANSFORM);
|
||||
LLGLSLShader gTransformTexCoordProgram(LLViewerShaderMgr::SHADER_TRANSFORM);
|
||||
LLGLSLShader gTransformNormalProgram(LLViewerShaderMgr::SHADER_TRANSFORM);
|
||||
LLGLSLShader gTransformColorProgram(LLViewerShaderMgr::SHADER_TRANSFORM);
|
||||
LLGLSLShader gTransformBinormalProgram(LLViewerShaderMgr::SHADER_TRANSFORM);
|
||||
LLGLSLShader gTransformTangentProgram(LLViewerShaderMgr::SHADER_TRANSFORM);
|
||||
|
||||
//utility shaders
|
||||
LLGLSLShader gOcclusionProgram(LLViewerShaderMgr::SHADER_INTERFACE);
|
||||
@@ -2747,16 +2747,16 @@ BOOL LLViewerShaderMgr::loadTransformShaders()
|
||||
|
||||
if (success)
|
||||
{
|
||||
gTransformBinormalProgram.mName = "Binormal Transform Shader";
|
||||
gTransformBinormalProgram.mShaderFiles.clear();
|
||||
gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
|
||||
gTransformTangentProgram.mName = "Binormal Transform Shader";
|
||||
gTransformTangentProgram.mShaderFiles.clear();
|
||||
gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gTransformTangentProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
|
||||
|
||||
const char* varyings[] = {
|
||||
"binormal_out",
|
||||
"tangent_out",
|
||||
};
|
||||
|
||||
success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings);
|
||||
success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ extern LLGLSLShader gTransformPositionProgram;
|
||||
extern LLGLSLShader gTransformTexCoordProgram;
|
||||
extern LLGLSLShader gTransformNormalProgram;
|
||||
extern LLGLSLShader gTransformColorProgram;
|
||||
extern LLGLSLShader gTransformBinormalProgram;
|
||||
extern LLGLSLShader gTransformTangentProgram;
|
||||
//utility shaders
|
||||
extern LLGLSLShader gOcclusionProgram;
|
||||
extern LLGLSLShader gOcclusionCubeProgram;
|
||||
@@ -244,7 +244,6 @@ extern LLGLSLShader gSplatTextureRectProgram;
|
||||
extern LLGLSLShader gGlowCombineFXAAProgram;
|
||||
extern LLGLSLShader gDebugProgram;
|
||||
extern LLGLSLShader gClipProgram;
|
||||
extern LLGLSLShader gAlphaMaskProgram;
|
||||
|
||||
//output tex0[tc0] + tex1[tc1]
|
||||
extern LLGLSLShader gTwoTextureAddProgram;
|
||||
|
||||
@@ -218,13 +218,13 @@ BOOL gShowOverlayTitle = FALSE;
|
||||
BOOL gPickTransparent = TRUE;
|
||||
|
||||
LLViewerObject* gDebugRaycastObject = NULL;
|
||||
LLVector3 gDebugRaycastIntersection;
|
||||
LLVector2 gDebugRaycastTexCoord;
|
||||
LLVector3 gDebugRaycastNormal;
|
||||
LLVector3 gDebugRaycastBinormal;
|
||||
S32 gDebugRaycastFaceHit;
|
||||
LLVector3 gDebugRaycastStart;
|
||||
LLVector3 gDebugRaycastEnd;
|
||||
LLVector4a gDebugRaycastIntersection;
|
||||
LLVector2 gDebugRaycastTexCoord;
|
||||
LLVector4a gDebugRaycastNormal;
|
||||
LLVector4a gDebugRaycastTangent;
|
||||
S32 gDebugRaycastFaceHit;
|
||||
LLVector4a gDebugRaycastStart;
|
||||
LLVector4a gDebugRaycastEnd;
|
||||
|
||||
// HUD display lines in lower right
|
||||
BOOL gDisplayWindInfo = FALSE;
|
||||
@@ -3038,7 +3038,7 @@ void LLViewerWindow::updateUI()
|
||||
&gDebugRaycastIntersection,
|
||||
&gDebugRaycastTexCoord,
|
||||
&gDebugRaycastNormal,
|
||||
&gDebugRaycastBinormal,
|
||||
&gDebugRaycastTangent,
|
||||
&gDebugRaycastStart,
|
||||
&gDebugRaycastEnd);
|
||||
}
|
||||
@@ -3982,7 +3982,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans
|
||||
}
|
||||
|
||||
LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
|
||||
LLVector3* intersection)
|
||||
LLVector4a* intersection)
|
||||
{
|
||||
S32 x = mouse_x;
|
||||
S32 y = mouse_y;
|
||||
@@ -3999,9 +3999,11 @@ LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 dep
|
||||
LLVector3 mouse_world_start = mouse_point_global;
|
||||
LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
|
||||
|
||||
return LLHUDIcon::lineSegmentIntersectAll(mouse_world_start, mouse_world_end, intersection);
|
||||
|
||||
LLVector4a start, end;
|
||||
start.load3(mouse_world_start.mV);
|
||||
end.load3(mouse_world_end.mV);
|
||||
|
||||
return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection);
|
||||
}
|
||||
|
||||
LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth,
|
||||
@@ -4009,12 +4011,12 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
|
||||
S32 this_face,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit,
|
||||
LLVector3 *intersection,
|
||||
LLVector4a *intersection,
|
||||
LLVector2 *uv,
|
||||
LLVector3 *normal,
|
||||
LLVector3 *binormal,
|
||||
LLVector3* start,
|
||||
LLVector3* end)
|
||||
LLVector4a *normal,
|
||||
LLVector4a *tangent,
|
||||
LLVector4a* start,
|
||||
LLVector4a* end)
|
||||
{
|
||||
S32 x = mouse_x;
|
||||
S32 y = mouse_y;
|
||||
@@ -4049,17 +4051,27 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
|
||||
if (!LLViewerJoystick::getInstance()->getOverrideCamera())
|
||||
{ //always set raycast intersection to mouse_world_end unless
|
||||
//flycam is on (for DoF effect)
|
||||
gDebugRaycastIntersection = mouse_world_end;
|
||||
gDebugRaycastIntersection.load3(mouse_world_end.mV);
|
||||
}
|
||||
|
||||
LLVector4a mw_start;
|
||||
mw_start.load3(mouse_world_start.mV);
|
||||
LLVector4a mw_end;
|
||||
mw_end.load3(mouse_world_end.mV);
|
||||
|
||||
LLVector4a mh_start;
|
||||
mh_start.load3(mouse_hud_start.mV);
|
||||
LLVector4a mh_end;
|
||||
mh_end.load3(mouse_hud_end.mV);
|
||||
|
||||
if (start)
|
||||
{
|
||||
*start = mouse_world_start;
|
||||
*start = mw_start;
|
||||
}
|
||||
|
||||
if (end)
|
||||
{
|
||||
*end = mouse_world_end;
|
||||
*end = mw_end;
|
||||
}
|
||||
|
||||
LLViewerObject* found = NULL;
|
||||
@@ -4068,25 +4080,25 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
|
||||
{
|
||||
if (this_object->isHUDAttachment()) // is a HUD object?
|
||||
{
|
||||
if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, pick_transparent,
|
||||
face_hit, intersection, uv, normal, binormal))
|
||||
if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent,
|
||||
face_hit, intersection, uv, normal, tangent))
|
||||
{
|
||||
found = this_object;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // is a world object
|
||||
{
|
||||
if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent,
|
||||
face_hit, intersection, uv, normal, binormal))
|
||||
if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent,
|
||||
face_hit, intersection, uv, normal, tangent))
|
||||
{
|
||||
found = this_object;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // check ALL objects
|
||||
{
|
||||
found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent,
|
||||
face_hit, intersection, uv, normal, binormal);
|
||||
found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent,
|
||||
face_hit, intersection, uv, normal, tangent);
|
||||
|
||||
// [RLVa:KB] - Checked: 2009-12-28 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k
|
||||
if ( (rlv_handler_t::isEnabled()) && (LLToolCamera::getInstance()->hasMouseCapture()) && (gKeyboard->currentMask(TRUE) & MASK_ALT) )
|
||||
@@ -4097,8 +4109,8 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
|
||||
|
||||
if (!found) // if not found in HUD, look in world:
|
||||
{
|
||||
found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent,
|
||||
face_hit, intersection, uv, normal, binormal);
|
||||
found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent,
|
||||
face_hit, intersection, uv, normal, tangent);
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
|
||||
#ifdef RLV_EXTENSION_CMD_INTERACT
|
||||
@@ -4118,6 +4130,10 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
|
||||
}
|
||||
#endif // RLV_EXTENSION_CMD_INTERACT
|
||||
// [/RLVa:KB]
|
||||
if (found && !pick_transparent)
|
||||
{
|
||||
gDebugRaycastIntersection = *intersection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5815,6 +5831,7 @@ LLPickInfo::LLPickInfo()
|
||||
mXYCoords(-1, -1),
|
||||
mIntersection(),
|
||||
mNormal(),
|
||||
mTangent(),
|
||||
mBinormal(),
|
||||
mHUDIcon(NULL),
|
||||
mPickTransparent(FALSE)
|
||||
@@ -5836,6 +5853,7 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
|
||||
mSTCoords(-1.f, -1.f),
|
||||
mXYCoords(-1, -1),
|
||||
mNormal(),
|
||||
mTangent(),
|
||||
mBinormal(),
|
||||
mHUDIcon(NULL),
|
||||
mPickTransparent(pick_transparent)
|
||||
@@ -5846,19 +5864,26 @@ void LLPickInfo::fetchResults()
|
||||
{
|
||||
|
||||
S32 face_hit = -1;
|
||||
LLVector3 intersection, normal, binormal;
|
||||
LLVector4a intersection, normal;
|
||||
LLVector4a tangent;
|
||||
|
||||
LLVector2 uv;
|
||||
|
||||
LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection);
|
||||
|
||||
LLVector4a origin;
|
||||
origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
|
||||
F32 icon_dist = 0.f;
|
||||
if (hit_icon)
|
||||
{
|
||||
icon_dist = (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec();
|
||||
LLVector4a delta;
|
||||
delta.setSub(intersection, origin);
|
||||
icon_dist = delta.getLength3().getF32();
|
||||
}
|
||||
|
||||
LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
|
||||
NULL, -1, mPickTransparent, &face_hit,
|
||||
&intersection, &uv, &normal, &binormal);
|
||||
&intersection, &uv, &normal, &tangent);
|
||||
|
||||
mPickPt = mMousePt;
|
||||
|
||||
@@ -5868,9 +5893,13 @@ void LLPickInfo::fetchResults()
|
||||
|
||||
LLViewerObject* objectp = hit_object;
|
||||
|
||||
|
||||
LLVector4a delta;
|
||||
delta.setSub(origin, intersection);
|
||||
|
||||
if (hit_icon &&
|
||||
(!objectp ||
|
||||
icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec()))
|
||||
icon_dist < delta.getLength3().getF32()))
|
||||
{
|
||||
// was this name referring to a hud icon?
|
||||
mHUDIcon = hit_icon;
|
||||
@@ -5907,11 +5936,16 @@ void LLPickInfo::fetchResults()
|
||||
{
|
||||
mPickType = PICK_OBJECT;
|
||||
}
|
||||
mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY);
|
||||
|
||||
LLVector3 v_intersection(intersection.getF32ptr());
|
||||
|
||||
mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY);
|
||||
mObjectID = objectp->mID;
|
||||
mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset;
|
||||
|
||||
mPosGlobal = gAgent.getPosGlobalFromAgent(intersection);
|
||||
|
||||
|
||||
mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection);
|
||||
|
||||
if (mWantSurfaceInfo)
|
||||
{
|
||||
@@ -5955,7 +5989,16 @@ void LLPickInfo::getSurfaceInfo()
|
||||
mIntersection = LLVector3(0,0,0);
|
||||
mNormal = LLVector3(0,0,0);
|
||||
mBinormal = LLVector3(0,0,0);
|
||||
mTangent = LLVector4(0,0,0,0);
|
||||
|
||||
LLVector4a tangent;
|
||||
LLVector4a intersection;
|
||||
LLVector4a normal;
|
||||
|
||||
tangent.clear();
|
||||
normal.clear();
|
||||
intersection.clear();
|
||||
|
||||
LLViewerObject* objectp = getObject();
|
||||
|
||||
if (objectp)
|
||||
@@ -5963,10 +6006,10 @@ void LLPickInfo::getSurfaceInfo()
|
||||
if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f,
|
||||
objectp, -1, mPickTransparent,
|
||||
&mObjectFace,
|
||||
&mIntersection,
|
||||
&intersection,
|
||||
&mSTCoords,
|
||||
&mNormal,
|
||||
&mBinormal))
|
||||
&normal,
|
||||
&tangent))
|
||||
{
|
||||
// if we succeeded with the intersect above, compute the texture coordinates:
|
||||
|
||||
@@ -5975,10 +6018,26 @@ void LLPickInfo::getSurfaceInfo()
|
||||
LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
|
||||
if (facep)
|
||||
{
|
||||
mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
|
||||
mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal);
|
||||
}
|
||||
}
|
||||
|
||||
mIntersection.set(intersection.getF32ptr());
|
||||
mNormal.set(normal.getF32ptr());
|
||||
mTangent.set(tangent.getF32ptr());
|
||||
|
||||
//extrapoloate binormal from normal and tangent
|
||||
|
||||
LLVector4a binormal;
|
||||
binormal.setCross3(normal, tangent);
|
||||
binormal.mul(tangent.getF32ptr()[3]);
|
||||
|
||||
mBinormal.set(binormal.getF32ptr());
|
||||
|
||||
mBinormal.normalize();
|
||||
mNormal.normalize();
|
||||
mTangent.normalize();
|
||||
|
||||
// and XY coords:
|
||||
updateXYCoords();
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
LLVector2 mSTCoords;
|
||||
LLCoordScreen mXYCoords;
|
||||
LLVector3 mNormal;
|
||||
LLVector4 mTangent;
|
||||
LLVector3 mBinormal;
|
||||
BOOL mPickTransparent;
|
||||
void getSurfaceInfo();
|
||||
@@ -347,19 +348,19 @@ public:
|
||||
static void hoverPickCallback(const LLPickInfo& pick_info);
|
||||
|
||||
LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
|
||||
LLVector3* intersection);
|
||||
LLVector4a* intersection);
|
||||
|
||||
LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f,
|
||||
LLViewerObject *this_object = NULL,
|
||||
S32 this_face = -1,
|
||||
BOOL pick_transparent = FALSE,
|
||||
S32* face_hit = NULL,
|
||||
LLVector3 *intersection = NULL,
|
||||
LLVector4a *intersection = NULL,
|
||||
LLVector2 *uv = NULL,
|
||||
LLVector3 *normal = NULL,
|
||||
LLVector3 *binormal = NULL,
|
||||
LLVector3* start = NULL,
|
||||
LLVector3* end = NULL);
|
||||
LLVector4a *normal = NULL,
|
||||
LLVector4a *tangent = NULL,
|
||||
LLVector4a* start = NULL,
|
||||
LLVector4a* end = NULL);
|
||||
|
||||
|
||||
// Returns a pointer to the last object hit
|
||||
@@ -509,13 +510,13 @@ extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar awa
|
||||
extern LLFrameTimer gAwayTriggerTimer; // how long the avatar has been away
|
||||
|
||||
extern LLViewerObject* gDebugRaycastObject;
|
||||
extern LLVector3 gDebugRaycastIntersection;
|
||||
extern LLVector4a gDebugRaycastIntersection;
|
||||
extern LLVector2 gDebugRaycastTexCoord;
|
||||
extern LLVector3 gDebugRaycastNormal;
|
||||
extern LLVector3 gDebugRaycastBinormal;
|
||||
extern LLVector4a gDebugRaycastNormal;
|
||||
extern LLVector4a gDebugRaycastTangent;
|
||||
extern S32 gDebugRaycastFaceHit;
|
||||
extern LLVector3 gDebugRaycastStart;
|
||||
extern LLVector3 gDebugRaycastEnd;
|
||||
extern LLVector4a gDebugRaycastStart;
|
||||
extern LLVector4a gDebugRaycastEnd;
|
||||
|
||||
extern BOOL gDisplayCameraPos;
|
||||
extern BOOL gDisplayWindInfo;
|
||||
|
||||
@@ -1729,19 +1729,20 @@ void LLVOAvatar::renderCollisionVolumes()
|
||||
|
||||
if (mNameText.notNull())
|
||||
{
|
||||
LLVector3 unused;
|
||||
mNameText->lineSegmentIntersect(LLVector3(0,0,0), LLVector3(0,0,1), unused, TRUE);
|
||||
LLVector4a unused;
|
||||
|
||||
mNameText->lineSegmentIntersect(unused, unused, unused, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit,
|
||||
LLVector3* intersection,
|
||||
LLVector4a* intersection,
|
||||
LLVector2* tex_coord,
|
||||
LLVector3* normal,
|
||||
LLVector3* bi_normal)
|
||||
LLVector4a* normal,
|
||||
LLVector4a* tangent)
|
||||
{
|
||||
if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar)
|
||||
{
|
||||
@@ -1758,8 +1759,8 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
glh::matrix4f inverse = mat.inverse();
|
||||
glh::matrix4f norm_mat = inverse.transpose();
|
||||
|
||||
glh::vec3f p1(start.mV);
|
||||
glh::vec3f p2(end.mV);
|
||||
glh::vec3f p1(start.getF32ptr());
|
||||
glh::vec3f p2(end.getF32ptr());
|
||||
|
||||
inverse.mult_matrix_vec(p1);
|
||||
inverse.mult_matrix_vec(p2);
|
||||
@@ -1778,12 +1779,12 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
|
||||
if (intersection)
|
||||
{
|
||||
*intersection = LLVector3(res_pos.v);
|
||||
intersection->load3(res_pos.v);
|
||||
}
|
||||
|
||||
if (normal)
|
||||
{
|
||||
*normal = LLVector3(res_norm.v);
|
||||
normal->load3(res_norm.v);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -1817,7 +1818,8 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
}
|
||||
}
|
||||
|
||||
LLVector3 position;
|
||||
|
||||
LLVector4a position;
|
||||
if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position))
|
||||
{
|
||||
if (intersection)
|
||||
@@ -1831,14 +1833,14 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end,
|
||||
LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit,
|
||||
LLVector3* intersection,
|
||||
LLVector4a* intersection,
|
||||
LLVector2* tex_coord,
|
||||
LLVector3* normal,
|
||||
LLVector3* bi_normal)
|
||||
LLVector4a* normal,
|
||||
LLVector4a* tangent)
|
||||
{
|
||||
static const LLCachedControl<bool> allow_mesh_picking("SGAllowRiggedMeshSelection");
|
||||
|
||||
@@ -1851,8 +1853,8 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
|
||||
|
||||
if (lineSegmentBoundingBox(start, end))
|
||||
{
|
||||
LLVector3 local_end = end;
|
||||
LLVector3 local_intersection;
|
||||
LLVector4a local_end = end;
|
||||
LLVector4a local_intersection;
|
||||
|
||||
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
|
||||
iter != mAttachmentPoints.end();
|
||||
@@ -1866,7 +1868,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
|
||||
{
|
||||
LLViewerObject* attached_object = (*attachment_iter);
|
||||
|
||||
if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal))
|
||||
if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, tangent))
|
||||
{
|
||||
local_end = local_intersection;
|
||||
if (intersection)
|
||||
|
||||
@@ -201,22 +201,22 @@ public:
|
||||
/*virtual*/ void updateRegion(LLViewerRegion *regionp);
|
||||
/*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);
|
||||
/*virtual*/ void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
BOOL pick_transparent = FALSE,
|
||||
S32* face_hit = NULL, // which face was hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
|
||||
LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end,
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL); // return the surface tangent at the intersection point
|
||||
LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
BOOL pick_transparent = FALSE,
|
||||
S32* face_hit = NULL, // which face was hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL); // return the surface tangent at the intersection point
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// LLCharacter interface and related
|
||||
|
||||
@@ -789,8 +789,8 @@ void LLVOGrass::updateDrawable(BOOL force_damped)
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
|
||||
LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
|
||||
BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
|
||||
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
|
||||
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
@@ -801,7 +801,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLVector3 dir = end-start;
|
||||
LLVector4a dir;
|
||||
dir.setSub(end, start);
|
||||
|
||||
mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
|
||||
|
||||
@@ -869,23 +870,31 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
|
||||
|
||||
U32 idx0 = 0,idx1 = 0,idx2 = 0;
|
||||
|
||||
if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE))
|
||||
LLVector4a v0a,v1a,v2a,v3a;
|
||||
|
||||
v0a.load3(v[0].mV);
|
||||
v1a.load3(v[1].mV);
|
||||
v2a.load3(v[2].mV);
|
||||
v3a.load3(v[3].mV);
|
||||
|
||||
|
||||
if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t))
|
||||
{
|
||||
hit = TRUE;
|
||||
idx0 = 0; idx1 = 1; idx2 = 2;
|
||||
}
|
||||
else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a, b, t, FALSE))
|
||||
else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t))
|
||||
{
|
||||
hit = TRUE;
|
||||
idx0 = 1; idx1 = 3; idx2 = 2;
|
||||
}
|
||||
else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, a, b, t, FALSE))
|
||||
else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t))
|
||||
{
|
||||
normal1 = -normal1;
|
||||
hit = TRUE;
|
||||
idx0 = 2; idx1 = 1; idx2 = 0;
|
||||
}
|
||||
else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, a, b, t, FALSE))
|
||||
else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t))
|
||||
{
|
||||
normal1 = -normal1;
|
||||
hit = TRUE;
|
||||
@@ -908,7 +917,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
|
||||
closest_t = t;
|
||||
if (intersection != NULL)
|
||||
{
|
||||
*intersection = start+dir*closest_t;
|
||||
dir.mul(closest_t);
|
||||
intersection->setAdd(start, dir);
|
||||
}
|
||||
|
||||
if (tex_coord != NULL)
|
||||
@@ -918,7 +928,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
|
||||
|
||||
if (normal != NULL)
|
||||
{
|
||||
*normal = normal1;
|
||||
normal->load3(normal1.mV);
|
||||
}
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
@@ -81,14 +81,14 @@ public:
|
||||
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
|
||||
/*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
|
||||
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
BOOL pick_transparent = FALSE,
|
||||
S32* face_hit = NULL, // which face was hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
|
||||
static S32 sMaxGrassSpecies;
|
||||
|
||||
@@ -103,10 +103,10 @@ public:
|
||||
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_BINORMAL)
|
||||
if (data_mask & MAP_TANGENT)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD0)
|
||||
@@ -942,8 +942,8 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
|
||||
LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
|
||||
BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
|
||||
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
|
||||
|
||||
{
|
||||
|
||||
@@ -952,7 +952,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLVector3 delta = end-start;
|
||||
LLVector4a da;
|
||||
da.setSub(end, start);
|
||||
LLVector3 delta(da.getF32ptr());
|
||||
|
||||
LLVector3 pdelta = delta;
|
||||
pdelta.mV[2] = 0;
|
||||
@@ -961,7 +963,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
|
||||
|
||||
F32 tdelta = 1.f/plength;
|
||||
|
||||
LLVector3 origin = start - mRegionp->getOriginAgent();
|
||||
LLVector3 v_start(start.getF32ptr());
|
||||
|
||||
LLVector3 origin = v_start - mRegionp->getOriginAgent();
|
||||
|
||||
if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])
|
||||
{
|
||||
@@ -1016,12 +1020,12 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
|
||||
{
|
||||
sample.mV[2] = mRegionp->getLandHeightRegion(sample);
|
||||
}
|
||||
*intersection = sample + mRegionp->getOriginAgent();
|
||||
intersection->load3((sample + mRegionp->getOriginAgent()).mV);
|
||||
}
|
||||
|
||||
if (normal)
|
||||
{
|
||||
*normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample));
|
||||
normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -85,14 +85,14 @@ public:
|
||||
void dirtyPatch();
|
||||
void dirtyGeom();
|
||||
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
BOOL pick_transparent = FALSE,
|
||||
S32* face_hit = NULL, // which face was hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
|
||||
BOOL mDirtiedPatch;
|
||||
|
||||
@@ -1253,8 +1253,8 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
|
||||
mDrawable->setPositionGroup(pos);
|
||||
}
|
||||
|
||||
BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
|
||||
LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
|
||||
BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
|
||||
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
|
||||
|
||||
{
|
||||
|
||||
@@ -1283,16 +1283,19 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end
|
||||
|
||||
LLVector3 pos, norm;
|
||||
|
||||
if (linesegment_tetrahedron(start, end, center, size, quat, pos, norm))
|
||||
LLVector3 start3(start.getF32ptr());
|
||||
LLVector3 end3(end.getF32ptr());
|
||||
|
||||
if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm))
|
||||
{
|
||||
if (intersection)
|
||||
{
|
||||
*intersection = pos;
|
||||
intersection->load3(pos.mV);
|
||||
}
|
||||
|
||||
if (normal)
|
||||
{
|
||||
*normal = norm;
|
||||
normal->load3(norm.mV);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -115,14 +115,14 @@ public:
|
||||
U32 drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, F32 alpha);
|
||||
|
||||
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
BOOL pick_transparent = FALSE,
|
||||
S32* face_hit = NULL, // which face was hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
|
||||
static S32 sMaxTreeSpecies;
|
||||
|
||||
@@ -1053,13 +1053,17 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo
|
||||
{ //already cached
|
||||
break;
|
||||
}
|
||||
volume->genBinormals(i);
|
||||
volume->genTangents(i);
|
||||
LLFace::cacheFaceInVRAM(face);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1218,7 +1222,7 @@ BOOL LLVOVolume::calcLOD()
|
||||
else
|
||||
{
|
||||
distance = mDrawable->mDistanceWRTCamera;
|
||||
radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length();
|
||||
radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();
|
||||
}
|
||||
|
||||
|
||||
@@ -3589,8 +3593,8 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
|
||||
}
|
||||
|
||||
|
||||
BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
|
||||
LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
|
||||
BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
|
||||
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
|
||||
|
||||
{
|
||||
if (!mbCanSelect ||
|
||||
@@ -3631,23 +3635,25 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
|
||||
if (volume)
|
||||
{
|
||||
LLVector3 v_start, v_end, v_dir;
|
||||
|
||||
LLVector4a local_start = start;
|
||||
LLVector4a local_end = end;
|
||||
|
||||
if (transform)
|
||||
{
|
||||
v_start = agentPositionToVolume(start);
|
||||
v_end = agentPositionToVolume(end);
|
||||
}
|
||||
else
|
||||
{
|
||||
v_start = start;
|
||||
v_end = end;
|
||||
}
|
||||
LLVector3 v_start(start.getF32ptr());
|
||||
LLVector3 v_end(end.getF32ptr());
|
||||
|
||||
LLVector3 p;
|
||||
LLVector3 n;
|
||||
v_start = agentPositionToVolume(v_start);
|
||||
v_end = agentPositionToVolume(v_end);
|
||||
|
||||
local_start.load3(v_start.mV);
|
||||
local_end.load3(v_end.mV);
|
||||
}
|
||||
|
||||
LLVector4a p;
|
||||
LLVector4a n;
|
||||
LLVector2 tc;
|
||||
LLVector3 bn;
|
||||
LLVector4a tn;
|
||||
|
||||
if (intersection != NULL)
|
||||
{
|
||||
@@ -3664,9 +3670,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
n = *normal;
|
||||
}
|
||||
|
||||
if (bi_normal != NULL)
|
||||
if (tangent != NULL)
|
||||
{
|
||||
bn = *bi_normal;
|
||||
tn = *tangent;
|
||||
}
|
||||
|
||||
S32 face_hit = -1;
|
||||
@@ -3692,8 +3698,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
continue;
|
||||
}
|
||||
|
||||
face_hit = volume->lineSegmentIntersect(v_start, v_end, i,
|
||||
&p, &tc, &n, &bn);
|
||||
face_hit = volume->lineSegmentIntersect(local_start, local_end, i,
|
||||
&p, &tc, &n, &tn);
|
||||
|
||||
if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit)
|
||||
{
|
||||
@@ -3702,7 +3708,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
if (face &&
|
||||
(pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
|
||||
{
|
||||
v_end = p;
|
||||
local_end = p;
|
||||
if (face_hitp != NULL)
|
||||
{
|
||||
*face_hitp = face_hit;
|
||||
@@ -3712,7 +3718,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
{
|
||||
if (transform)
|
||||
{
|
||||
*intersection = volumePositionToAgent(p); // must map back to agent space
|
||||
LLVector3 v_p(p.getF32ptr());
|
||||
|
||||
intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3724,27 +3732,36 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
{
|
||||
if (transform)
|
||||
{
|
||||
*normal = volumeDirectionToAgent(n);
|
||||
LLVector3 v_n(n.getF32ptr());
|
||||
normal->load3(volumeDirectionToAgent(v_n).mV);
|
||||
}
|
||||
else
|
||||
{
|
||||
*normal = n;
|
||||
}
|
||||
|
||||
(*normal).normVec();
|
||||
(*normal).normalize3fast();
|
||||
}
|
||||
|
||||
if (bi_normal != NULL)
|
||||
if (tangent != NULL)
|
||||
{
|
||||
if (transform)
|
||||
{
|
||||
*bi_normal = volumeDirectionToAgent(bn);
|
||||
LLVector3 v_tn(tn.getF32ptr());
|
||||
|
||||
LLVector4a trans_tangent;
|
||||
trans_tangent.load3(volumeDirectionToAgent(v_tn).mV);
|
||||
|
||||
LLVector4Logical mask;
|
||||
mask.clear();
|
||||
mask.setElement<3>();
|
||||
|
||||
tangent->setSelectWithMask(mask, tn, trans_tangent);
|
||||
}
|
||||
else
|
||||
{
|
||||
*bi_normal = bn;
|
||||
*tangent = tn;
|
||||
}
|
||||
(*bi_normal).normVec();
|
||||
(*tangent).normalize3fast();
|
||||
}
|
||||
|
||||
if (tex_coord != NULL)
|
||||
@@ -4262,11 +4279,18 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
|
||||
mFaceList.clear();
|
||||
|
||||
std::vector<LLFace*> fullbright_faces;
|
||||
std::vector<LLFace*> bump_faces;
|
||||
std::vector<LLFace*> simple_faces;
|
||||
const U32 MAX_FACE_COUNT = 4096;
|
||||
|
||||
static LLFace** fullbright_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
|
||||
static LLFace** bump_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
|
||||
static LLFace** simple_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
|
||||
static LLFace** alpha_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
|
||||
|
||||
U32 fullbright_count = 0;
|
||||
U32 bump_count = 0;
|
||||
U32 simple_count = 0;
|
||||
U32 alpha_count = 0;
|
||||
|
||||
std::vector<LLFace*> alpha_faces;
|
||||
U32 useage = group->mSpatialPartition->mBufferUsage;
|
||||
|
||||
static const LLCachedControl<S32> render_max_vbo_size("RenderMaxVBOSize", 512);
|
||||
@@ -4623,7 +4647,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
{
|
||||
if (facep->canRenderAsMask())
|
||||
{ //can be treated as alpha mask
|
||||
simple_faces.push_back(facep);
|
||||
if (simple_count < MAX_FACE_COUNT)
|
||||
{
|
||||
simple_faces[simple_count++] = facep;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4631,7 +4658,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
{ //only treat as alpha in the pipeline if < 100% transparent
|
||||
drawablep->setState(LLDrawable::HAS_ALPHA);
|
||||
}
|
||||
alpha_faces.push_back(facep);
|
||||
if (alpha_count < MAX_FACE_COUNT)
|
||||
{
|
||||
alpha_faces[alpha_count++] = facep;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -4645,34 +4675,52 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
&& LLPipeline::sRenderBump)
|
||||
{
|
||||
if (te->getBumpmap())
|
||||
{ //needs normal + binormal
|
||||
bump_faces.push_back(facep);
|
||||
{ //needs normal + tangent
|
||||
if (bump_count < MAX_FACE_COUNT)
|
||||
{
|
||||
bump_faces[bump_count++] = facep;
|
||||
}
|
||||
}
|
||||
else if (te->getShiny() || !te->getFullbright())
|
||||
{ //needs normal
|
||||
simple_faces.push_back(facep);
|
||||
if (simple_count < MAX_FACE_COUNT)
|
||||
{
|
||||
simple_faces[simple_count++] = facep;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //doesn't need normal
|
||||
facep->setState(LLFace::FULLBRIGHT);
|
||||
fullbright_faces.push_back(facep);
|
||||
if (fullbright_count < MAX_FACE_COUNT)
|
||||
{
|
||||
fullbright_faces[fullbright_count++] = facep;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (te->getBumpmap() && LLPipeline::sRenderBump)
|
||||
{ //needs normal + binormal
|
||||
bump_faces.push_back(facep);
|
||||
{ //needs normal + tangent
|
||||
if (bump_count < MAX_FACE_COUNT)
|
||||
{
|
||||
bump_faces[bump_count++] = facep;
|
||||
}
|
||||
}
|
||||
else if ((te->getShiny() && LLPipeline::sRenderBump) ||
|
||||
!(te->getFullbright() || bake_sunlight))
|
||||
{ //needs normal
|
||||
simple_faces.push_back(facep);
|
||||
if (simple_count < MAX_FACE_COUNT)
|
||||
{
|
||||
simple_faces[simple_count++] = facep;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //doesn't need normal
|
||||
facep->setState(LLFace::FULLBRIGHT);
|
||||
fullbright_faces.push_back(facep);
|
||||
if (fullbright_count < MAX_FACE_COUNT)
|
||||
{
|
||||
fullbright_faces[fullbright_count++] = facep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4714,18 +4762,18 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
|
||||
if (batch_textures)
|
||||
{
|
||||
bump_mask |= LLVertexBuffer::MAP_BINORMAL;
|
||||
genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE);
|
||||
genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE);
|
||||
genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE);
|
||||
genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE);
|
||||
bump_mask |= LLVertexBuffer::MAP_TANGENT;
|
||||
genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, simple_count, FALSE, TRUE);
|
||||
genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, fullbright_count, FALSE, TRUE);
|
||||
genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, bump_count, FALSE, TRUE);
|
||||
genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, alpha_count, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
genDrawInfo(group, simple_mask, simple_faces);
|
||||
genDrawInfo(group, fullbright_mask, fullbright_faces);
|
||||
genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE);
|
||||
genDrawInfo(group, alpha_mask, alpha_faces, TRUE);
|
||||
genDrawInfo(group, simple_mask, simple_faces, simple_count);
|
||||
genDrawInfo(group, fullbright_mask, fullbright_faces, fullbright_count);
|
||||
genDrawInfo(group, bump_mask, bump_faces, bump_count, FALSE, TRUE);
|
||||
genDrawInfo(group, alpha_mask, alpha_faces, alpha_count, TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -4767,13 +4815,17 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
{
|
||||
LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
|
||||
LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers
|
||||
S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ;
|
||||
|
||||
group->mBuilt = 1.f;
|
||||
|
||||
std::set<LLVertexBuffer*> mapped_buffers;
|
||||
|
||||
OctreeGuard guard(group->mOctreeNode);
|
||||
S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ;
|
||||
|
||||
const U32 MAX_BUFFER_COUNT = 4096;
|
||||
static LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
|
||||
|
||||
U32 buffer_count = 0;
|
||||
|
||||
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
|
||||
{
|
||||
LLDrawable* drawablep = *drawable_iter;
|
||||
@@ -4807,9 +4859,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
}
|
||||
|
||||
|
||||
if (buff->isLocked())
|
||||
if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT)
|
||||
{
|
||||
mapped_buffers.insert(buff);
|
||||
locked_buffer[buffer_count++] = buff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4825,7 +4877,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
}
|
||||
}
|
||||
|
||||
for (std::set<LLVertexBuffer*>::iterator iter = mapped_buffers.begin(); iter != mapped_buffers.end(); ++iter)
|
||||
for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
|
||||
{
|
||||
(*iter)->flush();
|
||||
}
|
||||
@@ -4904,7 +4956,7 @@ static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
|
||||
|
||||
|
||||
|
||||
void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)
|
||||
void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
|
||||
{
|
||||
LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
|
||||
|
||||
@@ -4931,17 +4983,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
if (!distance_sort)
|
||||
{
|
||||
//sort faces by things that break batches
|
||||
std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
|
||||
std::sort(faces, faces+face_count, CompareBatchBreakerModified());
|
||||
}
|
||||
else
|
||||
{
|
||||
//sort faces by distance
|
||||
std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
|
||||
std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater());
|
||||
}
|
||||
}
|
||||
|
||||
bool hud_group = group->isHUDGroup() ;
|
||||
std::vector<LLFace*>::iterator face_iter = faces.begin();
|
||||
LLFace** face_iter = faces;
|
||||
LLFace** end_faces = faces+face_count;
|
||||
|
||||
LLSpatialGroup::buffer_map_t buffer_map;
|
||||
|
||||
@@ -4973,7 +5026,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
|
||||
texture_index_channels = llmin(texture_index_channels, 16);
|
||||
|
||||
while (face_iter != faces.end())
|
||||
while (face_iter != end_faces)
|
||||
{
|
||||
//pull off next face
|
||||
LLFace* facep = *face_iter;
|
||||
@@ -4999,11 +5052,15 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
U32 index_count = facep->getIndicesCount();
|
||||
U32 geom_count = facep->getGeomCount();
|
||||
|
||||
|
||||
//sum up vertices needed for this render batch
|
||||
std::vector<LLFace*>::iterator i = face_iter;
|
||||
LLFace** i = face_iter;
|
||||
++i;
|
||||
|
||||
std::vector<LLViewerTexture*> texture_list;
|
||||
const U32 MAX_TEXTURE_COUNT = 32;
|
||||
static LLViewerTexture* texture_list[MAX_TEXTURE_COUNT];
|
||||
|
||||
U32 texture_count = 0;
|
||||
|
||||
{
|
||||
LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE);
|
||||
@@ -5011,11 +5068,15 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
{
|
||||
U8 cur_tex = 0;
|
||||
facep->setTextureIndex(cur_tex);
|
||||
texture_list.push_back(tex);
|
||||
if (texture_count < MAX_TEXTURE_COUNT)
|
||||
{
|
||||
texture_list[texture_count++] = tex;
|
||||
}
|
||||
|
||||
if (can_batch_texture(facep))
|
||||
{
|
||||
while (i != faces.end())
|
||||
{ //populate texture_list with any textures that can be batched
|
||||
//move i to the next unbatchable face
|
||||
while (i != end_faces)
|
||||
{
|
||||
facep = *i;
|
||||
if (!can_batch_texture(facep))
|
||||
@@ -5028,7 +5089,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
if (distance_sort)
|
||||
{ //textures might be out of order, see if texture exists in current batch
|
||||
bool found = false;
|
||||
for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)
|
||||
for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx)
|
||||
{
|
||||
if (facep->getTexture() == texture_list[tex_idx])
|
||||
{
|
||||
@@ -5040,7 +5101,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
|
||||
if (!found)
|
||||
{
|
||||
cur_tex = texture_list.size();
|
||||
cur_tex = texture_count;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -5055,7 +5116,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
|
||||
tex = facep->getTexture();
|
||||
|
||||
texture_list.push_back(tex);
|
||||
if (texture_count < MAX_TEXTURE_COUNT)
|
||||
{
|
||||
texture_list[texture_count++] = tex;
|
||||
}
|
||||
}
|
||||
|
||||
if (geom_count + facep->getGeomCount() > max_vertices)
|
||||
@@ -5074,7 +5138,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
}
|
||||
else
|
||||
{
|
||||
while (i != faces.end() &&
|
||||
while (i != end_faces &&
|
||||
(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
|
||||
{
|
||||
facep = *i;
|
||||
|
||||
@@ -142,14 +142,14 @@ public:
|
||||
|
||||
/*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const;
|
||||
/*virtual*/ U32 getHighLODTriangleCount();
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
BOOL pick_transparent = FALSE,
|
||||
S32* face_hit = NULL, // which face was hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
|
||||
LLVector3 agentPositionToVolume(const LLVector3& pos) const;
|
||||
|
||||
@@ -6167,20 +6167,20 @@ BOOL LLPipeline::getRenderHighlights(void*)
|
||||
return sRenderHighlight;
|
||||
}
|
||||
|
||||
LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
|
||||
LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit,
|
||||
LLVector3* intersection, // return the intersection point
|
||||
LLVector4a* intersection, // return the intersection point
|
||||
LLVector2* tex_coord, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent // return the surface tangent at the intersection point
|
||||
)
|
||||
{
|
||||
LLDrawable* drawable = NULL;
|
||||
|
||||
LLVector3 local_end = end;
|
||||
LLVector4a local_end = end;
|
||||
|
||||
LLVector3 position;
|
||||
LLVector4a position;
|
||||
|
||||
sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE;
|
||||
|
||||
@@ -6200,7 +6200,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
|
||||
LLSpatialPartition* part = region->getSpatialPartition(j);
|
||||
if (part && hasRenderType(part->mDrawableType))
|
||||
{
|
||||
LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
|
||||
LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
|
||||
if (hit)
|
||||
{
|
||||
drawable = hit;
|
||||
@@ -6215,8 +6215,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
|
||||
{
|
||||
//save hit info in case we need to restore
|
||||
//due to attachment override
|
||||
LLVector3 local_normal;
|
||||
LLVector3 local_binormal;
|
||||
LLVector4a local_normal;
|
||||
LLVector4a local_tangent;
|
||||
LLVector2 local_texcoord;
|
||||
S32 local_face_hit = -1;
|
||||
|
||||
@@ -6228,14 +6228,22 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
|
||||
{
|
||||
local_texcoord = *tex_coord;
|
||||
}
|
||||
if (bi_normal)
|
||||
if (tangent)
|
||||
{
|
||||
local_binormal = *bi_normal;
|
||||
local_tangent = *tangent;
|
||||
}
|
||||
else
|
||||
{
|
||||
local_tangent.clear();
|
||||
}
|
||||
if (normal)
|
||||
{
|
||||
local_normal = *normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
local_normal.clear();
|
||||
}
|
||||
|
||||
const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f;
|
||||
|
||||
@@ -6249,12 +6257,15 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
|
||||
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
|
||||
if (part && hasRenderType(part->mDrawableType))
|
||||
{
|
||||
LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
|
||||
LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
|
||||
if (hit)
|
||||
{
|
||||
LLVector4a delta;
|
||||
delta.setSub(position, local_end);
|
||||
|
||||
if (!drawable ||
|
||||
!drawable->getVObj()->isAttachment() ||
|
||||
(position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST)
|
||||
delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)
|
||||
{ //avatar overrides if previously hit drawable is not an attachment or
|
||||
//attachment is far enough away from detected intersection
|
||||
drawable = hit;
|
||||
@@ -6272,9 +6283,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
|
||||
{
|
||||
*tex_coord = local_texcoord;
|
||||
}
|
||||
if (bi_normal)
|
||||
if (tangent)
|
||||
{
|
||||
*bi_normal = local_binormal;
|
||||
*tangent = local_tangent;
|
||||
}
|
||||
if (normal)
|
||||
{
|
||||
@@ -6308,13 +6319,13 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
|
||||
return drawable ? drawable->getVObj().get() : NULL;
|
||||
}
|
||||
|
||||
LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
|
||||
LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit,
|
||||
LLVector3* intersection, // return the intersection point
|
||||
LLVector4a* intersection, // return the intersection point
|
||||
LLVector2* tex_coord, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent // return the surface tangent at the intersection point
|
||||
)
|
||||
{
|
||||
LLDrawable* drawable = NULL;
|
||||
@@ -6334,7 +6345,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co
|
||||
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
|
||||
if (part)
|
||||
{
|
||||
LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
|
||||
LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
|
||||
if (hit)
|
||||
{
|
||||
drawable = hit;
|
||||
@@ -6815,13 +6826,18 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b
|
||||
{
|
||||
if (LLViewerJoystick::getInstance()->getOverrideCamera())
|
||||
{ //focus on point under cursor
|
||||
focus_point = gDebugRaycastIntersection;
|
||||
focus_point.set(gDebugRaycastIntersection.getF32ptr());
|
||||
}
|
||||
else if (gAgentCamera.cameraMouselook())
|
||||
{ //focus on point under mouselook crosshairs
|
||||
LLVector4a result;
|
||||
result.clear();
|
||||
|
||||
gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
|
||||
NULL,
|
||||
&focus_point);
|
||||
NULL,
|
||||
&result);
|
||||
|
||||
focus_point.set(result.getF32ptr());
|
||||
}
|
||||
else if(gAgent.getRegion())
|
||||
{
|
||||
|
||||
@@ -189,21 +189,21 @@ public:
|
||||
void markMeshDirty(LLSpatialGroup* group);
|
||||
|
||||
//get the object between start and end that's closest to start.
|
||||
LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
|
||||
LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit, // return the face hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
LLViewerObject* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
|
||||
LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit, // return the face hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector4a* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
|
||||
// Something about these textures has changed. Dirty them.
|
||||
|
||||
Reference in New Issue
Block a user