From 798d367d54a6c6379ad355bd8345fa40e31e7fe9 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Sat, 6 Sep 2008 18:24:57 -0500 Subject: Second Life viewer sources 1.21.0-RC --- linden/indra/llmath/CMakeLists.txt | 81 +++ linden/indra/llmath/files.lst | 25 - linden/indra/llmath/llcamera.h | 5 +- linden/indra/llmath/llcrc.cpp | 224 --------- linden/indra/llmath/llcrc.h | 73 --- linden/indra/llmath/llline.cpp | 2 + linden/indra/llmath/llmath.h | 52 +- linden/indra/llmath/llmath.vcproj | 348 ------------- linden/indra/llmath/llmath_vc8.vcproj | 488 ------------------ linden/indra/llmath/llmath_vc9.vcproj | 489 ------------------ linden/indra/llmath/llmd5.cpp | 531 ------------------- linden/indra/llmath/llmd5.h | 133 ----- linden/indra/llmath/lloctree.h | 2 +- linden/indra/llmath/llquaternion.cpp | 8 +- linden/indra/llmath/llquaternion.h | 2 +- linden/indra/llmath/llrand.cpp | 176 ------- linden/indra/llmath/llrand.h | 132 ----- linden/indra/llmath/llrect.h | 5 +- linden/indra/llmath/llsdutil_math.cpp | 172 +++++++ linden/indra/llmath/llsphere.cpp | 2 + linden/indra/llmath/lluuid.cpp | 923 ---------------------------------- linden/indra/llmath/lluuid.h | 330 ------------ linden/indra/llmath/llvolume.cpp | 420 +++++++++++----- linden/indra/llmath/llvolume.h | 100 ++-- linden/indra/llmath/llvolumemgr.cpp | 7 +- linden/indra/llmath/llvolumemgr.h | 2 +- linden/indra/llmath/v2math.cpp | 1 + linden/indra/llmath/v2math.h | 14 +- linden/indra/llmath/v3color.h | 4 + linden/indra/llmath/v3dmath.cpp | 6 +- linden/indra/llmath/v3dmath.h | 48 +- linden/indra/llmath/v3math.cpp | 80 ++- linden/indra/llmath/v3math.h | 5 +- linden/indra/llmath/v4color.cpp | 28 +- linden/indra/llmath/v4color.h | 4 +- linden/indra/llmath/v4coloru.cpp | 8 +- linden/indra/llmath/v4coloru.h | 2 +- 37 files changed, 841 insertions(+), 4091 deletions(-) create mode 100644 linden/indra/llmath/CMakeLists.txt delete mode 100644 linden/indra/llmath/files.lst delete mode 100644 linden/indra/llmath/llcrc.cpp delete mode 100644 linden/indra/llmath/llcrc.h delete mode 100644 linden/indra/llmath/llmath.vcproj delete mode 100644 linden/indra/llmath/llmath_vc8.vcproj delete mode 100644 linden/indra/llmath/llmath_vc9.vcproj delete mode 100644 linden/indra/llmath/llmd5.cpp delete mode 100644 linden/indra/llmath/llmd5.h delete mode 100644 linden/indra/llmath/llrand.cpp delete mode 100644 linden/indra/llmath/llrand.h create mode 100644 linden/indra/llmath/llsdutil_math.cpp delete mode 100644 linden/indra/llmath/lluuid.cpp delete mode 100644 linden/indra/llmath/lluuid.h (limited to 'linden/indra/llmath') diff --git a/linden/indra/llmath/CMakeLists.txt b/linden/indra/llmath/CMakeLists.txt new file mode 100644 index 0000000..6a329fa --- /dev/null +++ b/linden/indra/llmath/CMakeLists.txt @@ -0,0 +1,81 @@ +# -*- cmake -*- + +project(llmath) + +include(00-Common) +include(LLCommon) + +include_directories( + ${LLCOMMON_INCLUDE_DIRS} + ) + +set(llmath_SOURCE_FILES + llbboxlocal.cpp + llcamera.cpp + llcoordframe.cpp + llline.cpp + llperlin.cpp + llquaternion.cpp + llrect.cpp + llsphere.cpp + llvolume.cpp + llvolumemgr.cpp + llsdutil_math.cpp + m3math.cpp + m4math.cpp + raytrace.cpp + v2math.cpp + v3color.cpp + v3dmath.cpp + v3math.cpp + v4color.cpp + v4coloru.cpp + v4math.cpp + xform.cpp + ) + +set(llmath_HEADER_FILES + CMakeLists.txt + + camera.h + coordframe.h + llbboxlocal.h + llcamera.h + llcoord.h + llcoordframe.h + llinterp.h + llline.h + llmath.h + lloctree.h + llperlin.h + llplane.h + llquantize.h + llquaternion.h + llrect.h + llsphere.h + lltreenode.h + llv4math.h + llv4matrix3.h + llv4matrix4.h + llv4vector3.h + llvolume.h + llvolumemgr.h + m3math.h + m4math.h + raytrace.h + v2math.h + v3color.h + v3dmath.h + v3math.h + v4color.h + v4coloru.h + v4math.h + xform.h + ) + +set_source_files_properties(${llmath_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) + +add_library (llmath ${llmath_SOURCE_FILES}) diff --git a/linden/indra/llmath/files.lst b/linden/indra/llmath/files.lst deleted file mode 100644 index 1001a6d..0000000 --- a/linden/indra/llmath/files.lst +++ /dev/null @@ -1,25 +0,0 @@ -llmath/llbboxlocal.cpp -llmath/llcamera.cpp -llmath/llcoordframe.cpp -llmath/llcrc.cpp -llmath/llline.cpp -llmath/llmd5.cpp -llmath/llperlin.cpp -llmath/llquaternion.cpp -llmath/llrand.cpp -llmath/llrect.cpp -llmath/llsphere.cpp -llmath/lluuid.cpp -llmath/llvolume.cpp -llmath/llvolumemgr.cpp -llmath/m3math.cpp -llmath/m4math.cpp -llmath/raytrace.cpp -llmath/v2math.cpp -llmath/v3color.cpp -llmath/v3dmath.cpp -llmath/v3math.cpp -llmath/v4color.cpp -llmath/v4coloru.cpp -llmath/v4math.cpp -llmath/xform.cpp diff --git a/linden/indra/llmath/llcamera.h b/linden/indra/llmath/llcamera.h index 7066b9f..2884338 100644 --- a/linden/indra/llmath/llcamera.h +++ b/linden/indra/llmath/llcamera.h @@ -115,11 +115,12 @@ protected: LLPlane mWorldPlanes[PLANE_NUM]; LLPlane mHorizPlanes[HORIZ_PLANE_NUM]; - typedef struct + struct frustum_plane { + frustum_plane() : mask(0) {} LLPlane p; U8 mask; - } frustum_plane; + }; frustum_plane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in diff --git a/linden/indra/llmath/llcrc.cpp b/linden/indra/llmath/llcrc.cpp deleted file mode 100644 index 447521a..0000000 --- a/linden/indra/llmath/llcrc.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file llcrc.cpp - * @brief implementation of the crc class. - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llcrc.h" -#include "llerror.h" - -/* Copyright (C) 1986 Gary S. Brown. You may use this program, or - code or tables extracted from it, as desired without restriction.*/ - -/* First, the polynomial itself and its table of feedback terms. The */ -/* polynomial is */ -/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ -/* Note that we take it "backwards" and put the highest-order term in */ -/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ -/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ -/* the MSB being 1. */ - -/* Note that the usual hardware shift register implementation, which */ -/* is what we're using (we're merely optimizing it by doing eight-bit */ -/* chunks at a time) shifts bits into the lowest-order term. In our */ -/* implementation, that means shifting towards the right. Why do we */ -/* do it this way? Because the calculated CRC must be transmitted in */ -/* order from highest-order term to lowest-order term. UARTs transmit */ -/* characters in order from LSB to MSB. By storing the CRC this way, */ -/* we hand it to the UART in the order low-byte to high-byte; the UART */ -/* sends each low-bit to hight-bit; and the result is transmission bit */ -/* by bit from highest- to lowest-order term without requiring any bit */ -/* shuffling on our part. Reception works similarly. */ - -/* The feedback terms table consists of 256, 32-bit entries. Notes: */ -/* */ -/* 1. The table can be generated at runtime if desired; code to do so */ -/* is shown later. It might not be obvious, but the feedback */ -/* terms simply represent the results of eight shift/xor opera- */ -/* tions for all combinations of data and CRC register values. */ -/* */ -/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ -/* be they sixteen or thirty-two bits wide. You simply choose the */ -/* appropriate table. Alternatively, because the table can be */ -/* generated at runtime, you can start by generating the table for */ -/* the polynomial in question and use exactly the same "updcrc", */ -/* if your application needn't simultaneously handle two CRC */ -/* polynomials. (Note, however, that XMODEM is strange.) */ -/* */ -/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ -/* of course, 32-bit entries work OK if the high 16 bits are zero. */ -/* */ -/* 4. The values must be right-shifted by eight bits by the "updcrc" */ -/* logic; the shift must be unsigned (bring in zeroes). On some */ -/* hardware you could probably optimize the shift in assembler by */ -/* using byte-swap instructions. */ - -///---------------------------------------------------------------------------- -/// Local function declarations, constants, enums, and typedefs -///---------------------------------------------------------------------------- - -#define UPDC32(octet,crc) (crc_32_tab[((crc) \ - ^ ((U8)octet)) & 0xff] ^ ((crc) >> 8)) - - -static U32 crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ -0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, -0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, -0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, -0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, -0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, -0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, -0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, -0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, -0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, -0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, -0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, -0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, -0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, -0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, -0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, -0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, -0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, -0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, -0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, -0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, -0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, -0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, -0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, -0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, -0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, -0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, -0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, -0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, -0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, -0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, -0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, -0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, -0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, -0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, -0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, -0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, -0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, -0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, -0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, -0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, -0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, -0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, -0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - - -///---------------------------------------------------------------------------- -/// Class llcrc -///---------------------------------------------------------------------------- - -// Default constructor -LLCRC::LLCRC() : mCurrent(0xffffffff) -{ -} - - -U32 LLCRC::getCRC() const -{ - return ~mCurrent; -} - -void LLCRC::update(U8 next_byte) -{ - mCurrent = UPDC32(next_byte, mCurrent); -} - -void LLCRC::update(const U8* buffer, size_t buffer_size) -{ - for (size_t i = 0; i < buffer_size; i++) - { - mCurrent = UPDC32(buffer[i], mCurrent); - } -} - -void LLCRC::update(const char* filename) -{ - if (!filename) - { - llerrs << "No filename specified" << llendl; - return; - } - - LLFILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ - - if (fp) - { - fseek(fp, 0, SEEK_END); - long size = ftell(fp); - - fseek(fp, 0, SEEK_SET); - - if (size > 0) - { - U8* data = new U8[size]; - size_t nread; - - nread = fread(data, 1, size, fp); - fclose(fp); - - if (nread < (size_t) size) - { - llwarns << "Short read on " << filename << llendl; - } - - update(data, nread); - delete[] data; - } - } -} - - -#ifdef _DEBUG -BOOL LLCRC::testHarness() -{ - const S32 TEST_BUFFER_SIZE = 16; - const char TEST_BUFFER[TEST_BUFFER_SIZE] = "hello &#$)$&Nd0"; /* Flawfinder: ignore */ - LLCRC c1, c2; - c1.update((U8*)TEST_BUFFER, TEST_BUFFER_SIZE - 1); - char* rh = (char*)TEST_BUFFER; - while(*rh != '\0') - { - c2.update(*rh); - ++rh; - } - return(c1.getCRC() == c2.getCRC()); -} -#endif - - - -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- diff --git a/linden/indra/llmath/llcrc.h b/linden/indra/llmath/llcrc.h deleted file mode 100644 index 59f58ce..0000000 --- a/linden/indra/llmath/llcrc.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file llcrc.h - * @brief LLCRC class header file. - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLCRC_H -#define LL_LLCRC_H - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class llcrc -// -// Simple 32 bit crc. To use, instantiate an LLCRC instance and feed -// it the bytes you want to check. It will update the internal crc as -// you go, and you can qery it at the end. As a horribly inefficient -// example (don't try this at work kids): -// -// LLCRC crc; -// LLFILE* fp = LLFile::fopen(filename,"rb"); -// while(!feof(fp)) { -// crc.update(fgetc(fp)); -// } -// fclose(fp); -// llinfos << "File crc: " << crc.getCRC() << llendl; -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLCRC -{ -protected: - U32 mCurrent; - -public: - LLCRC(); - - U32 getCRC() const; - void update(U8 next_byte); - void update(const U8* buffer, size_t buffer_size); - void update(const char *filename); - -#ifdef _DEBUG - // This function runs tests to make sure the crc is - // working. Returns TRUE if it is. - static BOOL testHarness(); -#endif -}; - - -#endif // LL_LLCRC_H diff --git a/linden/indra/llmath/llline.cpp b/linden/indra/llmath/llline.cpp index 9c41efb..cfd3f56 100644 --- a/linden/indra/llmath/llline.cpp +++ b/linden/indra/llmath/llline.cpp @@ -20,6 +20,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llline.h" #include "llrand.h" diff --git a/linden/indra/llmath/llmath.h b/linden/indra/llmath/llmath.h index 4a6358d..82ab197 100644 --- a/linden/indra/llmath/llmath.h +++ b/linden/indra/llmath/llmath.h @@ -33,9 +33,10 @@ #define LLMATH_H #include -//#include -//#include +#include #include "lldefs.h" +#include "llstl.h" // *TODO: Remove when LLString is gone +#include "llstring.h" // *TODO: Remove when LLString is gone // work around for Windows & older gcc non-standard function names. #if LL_WINDOWS @@ -93,6 +94,9 @@ const F32 F_APPROXIMATELY_ZERO = 0.00001f; const F32 F_LN2 = 0.69314718056f; const F32 OO_LN2 = 1.4426950408889634073599246810019f; +const F32 F_ALMOST_ZERO = 0.0001f; +const F32 F_ALMOST_ONE = 1.0f - F_ALMOST_ZERO; + // BUG: Eliminate in favor of F_APPROXIMATELY_ZERO above? const F32 FP_MAG_THRESHOLD = 0.0000001f; @@ -102,13 +106,13 @@ inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < inline BOOL is_approx_equal(F32 x, F32 y) { const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02; - return (abs((S32) ((U32&)x - (U32&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); + return (std::abs((S32) ((U32&)x - (U32&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); } inline BOOL is_approx_equal(F64 x, F64 y) { const S64 COMPARE_MANTISSA_UP_TO_BIT = 0x02; - return (abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); + return (std::abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); } inline BOOL is_approx_equal_fraction(F32 x, F32 y, U32 frac_bits) @@ -155,17 +159,17 @@ inline BOOL is_approx_equal_fraction(F64 x, F64 y, U32 frac_bits) inline S32 llabs(const S32 a) { - return S32(labs(a)); + return S32(std::labs(a)); } inline F32 llabs(const F32 a) { - return F32(fabs(a)); + return F32(std::fabs(a)); } inline F64 llabs(const F64 a) { - return F64(fabs(a)); + return F64(std::fabs(a)); } inline S32 lltrunc( F32 f ) @@ -473,8 +477,8 @@ inline F32 llsimple_angle(F32 angle) return angle; } -//calculate the nearesr power of two number for val, bounded by max_power_two -inline U32 get_nearest_power_two(U32 val, U32 max_power_two) +//SDK - Renamed this to get_lower_power_two, since this is what this actually does. +inline U32 get_lower_power_two(U32 val, U32 max_power_two) { if(!max_power_two) { @@ -489,4 +493,34 @@ inline U32 get_nearest_power_two(U32 val, U32 max_power_two) return max_power_two ; } + +// calculate next highest power of two, limited by max_power_two +// This is taken from a brilliant little code snipped on http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html +// Basically we convert the binary to a solid string of 1's with the same +// number of digits, then add one. We subtract 1 initially to handle +// the case where the number passed in is actually a power of two. +// WARNING: this only works with 32 bit ints. +inline U32 get_next_power_two(U32 val, U32 max_power_two) +{ + if(!max_power_two) + { + max_power_two = 1 << 31 ; + } + + if(val >= max_power_two) + { + return max_power_two; + } + + val--; + val = (val >> 1) | val; + val = (val >> 2) | val; + val = (val >> 4) | val; + val = (val >> 8) | val; + val = (val >> 16) | val; + val++; + + return val; +} + #endif diff --git a/linden/indra/llmath/llmath.vcproj b/linden/indra/llmath/llmath.vcproj deleted file mode 100644 index d05505e..0000000 --- a/linden/indra/llmath/llmath.vcproj +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/linden/indra/llmath/llmath_vc8.vcproj b/linden/indra/llmath/llmath_vc8.vcproj deleted file mode 100644 index 3b4413a..0000000 --- a/linden/indra/llmath/llmath_vc8.vcproj +++ /dev/null @@ -1,488 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/linden/indra/llmath/llmath_vc9.vcproj b/linden/indra/llmath/llmath_vc9.vcproj deleted file mode 100644 index 03bc780..0000000 --- a/linden/indra/llmath/llmath_vc9.vcproj +++ /dev/null @@ -1,489 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/linden/indra/llmath/llmd5.cpp b/linden/indra/llmath/llmd5.cpp deleted file mode 100644 index ea69002..0000000 --- a/linden/indra/llmath/llmd5.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/** - * @file llmd5.cpp - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -// llMD5.CC - source code for the C++/object oriented translation and -// modification of MD5. -// -// Adapted to Linden Lab by Frank Filipanits, 6/25/2002 -// Fixed potential memory leak, James Cook, 6/27/2002 - -// Translation and modification (c) 1995 by Mordechai T. Abzug - -// This translation/ modification is provided "as is," without express or -// implied warranty of any kind. - -// The translator/ modifier does not claim (1) that MD5 will do what you think -// it does; (2) that this translation/ modification is accurate; or (3) that -// this software is "merchantible." (Language for this disclaimer partially -// copied from the disclaimer below). - -/* based on: - - MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm - MDDRIVER.C - test driver for MD2, MD4 and MD5 - - - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - - */ - - - - - -#include "linden_common.h" - -#include "llmd5.h" - -#include - -// how many bytes to grab at a time when checking files -const int LLMD5::BLOCK_LEN = 4096; - - -// LLMD5 simple initialization method - -LLMD5::LLMD5() -{ - init(); -} - - - - -// MD5 block update operation. Continues an MD5 message-digest -// operation, processing another message block, and updating the -// context. - -void LLMD5::update (const uint1 *input, const uint4 input_length) { - - uint4 input_index, buffer_index; - uint4 buffer_space; // how much space is left in buffer - - if (finalized){ // so we can't update! - std::cerr << "LLMD5::update: Can't update a finalized digest!" << std::endl; - return; - } - - // Compute number of bytes mod 64 - buffer_index = (unsigned int)((count[0] >> 3) & 0x3F); - - // Update number of bits - if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) ) - count[1]++; - - count[1] += ((uint4)input_length >> 29); - - - buffer_space = 64 - buffer_index; // how much space is left in buffer - - // Transform as many times as possible. - if (input_length >= buffer_space) { // ie. we have enough to fill the buffer - // fill the rest of the buffer and transform - memcpy( /* Flawfinder: ignore */ - buffer + buffer_index, - input, - buffer_space); - transform (buffer); - - // now, transform each 64-byte piece of the input, bypassing the buffer - if (input == NULL || input_length == 0){ - std::cerr << "LLMD5::update: Invalid input!" << std::endl; - return; - } - - for (input_index = buffer_space; input_index + 63 < input_length; - input_index += 64) - transform (input+input_index); - - buffer_index = 0; // so we can buffer remaining - } - else - input_index=0; // so we can buffer the whole input - - - // and here we do the buffering: - memcpy(buffer+buffer_index, input+input_index, input_length-input_index); /* Flawfinder: ignore */ -} - - - -// MD5 update for files. -// Like above, except that it works on files (and uses above as a primitive.) - -void LLMD5::update(LLFILE* file){ - - unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */ - int len; - - while ( (len=(int)fread(buffer, 1, BLOCK_LEN, file)) ) - update(buffer, len); - - fclose (file); - -} - - - - - - -// MD5 update for istreams. -// Like update for files; see above. - -void LLMD5::update(std::istream& stream){ - - unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */ - int len; - - while (stream.good()){ - stream.read( (char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable. - len=stream.gcount(); - update(buffer, len); - } - -} - - - - - -// MD5 finalization. Ends an MD5 message-digest operation, writing the -// the message digest and zeroizing the context. - - -void LLMD5::finalize (){ - - unsigned char bits[8]; /* Flawfinder: ignore */ - unsigned int index, padLen; - static uint1 PADDING[64]={ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - if (finalized){ - std::cerr << "LLMD5::finalize: Already finalized this digest!" << std::endl; - return; - } - - // Save number of bits - encode (bits, count, 8); - - // Pad out to 56 mod 64. - index = (uint4) ((count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - update (PADDING, padLen); - - // Append length (before padding) - update (bits, 8); - - // Store state in digest - encode (digest, state, 16); - - // Zeroize sensitive information - memset (buffer, 0, sizeof(*buffer)); - - finalized=1; - -} - - - - -LLMD5::LLMD5(LLFILE *file){ - - init(); // must be called be all constructors - update(file); - finalize (); -} - - - - -LLMD5::LLMD5(std::istream& stream){ - - init(); // must called by all constructors - update (stream); - finalize(); -} - -// Digest a string of the format ("%s:%i" % (s, number)) -LLMD5::LLMD5(const unsigned char *string, const unsigned int number) -{ - const char *colon = ":"; - char tbuf[16]; /* Flawfinder: ignore */ - init(); - update(string, (U32)strlen((const char *) string)); /* Flawfinder: ignore */ - update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ - snprintf(tbuf, sizeof(tbuf), "%i", number); /* Flawfinder: ignore */ - update((const unsigned char *) tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */ - finalize(); -} - -// Digest a string -LLMD5::LLMD5(const unsigned char *s) -{ - init(); - update(s, (U32)strlen((const char *) s)); /* Flawfinder: ignore */ - finalize(); -} - -void LLMD5::raw_digest(unsigned char *s) -{ - if (!finalized) - { - std::cerr << "LLMD5::raw_digest: Can't get digest if you haven't "<< - "finalized the digest!" << std::endl; - s[0] = '\0'; - return; - } - - memcpy(s, digest, 16); /* Flawfinder: ignore */ - return; -} - - - -void LLMD5::hex_digest(char *s) -{ - int i; - - if (!finalized) - { - std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't "<< - "finalized the digest!" <> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (U32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (U32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (U32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (U32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - - - -// LLMD5 basic transformation. Transforms state based on block. -void LLMD5::transform (const U8 block[64]){ - - uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - decode (x, block, 64); - - assert(!finalized); // not just a user error, since the method is private - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - // Zeroize sensitive information. - memset ( (uint1 *) x, 0, sizeof(x)); - -} - - - -// Encodes input (UINT4) into output (unsigned char). Assumes len is -// a multiple of 4. -void LLMD5::encode (uint1 *output, const uint4 *input, const uint4 len) { - - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (uint1) (input[i] & 0xff); - output[j+1] = (uint1) ((input[i] >> 8) & 0xff); - output[j+2] = (uint1) ((input[i] >> 16) & 0xff); - output[j+3] = (uint1) ((input[i] >> 24) & 0xff); - } -} - - - - -// Decodes input (unsigned char) into output (UINT4). Assumes len is -// a multiple of 4. -void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){ - - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | - (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); -} diff --git a/linden/indra/llmath/llmd5.h b/linden/indra/llmath/llmd5.h deleted file mode 100644 index 9ba0a9f..0000000 --- a/linden/indra/llmath/llmd5.h +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @file llmd5.h - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLMD5_H -#define LL_LLMD5_H - -// LLMD5.CC - source code for the C++/object oriented translation and -// modification of MD5. - -// Translation and modification (c) 1995 by Mordechai T. Abzug - -// This translation/ modification is provided "as is," without express or -// implied warranty of any kind. - -// The translator/ modifier does not claim (1) that MD5 will do what you think -// it does; (2) that this translation/ modification is accurate; or (3) that -// this software is "merchantible." (Language for this disclaimer partially -// copied from the disclaimer below). - -/* based on: - - MD5.H - header file for MD5C.C - MDDRIVER.C - test driver for MD2, MD4 and MD5 - - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - -*/ - -// use for the raw digest output -const int MD5RAW_BYTES = 16; - -// use for outputting hex digests -const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null -const int MD5HEX_STR_BYTES = 32; // message system fixed size - -class LLMD5 { -// first, some types: - typedef unsigned int uint4; // assumes integer is 4 words long - typedef unsigned short int uint2; // assumes short integer is 2 words long - typedef unsigned char uint1; // assumes char is 1 word long - -// how many bytes to grab at a time when checking files - static const int BLOCK_LEN; - -public: -// methods for controlled operation: - LLMD5 (); // simple initializer - void update (const uint1 *input, const uint4 input_length); - void update (std::istream& stream); - void update (LLFILE *file); - void finalize (); - -// constructors for special circumstances. All these constructors finalize -// the MD5 context. - LLMD5 (const unsigned char *string); // digest string, finalize - LLMD5 (std::istream& stream); // digest stream, finalize - LLMD5 (LLFILE *file); // digest file, close, finalize - LLMD5 (const unsigned char *string, const unsigned int number); - -// methods to acquire finalized result - void raw_digest(unsigned char *array); // provide 16-byte array for binary data - void hex_digest(char *string); // provide 33-byte array for ascii-hex string - friend std::ostream& operator<< (std::ostream&, LLMD5 context); - - - -private: - - -// next, the private data: - uint4 state[4]; - uint4 count[2]; // number of *bits*, mod 2^64 - uint1 buffer[64]; // input buffer - uint1 digest[16]; - uint1 finalized; - -// last, the private methods, mostly static: - void init (); // called by all constructors - void transform (const uint1 *buffer); // does the real update work. Note - // that length is implied to be 64. - - static void encode (uint1 *dest, const uint4 *src, const uint4 length); - static void decode (uint4 *dest, const uint1 *src, const uint4 length); - -}; - -#endif // LL_LLMD5_H diff --git a/linden/indra/llmath/lloctree.h b/linden/indra/llmath/lloctree.h index e26bae5..57b359f 100644 --- a/linden/indra/llmath/lloctree.h +++ b/linden/indra/llmath/lloctree.h @@ -37,7 +37,7 @@ #include #include -#ifdef LL_RELEASE_FOR_DOWNLOAD +#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG #define OCT_ERRS LL_WARNS("OctreeErrors") #else #define OCT_ERRS LL_ERRS("OctreeErrors") diff --git a/linden/indra/llmath/llquaternion.cpp b/linden/indra/llmath/llquaternion.cpp index ab4855b..9eab8ed 100644 --- a/linden/indra/llmath/llquaternion.cpp +++ b/linden/indra/llmath/llquaternion.cpp @@ -791,7 +791,7 @@ LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) const char *OrderToString( const LLQuaternion::Order order ) { - char *p = NULL; + const char *p = NULL; switch( order ) { default: @@ -937,15 +937,15 @@ void LLQuaternion::unpackFromVector3( const LLVector3& vec ) } } -BOOL LLQuaternion::parseQuat(const char* buf, LLQuaternion* value) +BOOL LLQuaternion::parseQuat(const std::string& buf, LLQuaternion* value) { - if( buf == NULL || buf[0] == '\0' || value == NULL) + if( buf.empty() || value == NULL) { return FALSE; } LLQuaternion quat; - S32 count = sscanf( buf, "%f %f %f %f", quat.mQ + 0, quat.mQ + 1, quat.mQ + 2, quat.mQ + 3 ); + S32 count = sscanf( buf.c_str(), "%f %f %f %f", quat.mQ + 0, quat.mQ + 1, quat.mQ + 2, quat.mQ + 3 ); if( 4 == count ) { value->set( quat ); diff --git a/linden/indra/llmath/llquaternion.h b/linden/indra/llmath/llquaternion.h index 048db2d..1eb982e 100644 --- a/linden/indra/llmath/llquaternion.h +++ b/linden/indra/llmath/llquaternion.h @@ -158,7 +158,7 @@ public: friend const char *OrderToString( const Order order ); friend Order StringToOrder( const char *str ); - static BOOL parseQuat(const char* buf, LLQuaternion* value); + static BOOL parseQuat(const std::string& buf, LLQuaternion* value); // For debugging, only //static U32 mMultCount; diff --git a/linden/indra/llmath/llrand.cpp b/linden/indra/llmath/llrand.cpp deleted file mode 100644 index bc8c867..0000000 --- a/linden/indra/llmath/llrand.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @file llrand.cpp - * @brief Global random generator. - * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llrand.h" -#include "lluuid.h" - -/** - * Through analysis, we have decided that we want to take values which - * are close enough to 1.0 to map back to 0.0. We came to this - * conclusion from noting that: - * - * [0.0, 1.0) - * - * when scaled to the integer set: - * - * [0, 4) - * - * there is some value close enough to 1.0 that when multiplying by 4, - * gets truncated to 4. Therefore: - * - * [0,1-eps] => 0 - * [1,2-eps] => 1 - * [2,3-eps] => 2 - * [3,4-eps] => 3 - * - * So 0 gets uneven distribution if we simply clamp. The actual - * clamp utilized in this file is to map values out of range back - * to 0 to restore uniform distribution. - * - * Also, for clamping floats when asking for a distribution from - * [0.0,g) we have determined that for values of g < 0.5, then - * rand*g=g, which is not the desired result. As above, we clamp to 0 - * to restore uniform distribution. - */ - -// *NOTE: The system rand implementation is probably not correct. -#define LL_USE_SYSTEM_RAND 0 - -#if LL_USE_SYSTEM_RAND -#include -#endif - -#if LL_USE_SYSTEM_RAND -class LLSeedRand -{ -public: - LLSeedRand() - { -#if LL_WINDOWS - srand(LLUUID::getRandomSeed()); -#else - srand48(LLUUID::getRandomSeed()); -#endif - } -}; -static LLSeedRand sRandomSeeder; -inline F64 ll_internal_random_double() -{ -#if LL_WINDOWS - return (F64)rand() / (F64)RAND_MAX; -#else - return drand48(); -#endif -} -inline F32 ll_internal_random_float() -{ -#if LL_WINDOWS - return (F32)rand() / (F32)RAND_MAX; -#else - return (F32)drand48(); -#endif -} -#else -static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed()); -inline F64 ll_internal_random_double() -{ - // *HACK: Through experimentation, we have found that dual core - // CPUs (or at least multi-threaded processes) seem to - // occasionally give an obviously incorrect random number -- like - // 5^15 or something. Sooooo, clamp it as described above. - F64 rv = gRandomGenerator(); - if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0); - return rv; -} - -inline F32 ll_internal_random_float() -{ - // The clamping rules are described above. - F32 rv = (F32)gRandomGenerator(); - if(!((rv >= 0.0f) && (rv < 1.0f))) return fmod(rv, 1.f); - return rv; -} -#endif - -S32 ll_rand() -{ - return ll_rand(RAND_MAX); -} - -S32 ll_rand(S32 val) -{ - // The clamping rules are described above. - S32 rv = (S32)(ll_internal_random_double() * val); - if(rv == val) return 0; - return rv; -} - -F32 ll_frand() -{ - return ll_internal_random_float(); -} - -F32 ll_frand(F32 val) -{ - // The clamping rules are described above. - F32 rv = ll_internal_random_float() * val; - if(val > 0) - { - if(rv >= val) return 0.0f; - } - else - { - if(rv <= val) return 0.0f; - } - return rv; -} - -F64 ll_drand() -{ - return ll_internal_random_double(); -} - -F64 ll_drand(F64 val) -{ - // The clamping rules are described above. - F64 rv = ll_internal_random_double() * val; - if(val > 0) - { - if(rv >= val) return 0.0; - } - else - { - if(rv <= val) return 0.0; - } - return rv; -} diff --git a/linden/indra/llmath/llrand.h b/linden/indra/llmath/llrand.h deleted file mode 100644 index 0a28213..0000000 --- a/linden/indra/llmath/llrand.h +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @file llrand.h - * @brief Information, functions, and typedefs for randomness. - * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLRAND_H -#define LL_LLRAND_H - -#include -#include - -/** - * Use the boost random number generators if you want a stateful - * random numbers. If you want more random numbers, use the - * c-functions since they will generate faster/better randomness - * across the process. - * - * I tested some of the boost random engines, and picked a good double - * generator and a good integer generator. I also took some timings - * for them on linux using gcc 3.3.5. The harness also did some other - * fairly trivial operations to try to limit compiler optimizations, - * so these numbers are only good for relative comparisons. - * - * usec/inter algorithm - * 0.21 boost::minstd_rand0 - * 0.039 boost:lagged_fibonacci19937 - * 0.036 boost:lagged_fibonacci607 - * 0.44 boost::hellekalek1995 - * 0.44 boost::ecuyer1988 - * 0.042 boost::rand48 - * 0.043 boost::mt11213b - * 0.028 stdlib random() - * 0.05 stdlib lrand48() - * 0.034 stdlib rand() - * 0.020 the old & lame LLRand - */ - -/** - *@brief Generate a float from [0, RAND_MAX). - */ -S32 ll_rand(); - -/** - *@brief Generate a float from [0, val) or (val, 0]. - */ -S32 ll_rand(S32 val); - -/** - *@brief Generate a float from [0, 1.0). - */ -F32 ll_frand(); - -/** - *@brief Generate a float from [0, val) or (val, 0]. - */ -F32 ll_frand(F32 val); - -/** - *@brief Generate a double from [0, 1.0). - */ -F64 ll_drand(); - -/** - *@brief Generate a double from [0, val) or (val, 0]. - */ -F64 ll_drand(F64 val); - -/** - * @brief typedefs for good boost lagged fibonacci. - * @see boost::lagged_fibonacci - * - * These generators will quickly generate doubles. Note the memory - * requirements, because they are somewhat high. I chose the smallest - * one, and one comparable in speed but higher periodicity without - * outrageous memory requirements. - * To use: - * LLRandLagFib607 foo((U32)time(NULL)); - * double bar = foo(); - */ - -typedef boost::lagged_fibonacci607 LLRandLagFib607; -/**< - * lengh of cycle: 2^32,000 - * memory: 607*sizeof(double) (about 5K) - */ - -typedef boost::lagged_fibonacci2281 LLRandLagFib2281; -/**< - * lengh of cycle: 2^120,000 - * memory: 2281*sizeof(double) (about 17K) - */ - -/** - * @breif typedefs for a good boost mersenne twister implementation. - * @see boost::mersenne_twister - * - * This fairly quickly generates U32 values - * To use: - * LLRandMT19937 foo((U32)time(NULL)); - * U32 bar = foo(); - * - * lengh of cycle: 2^19,937-1 - * memory: about 2496 bytes - */ -typedef boost::mt11213b LLRandMT19937; -#endif diff --git a/linden/indra/llmath/llrect.h b/linden/indra/llmath/llrect.h index f2a5d75..ebe5d83 100644 --- a/linden/indra/llmath/llrect.h +++ b/linden/indra/llmath/llrect.h @@ -183,10 +183,11 @@ public: LLRectBase& setCenterAndSize(Type x, Type y, Type width, Type height) { + // width and height could be odd, so favor top, right with extra pixel mLeft = x - width/2; - mTop = y + height/2; - mRight = x + width/2; mBottom = y - height/2; + mTop = mBottom + height; + mRight = mLeft + width; return *this; } diff --git a/linden/indra/llmath/llsdutil_math.cpp b/linden/indra/llmath/llsdutil_math.cpp new file mode 100644 index 0000000..5b72875 --- /dev/null +++ b/linden/indra/llmath/llsdutil_math.cpp @@ -0,0 +1,172 @@ +/** + * @file llsdutil_math.cpp + * @author Phoenix + * @date 2006-05-24 + * @brief Implementation of classes, functions, etc, for using structured data. + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llsdutil.h" + +#include "v3math.h" +#include "v4math.h" +#include "v3dmath.h" +#include "v2math.h" +#include "llquaternion.h" +#include "v4color.h" + +#if LL_WINDOWS +# define WIN32_LEAN_AND_MEAN +# include // for htonl +#elif LL_LINUX || LL_SOLARIS +# include +#elif LL_DARWIN +# include +#endif + +#include "llsdserialize.h" + +// vector3 +LLSD ll_sd_from_vector3(const LLVector3& vec) +{ + LLSD rv; + rv.append((F64)vec.mV[VX]); + rv.append((F64)vec.mV[VY]); + rv.append((F64)vec.mV[VZ]); + return rv; +} + +LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index) +{ + LLVector3 rv; + rv.mV[VX] = (F32)sd[start_index].asReal(); + rv.mV[VY] = (F32)sd[++start_index].asReal(); + rv.mV[VZ] = (F32)sd[++start_index].asReal(); + return rv; +} + +// vector4 +LLSD ll_sd_from_vector4(const LLVector4& vec) +{ + LLSD rv; + rv.append((F64)vec.mV[VX]); + rv.append((F64)vec.mV[VY]); + rv.append((F64)vec.mV[VZ]); + rv.append((F64)vec.mV[VW]); + return rv; +} + +LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index) +{ + LLVector4 rv; + rv.mV[VX] = (F32)sd[start_index].asReal(); + rv.mV[VY] = (F32)sd[++start_index].asReal(); + rv.mV[VZ] = (F32)sd[++start_index].asReal(); + rv.mV[VW] = (F32)sd[++start_index].asReal(); + return rv; +} + +// vector3d +LLSD ll_sd_from_vector3d(const LLVector3d& vec) +{ + LLSD rv; + rv.append(vec.mdV[VX]); + rv.append(vec.mdV[VY]); + rv.append(vec.mdV[VZ]); + return rv; +} + +LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index) +{ + LLVector3d rv; + rv.mdV[VX] = sd[start_index].asReal(); + rv.mdV[VY] = sd[++start_index].asReal(); + rv.mdV[VZ] = sd[++start_index].asReal(); + return rv; +} + +//vector2 +LLSD ll_sd_from_vector2(const LLVector2& vec) +{ + LLSD rv; + rv.append((F64)vec.mV[VX]); + rv.append((F64)vec.mV[VY]); + return rv; +} + +LLVector2 ll_vector2_from_sd(const LLSD& sd) +{ + LLVector2 rv; + rv.mV[VX] = (F32)sd[0].asReal(); + rv.mV[VY] = (F32)sd[1].asReal(); + return rv; +} + +// Quaternion +LLSD ll_sd_from_quaternion(const LLQuaternion& quat) +{ + LLSD rv; + rv.append((F64)quat.mQ[VX]); + rv.append((F64)quat.mQ[VY]); + rv.append((F64)quat.mQ[VZ]); + rv.append((F64)quat.mQ[VW]); + return rv; +} + +LLQuaternion ll_quaternion_from_sd(const LLSD& sd) +{ + LLQuaternion quat; + quat.mQ[VX] = (F32)sd[0].asReal(); + quat.mQ[VY] = (F32)sd[1].asReal(); + quat.mQ[VZ] = (F32)sd[2].asReal(); + quat.mQ[VW] = (F32)sd[3].asReal(); + return quat; +} + +// color4 +LLSD ll_sd_from_color4(const LLColor4& c) +{ + LLSD rv; + rv.append(c.mV[0]); + rv.append(c.mV[1]); + rv.append(c.mV[2]); + rv.append(c.mV[3]); + return rv; +} + +LLColor4 ll_color4_from_sd(const LLSD& sd) +{ + LLColor4 c; + c.mV[0] = (F32)sd[0].asReal(); + c.mV[1] = (F32)sd[1].asReal(); + c.mV[2] = (F32)sd[2].asReal(); + c.mV[3] = (F32)sd[3].asReal(); + return c; +} diff --git a/linden/indra/llmath/llsphere.cpp b/linden/indra/llmath/llsphere.cpp index 62f6e27..f253b6c 100644 --- a/linden/indra/llmath/llsphere.cpp +++ b/linden/indra/llmath/llsphere.cpp @@ -20,6 +20,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llsphere.h" LLSphere::LLSphere() diff --git a/linden/indra/llmath/lluuid.cpp b/linden/indra/llmath/lluuid.cpp deleted file mode 100644 index d835cbc..0000000 --- a/linden/indra/llmath/lluuid.cpp +++ /dev/null @@ -1,923 +0,0 @@ -/** - * @file lluuid.cpp - * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -// We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes. -#if LL_WINDOWS -# undef WIN32_LEAN_AND_MEAN -# include -# include -#endif - -#include "lldefs.h" -#include "llerror.h" - -#include "lluuid.h" -#include "llerror.h" -#include "llrand.h" -#include "llmd5.h" -#include "llstring.h" -#include "lltimer.h" - -const LLUUID LLUUID::null; -const LLTransactionID LLTransactionID::tnull; - -/* - -NOT DONE YET!!! - -static char BASE85_TABLE[] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '!', '#', '$', '%', '&', '(', ')', '*', - '+', '-', ';', '[', '=', '>', '?', '@', '^', '_', - '`', '{', '|', '}', '~', '\0' -}; - - -void encode( char * fiveChars, unsigned int word ) throw( ) -{ -for( int ix = 0; ix < 5; ++ix ) { -fiveChars[4-ix] = encodeTable[ word % 85]; -word /= 85; -} -} - -To decode: -unsigned int decode( char const * fiveChars ) throw( bad_input_data ) -{ -unsigned int ret = 0; -for( int ix = 0; ix < 5; ++ix ) { -char * s = strchr( encodeTable, fiveChars[ ix ] ); -if( s == 0 ) throw bad_input_data(); -ret = ret * 85 + (s-encodeTable); -} -return ret; -} - -void LLUUID::toBase85(char* out) -{ - U32* me = (U32*)&(mData[0]); - for(S32 i = 0; i < 4; ++i) - { - char* o = &out[i*i]; - for(S32 j = 0; j < 5; ++j) - { - o[4-j] = BASE85_TABLE[ me[i] % 85]; - word /= 85; - } - } -} - -unsigned int decode( char const * fiveChars ) throw( bad_input_data ) -{ - unsigned int ret = 0; - for( S32 ix = 0; ix < 5; ++ix ) - { - char * s = strchr( encodeTable, fiveChars[ ix ] ); - ret = ret * 85 + (s-encodeTable); - } - return ret; -} -*/ - -#define LL_USE_JANKY_RANDOM_NUMBER_GENERATOR 0 -#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR -/** - * @brief a global for - */ -static U64 sJankyRandomSeed(LLUUID::getRandomSeed()); - -/** - * @brief generate a random U32. - */ -U32 janky_fast_random_bytes() -{ - sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223); - return (U32)sJankyRandomSeed; -} - -/** - * @brief generate a random U32 from [0, val) - */ -U32 janky_fast_random_byes_range(U32 val) -{ - sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223); - return (U32)(sJankyRandomSeed) % val; -} - -/** - * @brief generate a random U32 from [0, val) - */ -U32 janky_fast_random_seeded_bytes(U32 seed, U32 val) -{ - seed = U64L(1664525) * (U64)(seed) + U64L(1013904223); - return (U32)(seed) % val; -} -#endif - -// Common to all UUID implementations -void LLUUID::toString(char *out) const -{ - sprintf(out, - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - (U8)(mData[0]), - (U8)(mData[1]), - (U8)(mData[2]), - (U8)(mData[3]), - (U8)(mData[4]), - (U8)(mData[5]), - (U8)(mData[6]), - (U8)(mData[7]), - (U8)(mData[8]), - (U8)(mData[9]), - (U8)(mData[10]), - (U8)(mData[11]), - (U8)(mData[12]), - (U8)(mData[13]), - (U8)(mData[14]), - (U8)(mData[15])); -} - -void LLUUID::toCompressedString(char *out) const -{ - memcpy(out, mData, UUID_BYTES); /* Flawfinder: ignore */ - out[UUID_BYTES] = '\0'; -} - -std::string LLUUID::getString() const -{ - return asString(); -} - -std::string LLUUID::asString() const -{ - char str[UUID_STR_SIZE]; /* Flawfinder: ignore */ - toString(str); - return std::string(str); -} - -BOOL LLUUID::set(const std::string& in_string, BOOL emit) -{ - return set(in_string.c_str(), emit); -} - -BOOL LLUUID::set(const char *in_string, BOOL emit) -{ - BOOL broken_format = FALSE; - if (!in_string) - { - llerrs << "No string pointer in LLUUID::set!" << llendl; - setNull(); - return FALSE; - } - - // empty strings should make NULL uuid - if (!in_string[0]) - { - setNull(); - return TRUE; - } - - if (strlen(in_string) != (UUID_STR_LENGTH - 1)) /* Flawfinder: ignore */ - { - // I'm a moron. First implementation didn't have the right UUID format. - // Shouldn't see any of these any more - if (strlen(in_string) == (UUID_STR_LENGTH - 2)) /* Flawfinder: ignore */ - { - if(emit) - { - llinfos << "Warning! Using broken UUID string format" << llendl; - } - broken_format = TRUE; - } - else - { - // Bad UUID string. Spam as INFO, as most cases we don't care. - if(emit) - { - llinfos << "Bad UUID string: " << in_string << llendl; - } - setNull(); - return FALSE; - } - } - - U8 cur_pos = 0; - S32 i; - for (i = 0; i < UUID_BYTES; i++) - { - if ((i == 4) || (i == 6) || (i == 8) || (i == 10)) - { - cur_pos++; - if (broken_format && (i==10)) - { - // Missing - in the broken format - cur_pos--; - } - } - - mData[i] = 0; - - if ((*(in_string + cur_pos) >= '0') && (*(in_string+cur_pos) <= '9')) - { - mData[i] += (U8)(*(in_string + cur_pos) - '0'); - } - else if ((*(in_string + cur_pos) >= 'a') && (*(in_string+cur_pos) <='f')) - { - mData[i] += (U8)(10 + *(in_string + cur_pos) - 'a'); - } - else if ((*(in_string + cur_pos) >= 'A') && (*(in_string+cur_pos) <='F')) - { - mData[i] += (U8)(10 + *(in_string + cur_pos) - 'A'); - } - else - { - if(emit) - { - llwarns << "Invalid UUID string character" << llendl; - } - setNull(); - return FALSE; - } - - mData[i] = mData[i] << 4; - cur_pos++; - - if ((*(in_string + cur_pos) >= '0') && (*(in_string+cur_pos) <= '9')) - { - mData[i] += (U8)(*(in_string + cur_pos) - '0'); - } - else if ((*(in_string + cur_pos) >= 'a') && (*(in_string+cur_pos) <='f')) - { - mData[i] += (U8)(10 + *(in_string + cur_pos) - 'a'); - } - else if ((*(in_string + cur_pos) >= 'A') && (*(in_string+cur_pos) <='F')) - { - mData[i] += (U8)(10 + *(in_string + cur_pos) - 'A'); - } - else - { - if(emit) - { - llwarns << "Invalid UUID string character" << llendl; - } - setNull(); - return FALSE; - } - cur_pos++; - } - - return TRUE; -} - -BOOL LLUUID::validate(const std::string& in_string) -{ - return validate(in_string.c_str()); -} - -BOOL LLUUID::validate(const char *in_string) -{ - BOOL broken_format = FALSE; - if (!in_string) - { - return FALSE; - } - if (strlen(in_string) != (UUID_STR_LENGTH - 1)) /* Flawfinder: ignore */ - { - // I'm a moron. First implementation didn't have the right UUID format. - if (strlen(in_string) == (UUID_STR_LENGTH - 2)) /* Flawfinder: ignore */ - { - broken_format = TRUE; - } - else - { - return FALSE; - } - } - - U8 cur_pos = 0; - U32 i; - for (i = 0; i < 16; i++) - { - if ((i == 4) || (i == 6) || (i == 8) || (i == 10)) - { - cur_pos++; - if (broken_format && (i==10)) - { - // Missing - in the broken format - cur_pos--; - } - } - - if ((*(in_string + cur_pos) >= '0') && (*(in_string+cur_pos) <= '9')) - { - } - else if ((*(in_string + cur_pos) >= 'a') && (*(in_string+cur_pos) <='f')) - { - } - else if ((*(in_string + cur_pos) >= 'A') && (*(in_string+cur_pos) <='F')) - { - } - else - { - return FALSE; - } - - cur_pos++; - - if ((*(in_string + cur_pos) >= '0') && (*(in_string+cur_pos) <= '9')) - { - } - else if ((*(in_string + cur_pos) >= 'a') && (*(in_string+cur_pos) <='f')) - { - } - else if ((*(in_string + cur_pos) >= 'A') && (*(in_string+cur_pos) <='F')) - { - } - else - { - return FALSE; - } - cur_pos++; - } - return TRUE; -} - -const LLUUID& LLUUID::operator^=(const LLUUID& rhs) -{ - U32* me = (U32*)&(mData[0]); - const U32* other = (U32*)&(rhs.mData[0]); - for(S32 i = 0; i < 4; ++i) - { - me[i] = me[i] ^ other[i]; - } - return *this; -} - -LLUUID LLUUID::operator^(const LLUUID& rhs) const -{ - LLUUID id(*this); - id ^= rhs; - return id; -} - -void LLUUID::combine(const LLUUID& other, LLUUID& result) const -{ - LLMD5 md5_uuid; - md5_uuid.update((unsigned char*)mData, 16); - md5_uuid.update((unsigned char*)other.mData, 16); - md5_uuid.finalize(); - md5_uuid.raw_digest(result.mData); -} - -LLUUID LLUUID::combine(const LLUUID &other) const -{ - LLUUID combination; - combine(other, combination); - return combination; -} - -std::ostream& operator<<(std::ostream& s, const LLUUID &uuid) -{ - char uuid_str[UUID_STR_LENGTH]; - - uuid.toString(uuid_str); - s << uuid_str; - return s; -} - -std::istream& operator>>(std::istream &s, LLUUID &uuid) -{ - U32 i; - char uuid_str[UUID_STR_LENGTH]; /* Flawfinder: ignore */ - for (i = 0; i < UUID_STR_LENGTH-1; i++) - { - s >> uuid_str[i]; - } - uuid_str[i] = '\0'; - uuid.set(uuid_str); - return s; -} - -static void get_random_bytes(void *buf, int nbytes) -{ - int i; - char *cp = (char *) buf; - - // *NOTE: If we are not using the janky generator ll_rand() - // generates at least 3 good bytes of data since it is 0 to - // RAND_MAX. This could be made more efficient by copying all the - // bytes. - for (i=0; i < nbytes; i++) -#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR - *cp++ = janky_fast_random_bytes() & 0xFF; -#else - *cp++ = ll_rand() & 0xFF; -#endif - return; -} - -#if LL_WINDOWS -typedef struct _ASTAT_ -{ - ADAPTER_STATUS adapt; - NAME_BUFFER NameBuff [30]; -}ASTAT, * PASTAT; - -// static -S32 LLUUID::getNodeID(unsigned char * node_id) -{ - ASTAT Adapter; - NCB Ncb; - UCHAR uRetCode; - LANA_ENUM lenum; - int i; - int retval = 0; - - memset( &Ncb, 0, sizeof(Ncb) ); - Ncb.ncb_command = NCBENUM; - Ncb.ncb_buffer = (UCHAR *)&lenum; - Ncb.ncb_length = sizeof(lenum); - uRetCode = Netbios( &Ncb ); - // printf( "The NCBENUM return code is: 0x%x \n", uRetCode ); - - for(i=0; i < lenum.length ;i++) - { - memset( &Ncb, 0, sizeof(Ncb) ); - Ncb.ncb_command = NCBRESET; - Ncb.ncb_lana_num = lenum.lana[i]; - - uRetCode = Netbios( &Ncb ); - // printf( "The NCBRESET on LANA %d return code is: 0x%x \n", - // lenum.lana[i], uRetCode ); - - memset( &Ncb, 0, sizeof (Ncb) ); - Ncb.ncb_command = NCBASTAT; - Ncb.ncb_lana_num = lenum.lana[i]; - - strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */ - Ncb.ncb_buffer = (unsigned char *)&Adapter; - Ncb.ncb_length = sizeof(Adapter); - - uRetCode = Netbios( &Ncb ); -// printf( "The NCBASTAT on LANA %d return code is: 0x%x \n", -// lenum.lana[i], uRetCode ); - if ( uRetCode == 0 ) - { -// printf( "The Ethernet Number on LANA %d is: %02x%02x%02x%02x%02x%02x\n", -// lenum.lana[i], -// Adapter.adapt.adapter_address[0], -// Adapter.adapt.adapter_address[1], -// Adapter.adapt.adapter_address[2], -// Adapter.adapt.adapter_address[3], -// Adapter.adapt.adapter_address[4], -// Adapter.adapt.adapter_address[5] ); - memcpy(node_id,Adapter.adapt.adapter_address,6); /* Flawfinder: ignore */ - retval = 1; - - } - } - return retval; -} - -#elif LL_DARWIN -// Mac OS X version of the UUID generation code... -/* - * Get an ethernet hardware address, if we can find it... - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// static -S32 LLUUID::getNodeID(unsigned char *node_id) -{ - int i; - unsigned char *a = NULL; - struct ifaddrs *ifap, *ifa; - int rv; - S32 result = 0; - - if ((rv=getifaddrs(&ifap))==-1) - { - return -1; - } - if (ifap == NULL) - { - return -1; - } - - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) - { -// printf("Interface %s, address family %d, ", ifa->ifa_name, ifa->ifa_addr->sa_family); - for(i=0; i< ifa->ifa_addr->sa_len; i++) - { -// printf("%02X ", (unsigned char)ifa->ifa_addr->sa_data[i]); - } -// printf("\n"); - - if(ifa->ifa_addr->sa_family == AF_LINK) - { - // This is a link-level address - struct sockaddr_dl *lla = (struct sockaddr_dl *)ifa->ifa_addr; - -// printf("\tLink level address, type %02X\n", lla->sdl_type); - - if(lla->sdl_type == IFT_ETHER) - { - // Use the first ethernet MAC in the list. - // For some reason, the macro LLADDR() defined in net/if_dl.h doesn't expand correctly. This is what it would do. - a = (unsigned char *)&((lla)->sdl_data); - a += (lla)->sdl_nlen; - - if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) - { - continue; - } - - if (node_id) - { - memcpy(node_id, a, 6); - result = 1; - } - - // We found one. - break; - } - } - } - freeifaddrs(ifap); - - return result; -} - -#else - -// Linux version of the UUID generation code... -/* - * Get the ethernet hardware address, if we can find it... - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_NETINET_IN_H -#ifdef HAVE_NETINET_IN_H -#include -#if LL_SOLARIS -#include -#elif !LL_DARWIN -#include -#endif -#endif - -// static -S32 LLUUID::getNodeID(unsigned char *node_id) -{ - int sd; - struct ifreq ifr, *ifrp; - struct ifconf ifc; - char buf[1024]; - int n, i; - unsigned char *a; - -/* - * BSD 4.4 defines the size of an ifreq to be - * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len - * However, under earlier systems, sa_len isn't present, so the size is - * just sizeof(struct ifreq) - */ -#ifdef HAVE_SA_LEN -#ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) -#endif -#define ifreq_size(i) max(sizeof(struct ifreq),\ - sizeof((i).ifr_name)+(i).ifr_addr.sa_len) -#else -#define ifreq_size(i) sizeof(struct ifreq) -#endif /* HAVE_SA_LEN*/ - - sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); - if (sd < 0) { - return -1; - } - memset(buf, 0, sizeof(buf)); - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) { - close(sd); - return -1; - } - n = ifc.ifc_len; - for (i = 0; i < n; i+= ifreq_size(*ifr) ) { - ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i); - strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ); /* Flawfinder: ignore */ -#ifdef SIOCGIFHWADDR - if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) - continue; - a = (unsigned char *) &ifr.ifr_hwaddr.sa_data; -#else -#ifdef SIOCGENADDR - if (ioctl(sd, SIOCGENADDR, &ifr) < 0) - continue; - a = (unsigned char *) ifr.ifr_enaddr; -#else - /* - * XXX we don't have a way of getting the hardware - * address - */ - close(sd); - return 0; -#endif /* SIOCGENADDR */ -#endif /* SIOCGIFHWADDR */ - if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) - continue; - if (node_id) { - memcpy(node_id, a, 6); /* Flawfinder: ignore */ - close(sd); - return 1; - } - } - close(sd); - return 0; -} - -#endif - -S32 LLUUID::cmpTime(uuid_time_t *t1, uuid_time_t *t2) -{ - // Compare two time values. - - if (t1->high < t2->high) return -1; - if (t1->high > t2->high) return 1; - if (t1->low < t2->low) return -1; - if (t1->low > t2->low) return 1; - return 0; -} - -void LLUUID::getSystemTime(uuid_time_t *timestamp) -{ - // Get system time with 100ns precision. Time is since Oct 15, 1582. -#if LL_WINDOWS - ULARGE_INTEGER time; - GetSystemTimeAsFileTime((FILETIME *)&time); - // NT keeps time in FILETIME format which is 100ns ticks since - // Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. - // The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) - // + 18 years and 5 leap days. - time.QuadPart += - (unsigned __int64) (1000*1000*10) // seconds - * (unsigned __int64) (60 * 60 * 24) // days - * (unsigned __int64) (17+30+31+365*18+5); // # of days - - timestamp->high = time.HighPart; - timestamp->low = time.LowPart; -#else - struct timeval tp; - gettimeofday(&tp, 0); - - // Offset between UUID formatted times and Unix formatted times. - // UUID UTC base time is October 15, 1582. - // Unix base time is January 1, 1970. - U64 uuid_time = ((U64)tp.tv_sec * 10000000) + (tp.tv_usec * 10) + - U64L(0x01B21DD213814000); - timestamp->high = (U32) (uuid_time >> 32); - timestamp->low = (U32) (uuid_time & 0xFFFFFFFF); -#endif -} - -void LLUUID::getCurrentTime(uuid_time_t *timestamp) -{ - // Get current time as 60 bit 100ns ticks since whenever. - // Compensate for the fact that real clock resolution is less - // than 100ns. - - const U32 uuids_per_tick = 1024; - - static uuid_time_t time_last; - static U32 uuids_this_tick; - static BOOL init = FALSE; - - if (!init) { - getSystemTime(&time_last); - uuids_this_tick = uuids_per_tick; - init = TRUE; - } - - uuid_time_t time_now = {0,0}; - - while (1) { - getSystemTime(&time_now); - - // if clock reading changed since last UUID generated - if (cmpTime(&time_last, &time_now)) { - // reset count of uuid's generated with this clock reading - uuids_this_tick = 0; - break; - } - if (uuids_this_tick < uuids_per_tick) { - uuids_this_tick++; - break; - } - // going too fast for our clock; spin - } - - time_last = time_now; - - if (uuids_this_tick != 0) { - if (time_now.low & 0x80000000) { - time_now.low += uuids_this_tick; - if (!(time_now.low & 0x80000000)) - time_now.high++; - } else - time_now.low += uuids_this_tick; - } - - timestamp->high = time_now.high; - timestamp->low = time_now.low; -} - -void LLUUID::generate() -{ - // Create a UUID. - uuid_time_t timestamp; - - static unsigned char node_id[6]; /* Flawfinder: ignore */ - static int has_init = 0; - - // Create a UUID. - static uuid_time_t time_last = {0,0}; - static U16 clock_seq = 0; -#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR - static U32 seed = 0L; // dummy seed. reset it below -#endif - if (!has_init) - { - if (getNodeID(node_id) <= 0) - { - get_random_bytes(node_id, 6); - /* - * Set multicast bit, to prevent conflicts - * with IEEE 802 addresses obtained from - * network cards - */ - node_id[0] |= 0x80; - } - - getCurrentTime(&time_last); -#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR - seed = time_last.low; -#endif - -#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR - clock_seq = (U16)janky_fast_random_seeded_bytes(seed, 65536); -#else - clock_seq = (U16)ll_rand(65536); -#endif - has_init = 1; - } - - // get current time - getCurrentTime(×tamp); - - // if clock went backward change clockseq - if (cmpTime(×tamp, &time_last) == -1) { - clock_seq = (clock_seq + 1) & 0x3FFF; - if (clock_seq == 0) clock_seq++; - } - - memcpy(mData+10, node_id, 6); /* Flawfinder: ignore */ - U32 tmp; - tmp = timestamp.low; - mData[3] = (unsigned char) tmp; - tmp >>= 8; - mData[2] = (unsigned char) tmp; - tmp >>= 8; - mData[1] = (unsigned char) tmp; - tmp >>= 8; - mData[0] = (unsigned char) tmp; - - tmp = (U16) timestamp.high; - mData[5] = (unsigned char) tmp; - tmp >>= 8; - mData[4] = (unsigned char) tmp; - - tmp = (timestamp.high >> 16) | 0x1000; - mData[7] = (unsigned char) tmp; - tmp >>= 8; - mData[6] = (unsigned char) tmp; - - tmp = clock_seq; - mData[9] = (unsigned char) tmp; - tmp >>= 8; - mData[8] = (unsigned char) tmp; - - LLMD5 md5_uuid; - - md5_uuid.update(mData,16); - md5_uuid.finalize(); - md5_uuid.raw_digest(mData); - - time_last = timestamp; -} - -void LLUUID::generate(std::string hash_string) -{ - LLMD5 md5_uuid((U8*)hash_string.c_str()); - md5_uuid.raw_digest(mData); -} - -U32 LLUUID::getRandomSeed() -{ - static unsigned char seed[16]; /* Flawfinder: ignore */ - - getNodeID(&seed[0]); - seed[6]='\0'; - seed[7]='\0'; - getSystemTime((uuid_time_t *)(&seed[8])); - - LLMD5 md5_seed; - - md5_seed.update(seed,16); - md5_seed.finalize(); - md5_seed.raw_digest(seed); - - return(*(U32 *)seed); -} - -BOOL LLUUID::parseUUID(const char* buf, LLUUID* value) -{ - if( buf == NULL || buf[0] == '\0' || value == NULL) - { - return FALSE; - } - - LLString temp( buf ); - LLString::trim(temp); - if( LLUUID::validate( temp ) ) - { - value->set( temp ); - return TRUE; - } - return FALSE; -} - -LLAssetID LLTransactionID::makeAssetID(const LLUUID& session) const -{ - LLAssetID result; - if (isNull()) - { - result.setNull(); - } - else - { - combine(session, result); - } - return result; -} diff --git a/linden/indra/llmath/lluuid.h b/linden/indra/llmath/lluuid.h deleted file mode 100644 index 48308f2..0000000 --- a/linden/indra/llmath/lluuid.h +++ /dev/null @@ -1,330 +0,0 @@ -/** - * @file lluuid.h - * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLUUID_H -#define LL_LLUUID_H - -#include -#include -#include "stdtypes.h" - -const S32 UUID_BYTES = 16; -const S32 UUID_WORDS = 4; -const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below -const S32 UUID_STR_SIZE = 37; -const S32 UUID_BASE85_LENGTH = 21; // including the trailing NULL. - -struct uuid_time_t { - U32 high; - U32 low; - }; - -class LLUUID -{ -public: - // - // CREATORS - // - LLUUID(); - explicit LLUUID(const char *in_string); // Convert from string. - explicit LLUUID(const std::string& in_string); // Convert from string. - LLUUID(const LLUUID &in); - LLUUID &operator=(const LLUUID &rhs); - - ~LLUUID(); - - // - // MANIPULATORS - // - void generate(); // Generate a new UUID - void generate(std::string stream); //Generate a new UUID based on hash of input stream - BOOL set(const char *in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings - BOOL set(const std::string& in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings - void setNull(); // Faster than setting to LLUUID::null. - - S32 cmpTime(uuid_time_t *t1, uuid_time_t *t2); - static void getSystemTime(uuid_time_t *timestamp); - void getCurrentTime(uuid_time_t *timestamp); - - // - // ACCESSORS - // - BOOL isNull() const; // Faster than comparing to LLUUID::null. - BOOL notNull() const; // Faster than comparing to LLUUID::null. - // JC: This is dangerous. It allows UUIDs to be cast automatically - // to integers, among other things. Use isNull() or notNull(). - // operator bool() const; - - // JC: These must return real bool's (not BOOLs) or else use of the STL - // will generate bool-to-int performance warnings. - bool operator==(const LLUUID &rhs) const; - bool operator!=(const LLUUID &rhs) const; - bool operator<(const LLUUID &rhs) const; - bool operator>(const LLUUID &rhs) const; - - // xor functions. Useful since any two random uuids xored together - // will yield a determinate third random unique id that can be - // used as a key in a single uuid that represents 2. - const LLUUID& operator^=(const LLUUID& rhs); - LLUUID operator^(const LLUUID& rhs) const; - - // similar to functions above, but not invertible - // yields a third random UUID that can be reproduced from the two inputs - // but which, given the result and one of the inputs can't be used to - // deduce the other input - LLUUID combine(const LLUUID& other) const; - void combine(const LLUUID& other, LLUUID& result) const; - - friend std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); - friend std::istream& operator>>(std::istream& s, LLUUID &uuid); - - void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0) - void toCompressedString(char *out) const; // Does not allocate memory, needs 17 characters (including \0) - - std::string asString() const; - std::string getString() const; - - U16 getCRC16() const; - U32 getCRC32() const; - - static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal. - static BOOL validate(const char *in_string); // Validate that the UUID string is legal. - - static const LLUUID null; - - static U32 getRandomSeed(); - static S32 getNodeID(unsigned char * node_id); - - static BOOL parseUUID(const char* buf, LLUUID* value); - - U8 mData[UUID_BYTES]; -}; - - -// Construct -inline LLUUID::LLUUID() -{ - setNull(); -} - - -// Faster than copying from memory -inline void LLUUID::setNull() -{ - U32 *word = (U32 *)mData; - word[0] = 0; - word[1] = 0; - word[2] = 0; - word[3] = 0; -} - - -// Compare -inline bool LLUUID::operator==(const LLUUID& rhs) const -{ - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - // Note: binary & to avoid branching - return - (tmp[0] == rhstmp[0]) & - (tmp[1] == rhstmp[1]) & - (tmp[2] == rhstmp[2]) & - (tmp[3] == rhstmp[3]); -} - - -inline bool LLUUID::operator!=(const LLUUID& rhs) const -{ - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - // Note: binary | to avoid branching - return - (tmp[0] != rhstmp[0]) | - (tmp[1] != rhstmp[1]) | - (tmp[2] != rhstmp[2]) | - (tmp[3] != rhstmp[3]); -} - -/* -// JC: This is dangerous. It allows UUIDs to be cast automatically -// to integers, among other things. Use isNull() or notNull(). -inline LLUUID::operator bool() const -{ - U32 *word = (U32 *)mData; - return (word[0] | word[1] | word[2] | word[3]) > 0; -} -*/ - -inline BOOL LLUUID::notNull() const -{ - U32 *word = (U32 *)mData; - return (word[0] | word[1] | word[2] | word[3]) > 0; -} - -// Faster than == LLUUID::null because doesn't require -// as much memory access. -inline BOOL LLUUID::isNull() const -{ - U32 *word = (U32 *)mData; - // If all bits are zero, return !0 == TRUE - return !(word[0] | word[1] | word[2] | word[3]); -} - -// Copy constructor -inline LLUUID::LLUUID(const LLUUID& rhs) -{ - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - tmp[0] = rhstmp[0]; - tmp[1] = rhstmp[1]; - tmp[2] = rhstmp[2]; - tmp[3] = rhstmp[3]; -} - -inline LLUUID::~LLUUID() -{ -} - -// Assignment -inline LLUUID& LLUUID::operator=(const LLUUID& rhs) -{ - // No need to check the case where this==&rhs. The branch is slower than the write. - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - tmp[0] = rhstmp[0]; - tmp[1] = rhstmp[1]; - tmp[2] = rhstmp[2]; - tmp[3] = rhstmp[3]; - - return *this; -} - - -inline LLUUID::LLUUID(const char *in_string) -{ - if (!in_string || in_string[0] == 0) - { - setNull(); - return; - } - - set(in_string); -} - -inline LLUUID::LLUUID(const std::string& in_string) -{ - if (in_string.empty()) - { - setNull(); - return; - } - - set(in_string); -} - -// IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order -// IW: this will make me very sad -inline bool LLUUID::operator<(const LLUUID &rhs) const -{ - U32 i; - for( i = 0; i < (UUID_BYTES - 1); i++ ) - { - if( mData[i] != rhs.mData[i] ) - { - return (mData[i] < rhs.mData[i]); - } - } - return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]); -} - -inline bool LLUUID::operator>(const LLUUID &rhs) const -{ - U32 i; - for( i = 0; i < (UUID_BYTES - 1); i++ ) - { - if( mData[i] != rhs.mData[i] ) - { - return (mData[i] > rhs.mData[i]); - } - } - return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]); -} - -inline U16 LLUUID::getCRC16() const -{ - // A UUID is 16 bytes, or 8 shorts. - U16 *short_data = (U16*)mData; - U16 out = 0; - out += short_data[0]; - out += short_data[1]; - out += short_data[2]; - out += short_data[3]; - out += short_data[4]; - out += short_data[5]; - out += short_data[6]; - out += short_data[7]; - return out; -} - -inline U32 LLUUID::getCRC32() const -{ - U32 *tmp = (U32*)mData; - return tmp[0] + tmp[1] + tmp[2] + tmp[3]; -} - - -// Helper structure for ordering lluuids in stl containers. -// eg: std::map widget_map; -struct lluuid_less -{ - bool operator()(const LLUUID& lhs, const LLUUID& rhs) const - { - return (lhs < rhs) ? true : false; - } -}; - -typedef std::set uuid_list_t; - -/* - * Sub-classes for keeping transaction IDs and asset IDs - * straight. - */ -typedef LLUUID LLAssetID; - -class LLTransactionID : public LLUUID -{ -public: - LLTransactionID() : LLUUID() { } - - static const LLTransactionID tnull; - LLAssetID makeAssetID(const LLUUID& session) const; -}; - -#endif diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp index f7c9286..7b6c6a9 100644 --- a/linden/indra/llmath/llvolume.cpp +++ b/linden/indra/llmath/llvolume.cpp @@ -82,11 +82,6 @@ const F32 TAPER_MAX = 1.f; const F32 SKEW_MIN = -0.95f; const F32 SKEW_MAX = 0.95f; -const S32 SCULPT_REZ_1 = 6; // changed from 4 to 6 - 6 looks round whereas 4 looks square -const S32 SCULPT_REZ_2 = 8; -const S32 SCULPT_REZ_3 = 16; -const S32 SCULPT_REZ_4 = 32; - const F32 SCULPT_MIN_AREA = 0.002f; BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) @@ -104,46 +99,128 @@ BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLV } } -// intersect test between triangle pt1,pt2,pt3 and line from linept to linept+vect -//returns TRUE if intersecting and moves linept to the point of intersection -BOOL LLTriangleLineSegmentIntersect( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, LLVector3& linept, const LLVector3& vect) +BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size) +{ + float fAWdU[3]; + LLVector3 dir; + LLVector3 diff; + + for (U32 i = 0; i < 3; i++) + { + dir.mV[i] = 0.5f * (end.mV[i] - start.mV[i]); + diff.mV[i] = (0.5f * (end.mV[i] + start.mV[i])) - center.mV[i]; + fAWdU[i] = fabsf(dir.mV[i]); + if(fabsf(diff.mV[i])>size.mV[i] + fAWdU[i]) return false; + } + + float f; + f = dir.mV[1] * diff.mV[2] - dir.mV[2] * diff.mV[1]; if(fabsf(f)>size.mV[1]*fAWdU[2] + size.mV[2]*fAWdU[1]) return false; + f = dir.mV[2] * diff.mV[0] - dir.mV[0] * diff.mV[2]; if(fabsf(f)>size.mV[0]*fAWdU[2] + size.mV[2]*fAWdU[0]) return false; + f = dir.mV[0] * diff.mV[1] - dir.mV[1] * diff.mV[0]; if(fabsf(f)>size.mV[0]*fAWdU[1] + size.mV[1]*fAWdU[0]) return false; + + return true; +} + + +// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. +// returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b, +// and returns the intersection point along dir in intersection_t. + +// Moller-Trumbore algorithm +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) { - LLVector3 V1 = pt2-pt1; - LLVector3 V2 = pt3-pt2; + F32 u, v, t; - LLVector3 norm = V1 % V2; + /* find vectors for two edges sharing vert0 */ + LLVector3 edge1 = vert1 - vert0; - F32 dotprod = norm * vect; + LLVector3 edge2 = vert2 - vert0;; - if(dotprod < 0) + /* begin calculating determinant - also used to calculate U parameter */ + LLVector3 pvec = dir % edge2; + + /* if determinant is near zero, ray lies in plane of triangle */ + F32 det = edge1 * pvec; + + if (!two_sided) { - //Find point of intersect to triangle plane. - //find t to intersect point - F32 t = -(norm * (linept-pt1))/dotprod; + if (det < F_APPROXIMATELY_ZERO) + { + return FALSE; + } + + /* calculate distance from vert0 to ray origin */ + LLVector3 tvec = orig - vert0; - // if ds is neg line started past triangle so can't hit triangle. - if (t > 0) + /* calculate U parameter and test bounds */ + u = tvec * pvec; + + if (u < 0.f || u > det) { return FALSE; } - LLVector3 pt_int = linept + (vect*t); + /* prepare to test V parameter */ + LLVector3 qvec = tvec % edge1; - if(check_same_clock_dir(pt1, pt2, pt_int, norm)) + /* calculate V parameter and test bounds */ + v = dir * qvec; + if (v < 0.f || u + v > det) { - if(check_same_clock_dir(pt2, pt3, pt_int, norm)) + return FALSE; + } + + /* calculate t, scale parameters, ray intersects triangle */ + t = edge2 * qvec; + F32 inv_det = 1.0 / det; + t *= inv_det; + u *= inv_det; + v *= inv_det; + } + + else // two sided { - if(check_same_clock_dir(pt3, pt1, pt_int, norm)) + if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO) { - // answer in pt_int is insde triangle - linept.setVec(pt_int); - return TRUE; + return FALSE; } + F32 inv_det = 1.0 / det; + + /* calculate distance from vert0 to ray origin */ + LLVector3 tvec = orig - vert0; + + /* calculate U parameter and test bounds */ + u = (tvec * pvec) * inv_det; + if (u < 0.f || u > 1.f) + { + return FALSE; } + + /* prepare to test V parameter */ + LLVector3 qvec = tvec - edge1; + + /* calculate V parameter and test bounds */ + v = (dir * qvec) * inv_det; + + if (v < 0.f || u + v > 1.f) + { + return FALSE; } + + /* calculate t, ray intersects triangle */ + t = (edge2 * qvec) * inv_det; } - return FALSE; + if (intersection_a != NULL) + *intersection_a = u; + if (intersection_b != NULL) + *intersection_b = v; + if (intersection_t != NULL) + *intersection_t = t; + + + return TRUE; } @@ -198,9 +275,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3 F32 t, t_step, t_first, t_fraction, ang, ang_step; LLVector3 pt1,pt2; - mMaxX = 0.f; - mMinX = 0.f; - F32 begin = params.getBegin(); F32 end = params.getEnd(); @@ -236,15 +310,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3 if (t_fraction < 0.9999f) { LLVector3 new_pt = lerp(pt1, pt2, t_fraction); - F32 pt_x = new_pt.mV[VX]; - if (pt_x < mMinX) - { - mMinX = pt_x; - } - else if (pt_x > mMaxX) - { - mMaxX = pt_x; - } mProfile.push_back(new_pt); } @@ -254,16 +319,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3 // Iterate through all the integer steps of t. pt1.setVec(cos(ang)*scale,sin(ang)*scale,t); - F32 pt_x = pt1.mV[VX]; - if (pt_x < mMinX) - { - mMinX = pt_x; - } - else if (pt_x > mMaxX) - { - mMaxX = pt_x; - } - if (mProfile.size() > 0) { LLVector3 p = mProfile[mProfile.size()-1]; for (S32 i = 0; i < split && mProfile.size() > 0; i++) { @@ -287,15 +342,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3 if (t_fraction > 0.0001f) { LLVector3 new_pt = lerp(pt1, pt2, t_fraction); - F32 pt_x = new_pt.mV[VX]; - if (pt_x < mMinX) - { - mMinX = pt_x; - } - else if (pt_x > mMaxX) - { - mMaxX = pt_x; - } if (mProfile.size() > 0) { LLVector3 p = mProfile[mProfile.size()-1]; @@ -472,31 +518,9 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3 } -S32 sculpt_sides(F32 detail) -{ - - // detail is usually one of: 1, 1.5, 2.5, 4.0. - - if (detail <= 1.0) - { - return SCULPT_REZ_1; - } - if (detail <= 2.0) - { - return SCULPT_REZ_2; - } - if (detail <= 3.0) - { - return SCULPT_REZ_3; - } - else - { - return SCULPT_REZ_4; - } -} - -BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, BOOL is_sculpted) +BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, + BOOL is_sculpted, S32 sculpt_size) { LLMemType m1(LLMemType::MTYPE_VOLUME); @@ -640,7 +664,7 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai S32 sides = (S32)circle_detail; if (is_sculpted) - sides = sculpt_sides(detail); + sides = sculpt_size; genNGon(params, sides); @@ -1131,7 +1155,8 @@ const LLVector2 LLPathParams::getEndScale() const return end_scale; } -BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted) +BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, + BOOL is_sculpted, S32 sculpt_size) { LLMemType m1(LLMemType::MTYPE_VOLUME); @@ -1194,7 +1219,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions()); if (is_sculpted) - sides = sculpt_sides(detail); + sides = sculpt_size; genNGon(params, sides); } @@ -1259,7 +1284,8 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is return TRUE; } -BOOL LLDynamicPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted) +BOOL LLDynamicPath::generate(const LLPathParams& params, F32 detail, S32 split, + BOOL is_sculpted, S32 sculpt_size) { LLMemType m1(LLMemType::MTYPE_VOLUME); @@ -1979,6 +2005,12 @@ void LLVolume::sculptGeneratePlaceholder() // create the vertices from the map void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type) { + U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; + BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; + BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; + BOOL reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR + + LLMemType m1(LLMemType::MTYPE_VOLUME); S32 sizeS = mPathp->mPath.size(); @@ -1993,13 +2025,21 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 S32 i = t + line; Point& pt = mMesh[i]; - U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); + S32 reversed_t = t; + + if (reverse_horizontal) + { + reversed_t = sizeT - t - 1; + } + + U32 x = (U32) ((F32)reversed_t/(sizeT-1) * (F32) sculpt_width); U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); + if (y == 0) // top row stitching { // pinch? - if (sculpt_type == LL_SCULPT_TYPE_SPHERE) + if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) { x = sculpt_width / 2; } @@ -2008,7 +2048,7 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 if (y == sculpt_height) // bottom row stitching { // wrap? - if (sculpt_type == LL_SCULPT_TYPE_TORUS) + if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) { y = 0; } @@ -2018,7 +2058,7 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 } // pinch? - if (sculpt_type == LL_SCULPT_TYPE_SPHERE) + if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) { x = sculpt_width / 2; } @@ -2027,9 +2067,9 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 if (x == sculpt_width) // side stitching { // wrap? - if ((sculpt_type == LL_SCULPT_TYPE_SPHERE) || - (sculpt_type == LL_SCULPT_TYPE_TORUS) || - (sculpt_type == LL_SCULPT_TYPE_CYLINDER)) + if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || + (sculpt_stitching == LL_SCULPT_TYPE_TORUS) || + (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) { x = 0; } @@ -2041,12 +2081,69 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 } pt.mPos = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data); + + if (sculpt_mirror) + { + pt.mPos.mV[VX] *= -1.f; + } } + line += sizeT; } } +const S32 SCULPT_REZ_1 = 6; // changed from 4 to 6 - 6 looks round whereas 4 looks square +const S32 SCULPT_REZ_2 = 8; +const S32 SCULPT_REZ_3 = 16; +const S32 SCULPT_REZ_4 = 32; + +S32 sculpt_sides(F32 detail) +{ + + // detail is usually one of: 1, 1.5, 2.5, 4.0. + + if (detail <= 1.0) + { + return SCULPT_REZ_1; + } + if (detail <= 2.0) + { + return SCULPT_REZ_2; + } + if (detail <= 3.0) + { + return SCULPT_REZ_3; + } + else + { + return SCULPT_REZ_4; + } +} + + + +// determine the number of vertices in both s and t direction for this sculpt +void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t) +{ + S32 vertices = sculpt_sides(detail); + + F32 ratio; + if ((width == 0) || (height == 0)) + ratio = 1.f; + else + ratio = (F32) width / (F32) height; + + + s = (S32)(vertices / fsqrtf(ratio)); + + s = llmax(s, 3); // no degenerate sizes, please + t = vertices * vertices / s; + + t = llmax(t, 3); // no degenerate sizes, please + s = vertices * vertices / t; +} + // sculpt replaces generate() for sculpted surfaces void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level) { @@ -2061,11 +2158,16 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, data_is_empty = TRUE; } - mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE); - mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE); + S32 requested_sizeS = 0; + S32 requested_sizeT = 0; - S32 sizeS = mPathp->mPath.size(); - S32 sizeT = mProfilep->mProfile.size(); + sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, mDetail, requested_sizeS, requested_sizeT); + + mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS); + mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT); + + S32 sizeS = mPathp->mPath.size(); // we requested a specific size, now see what we really got + S32 sizeT = mProfilep->mProfile.size(); // we requested a specific size, now see what we really got // weird crash bug - DEV-11158 - trying to collect more data: if ((sizeS == 0) || (sizeT == 0)) @@ -3405,47 +3507,99 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, } } -S32 LLVolume::lineSegmentIntersect(const LLVector3& start, LLVector3& end) const +S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + S32 face, + LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) { - S32 ret = -1; + S32 hit_face = -1; - LLVector3 vec = end - start; + S32 start_face; + S32 end_face; - for (S32 i = 0; i < getNumFaces(); i++) + if (face == -1) // ALL_SIDES { - const LLVolumeFace& face = getVolumeFace(i); + start_face = 0; + end_face = getNumFaces() - 1; + } + else + { + start_face = face; + end_face = face; + } + + LLVector3 dir = end - start; + + F32 closest_t = 2.f; // must be larger than 1 + + for (S32 i = start_face; i <= end_face; i++) + { + const LLVolumeFace &face = getVolumeFace((U32)i); + + LLVector3 box_center = (face.mExtents[0] + face.mExtents[1]) / 2.f; + LLVector3 box_size = face.mExtents[1] - face.mExtents[0]; + + if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) + { + if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them + { + genBinormals(i); + } + + for (U32 tri = 0; tri < face.mIndices.size()/3; tri++) + { + S32 index1 = face.mIndices[tri*3+0]; + S32 index2 = face.mIndices[tri*3+1]; + S32 index3 = face.mIndices[tri*3+2]; - for (U32 j = 0; j < face.mIndices.size()/3; j++) + F32 a, b, t; + + if (LLTriangleRayIntersect(face.mVertices[index1].mPosition, + face.mVertices[index2].mPosition, + face.mVertices[index3].mPosition, + start, dir, &a, &b, &t, FALSE)) + { + if ((t >= 0.f) && // if hit is after start + (t <= 1.f) && // and before end + (t < closest_t)) // and this hit is closer { - //approximate normal - S32 v1 = face.mIndices[j*3+0]; - S32 v2 = face.mIndices[j*3+1]; - S32 v3 = face.mIndices[j*3+2]; + closest_t = t; + hit_face = i; - LLVector3 norm = (face.mVertices[v2].mPosition - face.mVertices[v1].mPosition) % - (face.mVertices[v3].mPosition - face.mVertices[v2].mPosition); + if (intersection != NULL) + { + *intersection = start + dir * closest_t; + } - if (norm.magVecSquared() >= 0.00000001f) + if (tex_coord != NULL) { - //get view vector - //LLVector3 view = (start-face.mVertices[v1].mPosition); - //if (view * norm < 0.0f) + *tex_coord = ((1.f - a - b) * face.mVertices[index1].mTexCoord + + a * face.mVertices[index2].mTexCoord + + b * face.mVertices[index3].mTexCoord); + + } + + if (normal != NULL) { - if (LLTriangleLineSegmentIntersect( face.mVertices[v1].mPosition, - face.mVertices[v2].mPosition, - face.mVertices[v3].mPosition, - end, - vec)) + *normal = ((1.f - a - b) * face.mVertices[index1].mNormal + + a * face.mVertices[index2].mNormal + + b * face.mVertices[index3].mNormal); + } + + if (bi_normal != NULL) { - vec = end-start; - ret = (S32) i; + *bi_normal = ((1.f - a - b) * face.mVertices[index1].mBinormal + + a * face.mVertices[index2].mBinormal + + b * face.mVertices[index3].mBinormal); + } + } } } } } - return ret; + + return hit_face; } class LLVertexIndexPair @@ -4768,6 +4922,13 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLMemType m1(LLMemType::MTYPE_VOLUME); BOOL flat = mTypeMask & FLAT_MASK; + + U8 sculpt_type = volume->getParams().getSculptType(); + U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; + BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; + BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; + BOOL sculpt_reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR + S32 num_vertices, num_indices; const std::vector& mesh = volume->getMesh(); @@ -4834,6 +4995,11 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } } + if (sculpt_reverse_horizontal) + { + ss = 1.f - ss; + } + // Check to see if this triangle wraps around the array. if (mBeginS + s >= max_s) { @@ -4995,9 +5161,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) BOOL s_bottom_converges = ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f); BOOL s_top_converges = ((mVertices[mNumS-1].mPosition - mVertices[mNumS*(mNumT-2)+mNumS-1].mPosition).magVecSquared() < 0.000001f); - U8 sculpt_type = volume->getParams().getSculptType(); - - if (sculpt_type == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes + if (sculpt_stitching == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes { if (volume->getPath().isOpen() == FALSE) { //wrap normals on T @@ -5046,15 +5210,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) BOOL wrap_s = FALSE; BOOL wrap_t = FALSE; - if (sculpt_type == LL_SCULPT_TYPE_SPHERE) + if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) average_poles = TRUE; - if ((sculpt_type == LL_SCULPT_TYPE_SPHERE) || - (sculpt_type == LL_SCULPT_TYPE_TORUS) || - (sculpt_type == LL_SCULPT_TYPE_CYLINDER)) + if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || + (sculpt_stitching == LL_SCULPT_TYPE_TORUS) || + (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) wrap_s = TRUE; - if (sculpt_type == LL_SCULPT_TYPE_TORUS) + if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) wrap_t = TRUE; diff --git a/linden/indra/llmath/llvolume.h b/linden/indra/llmath/llvolume.h index 5b48cfc..8ac0e71 100644 --- a/linden/indra/llmath/llvolume.h +++ b/linden/indra/llmath/llvolume.h @@ -175,7 +175,7 @@ const LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8; //============================================================================ -// sculpt types +// sculpt types + flags const U8 LL_SCULPT_TYPE_NONE = 0; const U8 LL_SCULPT_TYPE_SPHERE = 1; @@ -183,21 +183,30 @@ const U8 LL_SCULPT_TYPE_TORUS = 2; const U8 LL_SCULPT_TYPE_PLANE = 3; const U8 LL_SCULPT_TYPE_CYLINDER = 4; +const U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE | LL_SCULPT_TYPE_CYLINDER; + +const U8 LL_SCULPT_FLAG_INVERT = 64; +const U8 LL_SCULPT_FLAG_MIRROR = 128; class LLProfileParams { public: LLProfileParams() + : mCurveType(LL_PCODE_PROFILE_SQUARE), + mBegin(0.f), + mEnd(1.f), + mHollow(0.f), + mCRC(0) { - mCurveType = LL_PCODE_PROFILE_SQUARE; - mBegin = 0.f; - mEnd = 1.f; - mHollow = 0.f; } LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow) - : mCurveType(curve), mBegin(begin), mEnd(end), mHollow(hollow) + : mCurveType(curve), + mBegin(begin), + mEnd(end), + mHollow(hollow), + mCRC(0) { } @@ -222,6 +231,7 @@ public: temp_f32 = 1.f; } mHollow = temp_f32; + mCRC = 0; } bool operator==(const LLProfileParams ¶ms) const; @@ -309,27 +319,36 @@ class LLPathParams { public: LLPathParams() + : + mCurveType(LL_PCODE_PATH_LINE), + mBegin(0.f), + mEnd(1.f), + mScale(1.f,1.f), + mShear(0.f,0.f), + mTwistBegin(0.f), + mTwistEnd(0.f), + mRadiusOffset(0.f), + mTaper(0.f,0.f), + mRevolutions(1.f), + mSkew(0.f), + mCRC(0) { - mBegin = 0.f; - mEnd = 1.f; - mScale.setVec(1.f,1.f); - mShear.setVec(0.f,0.f); - mCurveType = LL_PCODE_PATH_LINE; - mTwistBegin = 0.f; - mTwistEnd = 0.f; - mRadiusOffset = 0.f; - mTaper.setVec(0.f,0.f); - mRevolutions = 1.f; - mSkew = 0.f; } LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy, F32 shx, F32 shy, F32 twistend, F32 twistbegin, F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew) - : mCurveType(curve), mBegin(begin), mEnd(end), mTwistBegin(twistbegin), mTwistEnd(twistend), - mRadiusOffset(radiusoffset), mRevolutions(revolutions), mSkew(skew) + : mCurveType(curve), + mBegin(begin), + mEnd(end), + mScale(scx,scy), + mShear(shx,shy), + mTwistBegin(twistbegin), + mTwistEnd(twistend), + mRadiusOffset(radiusoffset), + mTaper(tx,ty), + mRevolutions(revolutions), + mSkew(skew), + mCRC(0) { - mScale.setVec(scx,scy); - mShear.setVec(shx,shy); - mTaper.setVec(tx,ty); } LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew) @@ -347,6 +366,8 @@ public: mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA); mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f; mSkew = U8_TO_F32(skew) * SCALE_QUANTA; + + mCRC = 0; } bool operator==(const LLPathParams ¶ms) const; @@ -525,6 +546,7 @@ class LLVolumeParams { public: LLVolumeParams() + : mSculptType(LL_SCULPT_TYPE_NONE) { } @@ -649,7 +671,9 @@ public: mConcave(FALSE), mDirty(TRUE), mTotalOut(0), - mTotal(2) + mTotal(2), + mMinX(0.f), + mMaxX(0.f) { } @@ -660,7 +684,8 @@ public: BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); } BOOL isOpen() const { return mOpen; } void setDirty() { mDirty = TRUE; } - BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, BOOL is_sculpted = FALSE); + BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, + BOOL is_sculpted = FALSE, S32 sculpt_size = 0); BOOL isConcave() const { return mConcave; } public: struct Face @@ -678,8 +703,6 @@ public: std::vector mFaces; std::vector mEdgeNormals; std::vector mEdgeCenters; - F32 mMaxX; - F32 mMinX; friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile); @@ -698,6 +721,9 @@ protected: S32 mTotalOut; S32 mTotal; + + F32 mMaxX; + F32 mMinX; }; //------------------------------------------------------------------- @@ -728,7 +754,8 @@ public: virtual ~LLPath(); void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); - virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE); + virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, + BOOL is_sculpted = FALSE, S32 sculpt_size = 0); BOOL isOpen() const { return mOpen; } F32 getStep() const { return mStep; } @@ -754,7 +781,8 @@ class LLDynamicPath : public LLPath { public: LLDynamicPath() : LLPath() { } - /*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE); + /*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, + BOOL is_sculpted = FALSE, S32 sculpt_size = 0); }; // Yet another "face" class - caches volume-specific, but not instance-specific data for faces) @@ -885,7 +913,13 @@ 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, LLVector3& end) const; + S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + S32 face = -1, // which face to check, -1 = ALL_SIDES + LLVector3* 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 + ); // The following cleans up vertices and triangles, // getting rid of degenerate triangles and duplicate vertices, @@ -916,6 +950,8 @@ private: F32 sculptGetSurfaceArea(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data); void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); void sculptGeneratePlaceholder(); + void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t); + protected: BOOL generate(); @@ -946,4 +982,10 @@ LLVector3 calc_binormal_from_triangle( const LLVector3& pos2, const LLVector2& tex2); +BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& 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); + + + #endif diff --git a/linden/indra/llmath/llvolumemgr.cpp b/linden/indra/llmath/llvolumemgr.cpp index 0b5464c..a3cd6b5 100644 --- a/linden/indra/llmath/llvolumemgr.cpp +++ b/linden/indra/llmath/llvolumemgr.cpp @@ -115,7 +115,7 @@ LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 { mDataMutex->unlock(); } - return volgroupp->getLODVolume(detail); + return volgroupp->refLOD(detail); } // virtual @@ -294,7 +294,7 @@ bool LLVolumeLODGroup::cleanupRefs() return res; } -LLVolume* LLVolumeLODGroup::getLODVolume(const S32 detail) +LLVolume* LLVolumeLODGroup::refLOD(const S32 detail) { llassert(detail >=0 && detail < NUM_LODS); mAccessCount[detail]++; @@ -376,7 +376,6 @@ F32 LLVolumeLODGroup::getVolumeScaleFromDetail(const S32 detail) F32 LLVolumeLODGroup::dump() { - char dump_str[255]; /* Flawfinder: ignore */ F32 usage = 0.f; for (S32 i = 0; i < NUM_LODS; i++) { @@ -387,7 +386,7 @@ F32 LLVolumeLODGroup::dump() } usage = usage / (F32)NUM_LODS; - snprintf(dump_str, sizeof(dump_str), "%.3f %d %d %d %d", usage, mAccessCount[0], mAccessCount[1], mAccessCount[2], mAccessCount[3]); /* Flawfinder: ignore */ + std::string dump_str = llformat("%.3f %d %d %d %d", usage, mAccessCount[0], mAccessCount[1], mAccessCount[2], mAccessCount[3]); llinfos << dump_str << llendl; return usage; diff --git a/linden/indra/llmath/llvolumemgr.h b/linden/indra/llmath/llvolumemgr.h index dcaca01..d579fed 100644 --- a/linden/indra/llmath/llvolumemgr.h +++ b/linden/indra/llmath/llvolumemgr.h @@ -59,7 +59,7 @@ public: static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher); static F32 getVolumeScaleFromDetail(const S32 detail); - LLVolume* getLODVolume(const S32 detail); + LLVolume* refLOD(const S32 detail); BOOL derefLOD(LLVolume *volumep); S32 getNumRefs() const { return mRefs; } diff --git a/linden/indra/llmath/v2math.cpp b/linden/indra/llmath/v2math.cpp index 76fa60f..c3bb093 100644 --- a/linden/indra/llmath/v2math.cpp +++ b/linden/indra/llmath/v2math.cpp @@ -33,6 +33,7 @@ //#include "vmath.h" #include "v2math.h" +#include "v3math.h" #include "v4math.h" #include "m4math.h" #include "m3math.h" diff --git a/linden/indra/llmath/v2math.h b/linden/indra/llmath/v2math.h index 5a520d2..350079d 100644 --- a/linden/indra/llmath/v2math.h +++ b/linden/indra/llmath/v2math.h @@ -33,6 +33,7 @@ #define LL_V2MATH_H #include "llmath.h" +#include "v3math.h" class LLVector4; class LLMatrix3; @@ -49,9 +50,10 @@ class LLVector2 static LLVector2 zero; - LLVector2(); // Initializes LLVector2 to (0, 0) - LLVector2(F32 x, F32 y); // Initializes LLVector2 to (x. y) - LLVector2(const F32 *vec); // Initializes LLVector2 to (vec[0]. vec[1]) + LLVector2(); // Initializes LLVector2 to (0, 0) + LLVector2(F32 x, F32 y); // Initializes LLVector2 to (x. y) + LLVector2(const F32 *vec); // Initializes LLVector2 to (vec[0]. vec[1]) + explicit LLVector2(const LLVector3 &vec); // Initializes LLVector2 to (vec[0]. vec[1]) // Clears LLVector2 to (0, 0). DEPRECATED - prefer zeroVec. void clear(); @@ -137,6 +139,12 @@ inline LLVector2::LLVector2(const F32 *vec) mV[VY] = vec[VY]; } +inline LLVector2::LLVector2(const LLVector3 &vec) +{ + mV[VX] = vec.mV[VX]; + mV[VY] = vec.mV[VY]; +} + // Clear and Assignment Functions diff --git a/linden/indra/llmath/v3color.h b/linden/indra/llmath/v3color.h index a3bf385..b9bc641 100644 --- a/linden/indra/llmath/v3color.h +++ b/linden/indra/llmath/v3color.h @@ -174,6 +174,10 @@ inline LLColor3::LLColor3(const F32 *vec) mV[VZ] = vec[VZ]; } +#if LL_WINDOWS +# pragma warning( disable : 4996 ) // strncpy teh sux0r +#endif + inline LLColor3::LLColor3(char* color_string) // takes a string of format "RRGGBB" where RR is hex 00..FF { if (strlen(color_string) < 6) /* Flawfinder: ignore */ diff --git a/linden/indra/llmath/v3dmath.cpp b/linden/indra/llmath/v3dmath.cpp index b59f519..5a3246c 100644 --- a/linden/indra/llmath/v3dmath.cpp +++ b/linden/indra/llmath/v3dmath.cpp @@ -132,15 +132,15 @@ const LLVector3d& LLVector3d::rotVec(F64 angle, F64 x, F64 y, F64 z) } -BOOL LLVector3d::parseVector3d(const char* buf, LLVector3d* value) +BOOL LLVector3d::parseVector3d(const std::string& buf, LLVector3d* value) { - if( buf == NULL || buf[0] == '\0' || value == NULL) + if( buf.empty() || value == NULL) { return FALSE; } LLVector3d v; - S32 count = sscanf( buf, "%lf %lf %lf", v.mdV + 0, v.mdV + 1, v.mdV + 2 ); + S32 count = sscanf( buf.c_str(), "%lf %lf %lf", v.mdV + 0, v.mdV + 1, v.mdV + 2 ); if( 3 == count ) { value->setVec( v ); diff --git a/linden/indra/llmath/v3dmath.h b/linden/indra/llmath/v3dmath.h index 9bd80b8..ecb333a 100644 --- a/linden/indra/llmath/v3dmath.h +++ b/linden/indra/llmath/v3dmath.h @@ -95,6 +95,10 @@ class LLVector3d F64 magVecSquared() const; // Returns magnitude squared of LLVector3d inline F64 normVec(); // Normalizes and returns the magnitude of LLVector3d + F64 length() const; // Returns magnitude of LLVector3d + F64 lengthSquared() const; // Returns magnitude squared of LLVector3d + inline F64 normalize(); // Normalizes and returns the magnitude of LLVector3d + const LLVector3d& rotVec(const F64 angle, const LLVector3d &vec); // Rotates about vec by angle radians const LLVector3d& rotVec(const F64 angle, const F64 x, const F64 y, const F64 z); // Rotates about x,y,z by angle radians const LLVector3d& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat @@ -128,7 +132,7 @@ class LLVector3d friend std::ostream& operator<<(std::ostream& s, const LLVector3d &a); // Stream a - static BOOL parseVector3d(const char* buf, LLVector3d* value); + static BOOL parseVector3d(const std::string& buf, LLVector3d* value); }; @@ -261,6 +265,28 @@ inline F64 LLVector3d::normVec(void) return (mag); } +inline F64 LLVector3d::normalize(void) +{ + F64 mag = fsqrtf(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); + F64 oomag; + + if (mag > FP_MAG_THRESHOLD) + { + oomag = 1.f/mag; + mdV[0] *= oomag; + mdV[1] *= oomag; + mdV[2] *= oomag; + } + else + { + mdV[0] = 0.f; + mdV[1] = 0.f; + mdV[2] = 0.f; + mag = 0; + } + return (mag); +} + // LLVector3d Magnitude and Normalization Functions inline F64 LLVector3d::magVec(void) const @@ -273,6 +299,16 @@ inline F64 LLVector3d::magVecSquared(void) const return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]; } +inline F64 LLVector3d::length(void) const +{ + return fsqrtf(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); +} + +inline F64 LLVector3d::lengthSquared(void) const +{ + return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]; +} + inline LLVector3d operator+(const LLVector3d &a, const LLVector3d &b) { LLVector3d c(a); @@ -416,8 +452,8 @@ inline F64 angle_between(const LLVector3d& a, const LLVector3d& b) { LLVector3d an = a; LLVector3d bn = b; - an.normVec(); - bn.normVec(); + an.normalize(); + bn.normalize(); F64 cosine = an * bn; F64 angle = (cosine >= 1.0f) ? 0.0f : (cosine <= -1.0f) ? F_PI : @@ -429,8 +465,8 @@ inline BOOL are_parallel(const LLVector3d &a, const LLVector3d &b, const F64 eps { LLVector3d an = a; LLVector3d bn = b; - an.normVec(); - bn.normVec(); + an.normalize(); + bn.normalize(); F64 dot = an * bn; if ( (1.0f - fabs(dot)) < epsilon) { @@ -443,7 +479,7 @@ inline BOOL are_parallel(const LLVector3d &a, const LLVector3d &b, const F64 eps inline LLVector3d projected_vec(const LLVector3d &a, const LLVector3d &b) { LLVector3d project_axis = b; - project_axis.normVec(); + project_axis.normalize(); return project_axis * (a * project_axis); } diff --git a/linden/indra/llmath/v3math.cpp b/linden/indra/llmath/v3math.cpp index bbe460f..cb87836 100644 --- a/linden/indra/llmath/v3math.cpp +++ b/linden/indra/llmath/v3math.cpp @@ -34,6 +34,7 @@ #include "v3math.h" //#include "vmath.h" +#include "v2math.h" #include "v4math.h" #include "m4math.h" #include "m3math.h" @@ -73,6 +74,72 @@ BOOL LLVector3::clamp(F32 min, F32 max) return ret; } +// Clamps length to an upper limit. +// Returns TRUE if the data changed +BOOL LLVector3::clampLength( F32 length_limit ) +{ + BOOL changed = FALSE; + + F32 len = length(); + if (llfinite(len)) + { + if ( len > length_limit) + { + normalize(); + if (length_limit < 0.f) + { + length_limit = 0.f; + } + mV[0] *= length_limit; + mV[1] *= length_limit; + mV[2] *= length_limit; + changed = TRUE; + } + } + else + { // this vector may still be salvagable + F32 max_abs_component = 0.f; + for (S32 i = 0; i < 3; ++i) + { + F32 abs_component = fabs(mV[i]); + if (llfinite(abs_component)) + { + if (abs_component > max_abs_component) + { + max_abs_component = abs_component; + } + } + else + { + // no it can't be salvaged --> clear it + clear(); + changed = TRUE; + break; + } + } + if (!changed) + { + // yes it can be salvaged --> + // bring the components down before we normalize + mV[0] /= max_abs_component; + mV[1] /= max_abs_component; + mV[2] /= max_abs_component; + normalize(); + + if (length_limit < 0.f) + { + length_limit = 0.f; + } + mV[0] *= length_limit; + mV[1] *= length_limit; + mV[2] *= length_limit; + } + } + + return changed; +} + + // Sets all values to absolute value of their original values // Returns TRUE if data changed BOOL LLVector3::abs() @@ -204,6 +271,13 @@ const LLVector3& LLVector3::setVec(const LLVector4 &vec) return (*this); } +LLVector3::LLVector3(const LLVector2 &vec) +{ + mV[VX] = (F32)vec.mV[VX]; + mV[VY] = (F32)vec.mV[VY]; + mV[VZ] = 0; +} + LLVector3::LLVector3(const LLVector3d &vec) { mV[VX] = (F32)vec.mdV[VX]; @@ -260,15 +334,15 @@ const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &rot) } // static -BOOL LLVector3::parseVector3(const char* buf, LLVector3* value) +BOOL LLVector3::parseVector3(const std::string& buf, LLVector3* value) { - if( buf == NULL || buf[0] == '\0' || value == NULL) + if( buf.empty() || value == NULL) { return FALSE; } LLVector3 v; - S32 count = sscanf( buf, "%f %f %f", v.mV + 0, v.mV + 1, v.mV + 2 ); + S32 count = sscanf( buf.c_str(), "%f %f %f", v.mV + 0, v.mV + 1, v.mV + 2 ); if( 3 == count ) { value->setVec( v ); diff --git a/linden/indra/llmath/v3math.h b/linden/indra/llmath/v3math.h index ddb5e1f..65932cd 100644 --- a/linden/indra/llmath/v3math.h +++ b/linden/indra/llmath/v3math.h @@ -36,6 +36,7 @@ #include "llmath.h" #include "llsd.h" +class LLVector2; class LLVector4; class LLMatrix3; class LLVector3d; @@ -62,6 +63,7 @@ class LLVector3 inline LLVector3(); // Initializes LLVector3 to (0, 0, 0) inline LLVector3(const F32 x, const F32 y, const F32 z); // Initializes LLVector3 to (x. y, z) inline explicit LLVector3(const F32 *vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) + explicit LLVector3(const LLVector2 &vec); // Initializes LLVector3 to (vec[0]. vec[1], 0) explicit LLVector3(const LLVector3d &vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) explicit LLVector3(const LLVector4 &vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2]) LLVector3(const LLSD& sd); @@ -74,6 +76,7 @@ class LLVector3 inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite BOOL clamp(F32 min, F32 max); // Clamps all values to (min,max), returns TRUE if data changed + BOOL clampLength( F32 length_limit ); // Scales vector to limit length to a value void quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz); // changes the vector to reflect quatization void quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz); // changes the vector to reflect quatization @@ -147,7 +150,7 @@ class LLVector3 friend std::ostream& operator<<(std::ostream& s, const LLVector3 &a); // Stream a - static BOOL parseVector3(const char* buf, LLVector3* value); + static BOOL parseVector3(const std::string& buf, LLVector3* value); }; typedef LLVector3 LLSimLocalVec; diff --git a/linden/indra/llmath/v4color.cpp b/linden/indra/llmath/v4color.cpp index 8e6907e..88237a0 100644 --- a/linden/indra/llmath/v4color.cpp +++ b/linden/indra/llmath/v4color.cpp @@ -286,16 +286,14 @@ void LLColor4::calcHSL(F32* hue, F32* saturation, F32* luminance) const } // static -BOOL LLColor4::parseColor(const char* buf, LLColor4* color) +BOOL LLColor4::parseColor(const std::string& buf, LLColor4* color) { - if( buf == NULL || buf[0] == '\0' || color == NULL) + if( buf.empty() || color == NULL) { return FALSE; } - LLString full_string(buf); - - boost_tokenizer tokens(full_string, boost::char_separator(", ")); + boost_tokenizer tokens(buf, boost::char_separator(", ")); boost_tokenizer::iterator token_iter = tokens.begin(); if (token_iter == tokens.end()) { @@ -304,15 +302,15 @@ BOOL LLColor4::parseColor(const char* buf, LLColor4* color) // Grab the first token into a string, since we don't know // if this is a float or a color name. - LLString color_name( (*token_iter) ); + std::string color_name( (*token_iter) ); ++token_iter; if (token_iter != tokens.end()) { // There are more tokens to read. This must be a vector. LLColor4 v; - LLString::convertToF32( color_name, v.mV[VX] ); - LLString::convertToF32( *token_iter, v.mV[VY] ); + LLStringUtil::convertToF32( color_name, v.mV[VX] ); + LLStringUtil::convertToF32( *token_iter, v.mV[VY] ); v.mV[VZ] = 0.0f; v.mV[VW] = 1.0f; @@ -320,18 +318,18 @@ BOOL LLColor4::parseColor(const char* buf, LLColor4* color) if (token_iter == tokens.end()) { // This is a malformed vector. - llwarns << "LLColor4::parseColor() malformed color " << full_string << llendl; + llwarns << "LLColor4::parseColor() malformed color " << buf << llendl; } else { // There is a z-component. - LLString::convertToF32( *token_iter, v.mV[VZ] ); + LLStringUtil::convertToF32( *token_iter, v.mV[VZ] ); ++token_iter; if (token_iter != tokens.end()) { // There is an alpha component. - LLString::convertToF32( *token_iter, v.mV[VW] ); + LLStringUtil::convertToF32( *token_iter, v.mV[VW] ); } } @@ -615,19 +613,19 @@ BOOL LLColor4::parseColor(const char* buf, LLColor4* color) } // static -BOOL LLColor4::parseColor4(const char* buf, LLColor4* value) +BOOL LLColor4::parseColor4(const std::string& buf, LLColor4* value) { - if( buf == NULL || buf[0] == '\0' || value == NULL) + if( buf.empty() || value == NULL) { return FALSE; } LLColor4 v; - S32 count = sscanf( buf, "%f, %f, %f, %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); + S32 count = sscanf( buf.c_str(), "%f, %f, %f, %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); if (1 == count ) { // try this format - count = sscanf( buf, "%f %f %f %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); + count = sscanf( buf.c_str(), "%f %f %f %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); } if( 4 == count ) { diff --git a/linden/indra/llmath/v4color.h b/linden/indra/llmath/v4color.h index a2c0fb6..53e4407 100644 --- a/linden/indra/llmath/v4color.h +++ b/linden/indra/llmath/v4color.h @@ -211,8 +211,8 @@ class LLColor4 static LLColor4 cyan5; static LLColor4 cyan6; - static BOOL parseColor(const char* buf, LLColor4* color); - static BOOL parseColor4(const char* buf, LLColor4* color); + static BOOL parseColor(const std::string& buf, LLColor4* color); + static BOOL parseColor4(const std::string& buf, LLColor4* color); inline void clamp(); }; diff --git a/linden/indra/llmath/v4coloru.cpp b/linden/indra/llmath/v4coloru.cpp index 56a8413..7ad7eb2 100644 --- a/linden/indra/llmath/v4coloru.cpp +++ b/linden/indra/llmath/v4coloru.cpp @@ -93,19 +93,19 @@ std::ostream& operator<<(std::ostream& s, const LLColor4U &a) } // static -BOOL LLColor4U::parseColor4U(const char* buf, LLColor4U* value) +BOOL LLColor4U::parseColor4U(const std::string& buf, LLColor4U* value) { - if( buf == NULL || buf[0] == '\0' || value == NULL) + if( buf.empty() || value == NULL) { return FALSE; } U32 v[4]; - S32 count = sscanf( buf, "%u, %u, %u, %u", v + 0, v + 1, v + 2, v + 3 ); + S32 count = sscanf( buf.c_str(), "%u, %u, %u, %u", v + 0, v + 1, v + 2, v + 3 ); if (1 == count ) { // try this format - count = sscanf( buf, "%u %u %u %u", v + 0, v + 1, v + 2, v + 3 ); + count = sscanf( buf.c_str(), "%u %u %u %u", v + 0, v + 1, v + 2, v + 3 ); } if( 4 != count ) { diff --git a/linden/indra/llmath/v4coloru.h b/linden/indra/llmath/v4coloru.h index c9c5418..910a081 100644 --- a/linden/indra/llmath/v4coloru.h +++ b/linden/indra/llmath/v4coloru.h @@ -127,7 +127,7 @@ public: inline void setVecScaleClamp(const LLColor3 &color); inline void setVecScaleClamp(const LLColor4 &color); - static BOOL parseColor4U(const char* buf, LLColor4U* value); + static BOOL parseColor4U(const std::string& buf, LLColor4U* value); static LLColor4U white; static LLColor4U black; -- cgit v1.1