aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRevolutionSmythe2011-03-18 17:32:12 -0500
committerRevolutionSmythe2011-03-18 17:32:12 -0500
commit892e8b82d84266f8bdfbd5c2cdd388f71c208035 (patch)
tree5401ea123b868931342000db3f23ff60724746dd
parentfix bogus in install.xml (diff)
downloadmeta-impy-892e8b82d84266f8bdfbd5c2cdd388f71c208035.zip
meta-impy-892e8b82d84266f8bdfbd5c2cdd388f71c208035.tar.gz
meta-impy-892e8b82d84266f8bdfbd5c2cdd388f71c208035.tar.bz2
meta-impy-892e8b82d84266f8bdfbd5c2cdd388f71c208035.tar.xz
Merge in Var Sized Regions into the Imprudence Experimental.
-rw-r--r--linden/indra/llcommon/indra_constants.h7
-rw-r--r--linden/indra/llinventory/llparcel.h3
-rw-r--r--linden/indra/llmessage/message_prehash.cpp4
-rw-r--r--linden/indra/llmessage/message_prehash.h4
-rw-r--r--linden/indra/llmessage/patch_code.cpp13
-rw-r--r--linden/indra/llmessage/patch_code.h2
-rw-r--r--linden/indra/llmessage/patch_dct.h2
-rwxr-xr-xlinden/indra/llwindow/glh/glh_linear.h3242
-rw-r--r--linden/indra/newview/llcloud.cpp2
-rw-r--r--linden/indra/newview/llfloaterregioninfo.cpp8
-rw-r--r--linden/indra/newview/llglsandbox.cpp2
-rw-r--r--linden/indra/newview/llmapresponders.cpp4
-rw-r--r--linden/indra/newview/llstartup.cpp14
-rw-r--r--linden/indra/newview/llsurface.cpp20
-rwxr-xr-xlinden/indra/newview/llviewermessage.cpp27
-rw-r--r--linden/indra/newview/llviewerparcelmgr.cpp22
-rw-r--r--linden/indra/newview/llviewerparcelmgr.h2
-rw-r--r--linden/indra/newview/llviewerparceloverlay.cpp4
-rw-r--r--linden/indra/newview/llviewerparceloverlay.h1
-rw-r--r--linden/indra/newview/llviewerregion.cpp3
-rw-r--r--linden/indra/newview/llvlmanager.cpp61
-rw-r--r--linden/indra/newview/llvowater.cpp2
-rw-r--r--linden/indra/newview/llwind.cpp4
-rw-r--r--linden/indra/newview/llworld.cpp27
-rw-r--r--linden/indra/newview/llworld.h6
-rw-r--r--linden/indra/newview/llworldmap.cpp29
-rw-r--r--linden/indra/newview/llworldmap.h2
-rw-r--r--linden/indra/newview/llworldmapview.cpp14
28 files changed, 1823 insertions, 1708 deletions
diff --git a/linden/indra/llcommon/indra_constants.h b/linden/indra/llcommon/indra_constants.h
index 279d280..ae1e04a 100644
--- a/linden/indra/llcommon/indra_constants.h
+++ b/linden/indra/llcommon/indra_constants.h
@@ -151,7 +151,12 @@ const U32 PORT_DISCOVERY_RANGE_MAX = PORT_DISCOVERY_RANGE_MIN + 50;
151const char LAND_LAYER_CODE = 'L'; 151const char LAND_LAYER_CODE = 'L';
152const char WATER_LAYER_CODE = 'W'; 152const char WATER_LAYER_CODE = 'W';
153const char WIND_LAYER_CODE = '7'; 153const char WIND_LAYER_CODE = '7';
154const char CLOUD_LAYER_CODE = '8'; 154const char CLOUD_LAYER_CODE = '8';
155
156// Extended land layer for Aurora Sim
157const char AURORA_LAND_LAYER_CODE = 'M';
158const char AURORA_WIND_LAYER_CODE = '9';
159const char AURORA_CLOUD_LAYER_CODE = ':';
155 160
156// keys 161// keys
157// Bit masks for various keyboard modifier keys. 162// Bit masks for various keyboard modifier keys.
diff --git a/linden/indra/llinventory/llparcel.h b/linden/indra/llinventory/llparcel.h
index 8faa673..366f589 100644
--- a/linden/indra/llinventory/llparcel.h
+++ b/linden/indra/llinventory/llparcel.h
@@ -66,7 +66,8 @@ const S32 PARCEL_PASS_PRICE_DEFAULT = 10;
66const F32 PARCEL_PASS_HOURS_DEFAULT = 1.f; 66const F32 PARCEL_PASS_HOURS_DEFAULT = 1.f;
67 67
68// Number of "chunks" in which parcel overlay data is sent 68// Number of "chunks" in which parcel overlay data is sent
69// Chunk 0 = southern rows, entire width 69// Chunk 0 = southern rows, entire width
70// NOTE: NOT USABLE FOR VAR SIZED REGIONS!
70const S32 PARCEL_OVERLAY_CHUNKS = 4; 71const S32 PARCEL_OVERLAY_CHUNKS = 4;
71 72
72// Bottom three bits are a color index for the land overlay 73// Bottom three bits are a color index for the land overlay
diff --git a/linden/indra/llmessage/message_prehash.cpp b/linden/indra/llmessage/message_prehash.cpp
index ecb45bf..a8b021f 100644
--- a/linden/indra/llmessage/message_prehash.cpp
+++ b/linden/indra/llmessage/message_prehash.cpp
@@ -586,7 +586,9 @@ char* _PREHASH_NotecardItemID = LLMessageStringTable::getInstance()->getString("
586char* _PREHASH_LastName = LLMessageStringTable::getInstance()->getString("LastName"); 586char* _PREHASH_LastName = LLMessageStringTable::getInstance()->getString("LastName");
587char* _PREHASH_From = LLMessageStringTable::getInstance()->getString("From"); 587char* _PREHASH_From = LLMessageStringTable::getInstance()->getString("From");
588char* _PREHASH_RoleChange = LLMessageStringTable::getInstance()->getString("RoleChange"); 588char* _PREHASH_RoleChange = LLMessageStringTable::getInstance()->getString("RoleChange");
589char* _PREHASH_Port = LLMessageStringTable::getInstance()->getString("Port"); 589char* _PREHASH_Port = LLMessageStringTable::getInstance()->getString("Port");
590char* _PREHASH_RegionSizeX = LLMessageStringTable::getInstance()->getString("RegionSizeX");
591char* _PREHASH_RegionSizeY = LLMessageStringTable::getInstance()->getString("RegionSizeY");
590char* _PREHASH_MemberTitle = LLMessageStringTable::getInstance()->getString("MemberTitle"); 592char* _PREHASH_MemberTitle = LLMessageStringTable::getInstance()->getString("MemberTitle");
591char* _PREHASH_LogParcelChanges = LLMessageStringTable::getInstance()->getString("LogParcelChanges"); 593char* _PREHASH_LogParcelChanges = LLMessageStringTable::getInstance()->getString("LogParcelChanges");
592char* _PREHASH_AgentCachedTextureResponse = LLMessageStringTable::getInstance()->getString("AgentCachedTextureResponse"); 594char* _PREHASH_AgentCachedTextureResponse = LLMessageStringTable::getInstance()->getString("AgentCachedTextureResponse");
diff --git a/linden/indra/llmessage/message_prehash.h b/linden/indra/llmessage/message_prehash.h
index 8516483..adf27ee 100644
--- a/linden/indra/llmessage/message_prehash.h
+++ b/linden/indra/llmessage/message_prehash.h
@@ -586,7 +586,9 @@ extern char * _PREHASH_NotecardItemID;
586extern char * _PREHASH_LastName; 586extern char * _PREHASH_LastName;
587extern char * _PREHASH_From; 587extern char * _PREHASH_From;
588extern char * _PREHASH_RoleChange; 588extern char * _PREHASH_RoleChange;
589extern char * _PREHASH_Port; 589extern char * _PREHASH_Port;
590extern char * _PREHASH_RegionSizeX;
591extern char * _PREHASH_RegionSizeY;
590extern char * _PREHASH_MemberTitle; 592extern char * _PREHASH_MemberTitle;
591extern char * _PREHASH_LogParcelChanges; 593extern char * _PREHASH_LogParcelChanges;
592extern char * _PREHASH_AgentCachedTextureResponse; 594extern char * _PREHASH_AgentCachedTextureResponse;
diff --git a/linden/indra/llmessage/patch_code.cpp b/linden/indra/llmessage/patch_code.cpp
index 90fb236..4b4313d 100644
--- a/linden/indra/llmessage/patch_code.cpp
+++ b/linden/indra/llmessage/patch_code.cpp
@@ -235,7 +235,7 @@ void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp)
235 gPatchSize = gopp->patch_size; 235 gPatchSize = gopp->patch_size;
236} 236}
237 237
238void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph) 238void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, BOOL b_large_patch)
239{ 239{
240 U8 retvalu8; 240 U8 retvalu8;
241 241
@@ -274,15 +274,18 @@ void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph)
274#endif 274#endif
275 ph->range = retvalu16; 275 ph->range = retvalu16;
276 276
277 retvalu16 = 0; 277 retvalu32 = 0;
278#ifdef LL_BIG_ENDIAN 278#ifdef LL_BIG_ENDIAN
279 ret = (U8 *)&retvalu16; 279 ret = (U8 *)&retvalu16;
280 bitpack.bitUnpack(&(ret[1]), 8); 280 bitpack.bitUnpack(&(ret[1]), 8);
281 bitpack.bitUnpack(&(ret[0]), 2); 281 bitpack.bitUnpack(&(ret[0]), 2);
282#else 282#else
283 bitpack.bitUnpack((U8 *)&retvalu16, 10); 283 if (b_large_patch)
284#endif 284 bitpack.bitUnpack((U8 *)&retvalu32, 32);
285 ph->patchids = retvalu16; 285 else
286 bitpack.bitUnpack((U8 *)&retvalu32, 10);
287#endif
288 ph->patchids = retvalu32;
286 289
287 gWordBits = (ph->quant_wbits & 0xf) + 2; 290 gWordBits = (ph->quant_wbits & 0xf) + 2;
288} 291}
diff --git a/linden/indra/llmessage/patch_code.h b/linden/indra/llmessage/patch_code.h
index 82fa6bb..dbfdf70 100644
--- a/linden/indra/llmessage/patch_code.h
+++ b/linden/indra/llmessage/patch_code.h
@@ -46,7 +46,7 @@ void end_patch_coding(LLBitPack &bitpack);
46 46
47void init_patch_decoding(LLBitPack &bitpack); 47void init_patch_decoding(LLBitPack &bitpack);
48void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp); 48void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp);
49void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph); 49void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, BOOL b_large_patch);
50void decode_patch(LLBitPack &bitpack, S32 *patches); 50void decode_patch(LLBitPack &bitpack, S32 *patches);
51 51
52#endif 52#endif
diff --git a/linden/indra/llmessage/patch_dct.h b/linden/indra/llmessage/patch_dct.h
index 663e146..ba21be7 100644
--- a/linden/indra/llmessage/patch_dct.h
+++ b/linden/indra/llmessage/patch_dct.h
@@ -79,7 +79,7 @@ public:
79 F32 dc_offset; // 4 bytes 79 F32 dc_offset; // 4 bytes
80 U16 range; // 2 = 7 ((S16) FP range (breaks if we need > 32K meters in 1 patch) 80 U16 range; // 2 = 7 ((S16) FP range (breaks if we need > 32K meters in 1 patch)
81 U8 quant_wbits; // 1 = 8 (upper 4 bits is quant - 2, lower 4 bits is word bits - 2) 81 U8 quant_wbits; // 1 = 8 (upper 4 bits is quant - 2, lower 4 bits is word bits - 2)
82 U16 patchids; // 2 = 10 (actually only uses 10 bits, 5 for each) 82 U32 patchids; // 2 = 10 (actually only uses 10 bits, 5 for each)
83}; 83};
84 84
85// Compression routines 85// Compression routines
diff --git a/linden/indra/llwindow/glh/glh_linear.h b/linden/indra/llwindow/glh/glh_linear.h
index 04ae1bd..bb59d7e 100755
--- a/linden/indra/llwindow/glh/glh_linear.h
+++ b/linden/indra/llwindow/glh/glh_linear.h
@@ -1,1621 +1,1621 @@
1/* 1/*
2 glh - is a platform-indepenedent C++ OpenGL helper library 2 glh - is a platform-indepenedent C++ OpenGL helper library
3 3
4 4
5 Copyright (c) 2000 Cass Everitt 5 Copyright (c) 2000 Cass Everitt
6 Copyright (c) 2000 NVIDIA Corporation 6 Copyright (c) 2000 NVIDIA Corporation
7 All rights reserved. 7 All rights reserved.
8 8
9 Redistribution and use in source and binary forms, with or 9 Redistribution and use in source and binary forms, with or
10 without modification, are permitted provided that the following 10 without modification, are permitted provided that the following
11 conditions are met: 11 conditions are met:
12 12
13 * Redistributions of source code must retain the above 13 * Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the following 14 copyright notice, this list of conditions and the following
15 disclaimer. 15 disclaimer.
16 16
17 * Redistributions in binary form must reproduce the above 17 * Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the following 18 copyright notice, this list of conditions and the following
19 disclaimer in the documentation and/or other materials 19 disclaimer in the documentation and/or other materials
20 provided with the distribution. 20 provided with the distribution.
21 21
22 * The names of contributors to this software may not be used 22 * The names of contributors to this software may not be used
23 to endorse or promote products derived from this software 23 to endorse or promote products derived from this software
24 without specific prior written permission. 24 without specific prior written permission.
25 25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 30 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 32 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 33 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 POSSIBILITY OF SUCH DAMAGE. 37 POSSIBILITY OF SUCH DAMAGE.
38 38
39 39
40 Cass Everitt - cass@r3.nu 40 Cass Everitt - cass@r3.nu
41*/ 41*/
42 42
43/* 43/*
44glh_linear.h 44glh_linear.h
45*/ 45*/
46 46
47// Author: Cass W. Everitt 47// Author: Cass W. Everitt
48 48
49#ifndef GLH_LINEAR_H 49#ifndef GLH_LINEAR_H
50#define GLH_LINEAR_H 50#define GLH_LINEAR_H
51 51
52#include <memory.h> 52#include <memory.h>
53#include <math.h> 53#include <math.h>
54#include <assert.h> 54#include <assert.h>
55 55
56// only supports float for now... 56// only supports float for now...
57#define GLH_REAL_IS_FLOAT 57#define GLH_REAL_IS_FLOAT
58 58
59#ifdef GLH_REAL_IS_FLOAT 59#ifdef GLH_REAL_IS_FLOAT
60# define GLH_REAL float 60# define GLH_REAL float
61# define GLH_REAL_NAMESPACE ns_float 61# define GLH_REAL_NAMESPACE ns_float
62#endif 62#endif
63 63
64#define GLH_QUATERNION_NORMALIZATION_THRESHOLD 64 64#define GLH_QUATERNION_NORMALIZATION_THRESHOLD 64
65 65
66#define GLH_RAD_TO_DEG GLH_REAL(57.2957795130823208767981548141052) 66#define GLH_RAD_TO_DEG GLH_REAL(57.2957795130823208767981548141052)
67#define GLH_DEG_TO_RAD GLH_REAL(0.0174532925199432957692369076848861) 67#define GLH_DEG_TO_RAD GLH_REAL(0.0174532925199432957692369076848861)
68#define GLH_ZERO GLH_REAL(0.0) 68#define GLH_ZERO GLH_REAL(0.0)
69#define GLH_ONE GLH_REAL(1.0) 69#define GLH_ONE GLH_REAL(1.0)
70#define GLH_TWO GLH_REAL(2.0) 70#define GLH_TWO GLH_REAL(2.0)
71#define GLH_EPSILON GLH_REAL(10e-6) 71#define GLH_EPSILON GLH_REAL(10e-6)
72#define GLH_PI GLH_REAL(3.1415926535897932384626433832795) 72#define GLH_PI GLH_REAL(3.1415926535897932384626433832795)
73 73
74#define equivalent(a,b) (((a < b + GLH_EPSILON) && (a > b - GLH_EPSILON)) ? true : false) 74#define equivalent(a,b) (((a < b + GLH_EPSILON) && (a > b - GLH_EPSILON)) ? true : false)
75 75
76namespace glh 76namespace glh
77{ 77{
78 78
79 inline GLH_REAL to_degrees(GLH_REAL radians) { return radians*GLH_RAD_TO_DEG; } 79 inline GLH_REAL to_degrees(GLH_REAL radians) { return radians*GLH_RAD_TO_DEG; }
80 inline GLH_REAL to_radians(GLH_REAL degrees) { return degrees*GLH_DEG_TO_RAD; } 80 inline GLH_REAL to_radians(GLH_REAL degrees) { return degrees*GLH_DEG_TO_RAD; }
81 81
82 // forward declarations for friend template functions. 82 // forward declarations for friend template functions.
83 template <int N, class T> class vec; 83 template <int N, class T> class vec;
84 84
85 // forward declarations for friend template functions. 85 // forward declarations for friend template functions.
86 template <int N, class T> 86 template <int N, class T>
87 bool operator == ( const vec<N,T> & v1, const vec<N,T> & v2 ); 87 bool operator == ( const vec<N,T> & v1, const vec<N,T> & v2 );
88 88
89 // forward declarations for friend template functions. 89 // forward declarations for friend template functions.
90 template <int N, class T> 90 template <int N, class T>
91 bool operator != ( const vec<N,T> & v1, const vec<N,T> & v2 ); 91 bool operator != ( const vec<N,T> & v1, const vec<N,T> & v2 );
92 92
93 template <int N, class T> 93 template <int N, class T>
94 class vec 94 class vec
95 { 95 {
96 public: 96 public:
97 int size() const { return N; } 97 int size() const { return N; }
98 98
99 vec(const T & t = T()) 99 vec(const T & t = T())
100 { for(int i = 0; i < N; i++) v[i] = t; } 100 { for(int i = 0; i < N; i++) v[i] = t; }
101 vec(const T * tp) 101 vec(const T * tp)
102 { for(int i = 0; i < N; i++) v[i] = tp[i]; } 102 { for(int i = 0; i < N; i++) v[i] = tp[i]; }
103 103
104 const T * get_value() const 104 const T * get_value() const
105 { return v; } 105 { return v; }
106 106
107 107
108 T dot( const vec<N,T> & rhs ) const 108 T dot( const vec<N,T> & rhs ) const
109 { 109 {
110 T r = 0; 110 T r = 0;
111 for(int i = 0; i < N; i++) r += v[i]*rhs.v[i]; 111 for(int i = 0; i < N; i++) r += v[i]*rhs.v[i];
112 return r; 112 return r;
113 } 113 }
114 114
115 T length() const 115 T length() const
116 { 116 {
117 T r = 0; 117 T r = 0;
118 for(int i = 0; i < N; i++) r += v[i]*v[i]; 118 for(int i = 0; i < N; i++) r += v[i]*v[i];
119 return T(sqrt(r)); 119 return T(sqrt(r));
120 } 120 }
121 121
122 T square_norm() const 122 T square_norm() const
123 { 123 {
124 T r = 0; 124 T r = 0;
125 for(int i = 0; i < N; i++) r += v[i]*v[i]; 125 for(int i = 0; i < N; i++) r += v[i]*v[i];
126 return r; 126 return r;
127 } 127 }
128 128
129 void negate() 129 void negate()
130 { for(int i = 0; i < N; i++) v[i] = -v[i]; } 130 { for(int i = 0; i < N; i++) v[i] = -v[i]; }
131 131
132 132
133 T normalize() 133 T normalize()
134 { 134 {
135 T sum(0); 135 T sum(0);
136 for(int i = 0; i < N; i++) 136 for(int i = 0; i < N; i++)
137 sum += v[i]*v[i]; 137 sum += v[i]*v[i];
138 sum = T(sqrt(sum)); 138 sum = T(sqrt(sum));
139 if (sum > GLH_EPSILON) 139 if (sum > GLH_EPSILON)
140 for(int i = 0; i < N; i++) 140 for(int i = 0; i < N; i++)
141 v[i] /= sum; 141 v[i] /= sum;
142 return sum; 142 return sum;
143 } 143 }
144 144
145 145
146 vec<N,T> & set_value( const T * rhs ) 146 vec<N,T> & set_value( const T * rhs )
147 { for(int i = 0; i < N; i++) v[i] = rhs[i]; return *this; } 147 { for(int i = 0; i < N; i++) v[i] = rhs[i]; return *this; }
148 148
149 T & operator [] ( int i ) 149 T & operator [] ( int i )
150 { return v[i]; } 150 { return v[i]; }
151 151
152 const T & operator [] ( int i ) const 152 const T & operator [] ( int i ) const
153 { return v[i]; } 153 { return v[i]; }
154 154
155 vec<N,T> & operator *= ( T d ) 155 vec<N,T> & operator *= ( T d )
156 { for(int i = 0; i < N; i++) v[i] *= d; return *this;} 156 { for(int i = 0; i < N; i++) v[i] *= d; return *this;}
157 157
158 vec<N,T> & operator *= ( const vec<N,T> & u ) 158 vec<N,T> & operator *= ( const vec<N,T> & u )
159 { for(int i = 0; i < N; i++) v[i] *= u[i]; return *this;} 159 { for(int i = 0; i < N; i++) v[i] *= u[i]; return *this;}
160 160
161 vec<N,T> & operator /= ( T d ) 161 vec<N,T> & operator /= ( T d )
162 { if(d == 0) return *this; for(int i = 0; i < N; i++) v[i] /= d; return *this;} 162 { if(d == 0) return *this; for(int i = 0; i < N; i++) v[i] /= d; return *this;}
163 163
164 vec<N,T> & operator += ( const vec<N,T> & u ) 164 vec<N,T> & operator += ( const vec<N,T> & u )
165 { for(int i = 0; i < N; i++) v[i] += u.v[i]; return *this;} 165 { for(int i = 0; i < N; i++) v[i] += u.v[i]; return *this;}
166 166
167 vec<N,T> & operator -= ( const vec<N,T> & u ) 167 vec<N,T> & operator -= ( const vec<N,T> & u )
168 { for(int i = 0; i < N; i++) v[i] -= u.v[i]; return *this;} 168 { for(int i = 0; i < N; i++) v[i] -= u.v[i]; return *this;}
169 169
170 170
171 vec<N,T> operator - () const 171 vec<N,T> operator - () const
172 { vec<N,T> rv = v; rv.negate(); return rv; } 172 { vec<N,T> rv = v; rv.negate(); return rv; }
173 173
174 vec<N,T> operator + ( const vec<N,T> &v) const 174 vec<N,T> operator + ( const vec<N,T> &v) const
175 { vec<N,T> rt(*this); return rt += v; } 175 { vec<N,T> rt(*this); return rt += v; }
176 176
177 vec<N,T> operator - ( const vec<N,T> &v) const 177 vec<N,T> operator - ( const vec<N,T> &v) const
178 { vec<N,T> rt(*this); return rt -= v; } 178 { vec<N,T> rt(*this); return rt -= v; }
179 179
180 vec<N,T> operator * ( T d) const 180 vec<N,T> operator * ( T d) const
181 { vec<N,T> rt(*this); return rt *= d; } 181 { vec<N,T> rt(*this); return rt *= d; }
182 182
183 friend bool operator == <> ( const vec<N,T> &v1, const vec<N,T> &v2 ); 183 friend bool operator == <> ( const vec<N,T> &v1, const vec<N,T> &v2 );
184 friend bool operator != <> ( const vec<N,T> &v1, const vec<N,T> &v2 ); 184 friend bool operator != <> ( const vec<N,T> &v1, const vec<N,T> &v2 );
185 185
186 186
187 //protected: 187 //protected:
188 T v[N]; 188 T v[N];
189 }; 189 };
190 190
191 191
192 192
193 // vector friend operators 193 // vector friend operators
194 194
195 template <int N, class T> inline 195 template <int N, class T> inline
196 vec<N,T> operator * ( const vec<N,T> & b, T d ) 196 vec<N,T> operator * ( const vec<N,T> & b, T d )
197 { 197 {
198 vec<N,T> rt(b); 198 vec<N,T> rt(b);
199 return rt *= d; 199 return rt *= d;
200 } 200 }
201 201
202 template <int N, class T> inline 202 template <int N, class T> inline
203 vec<N,T> operator * ( T d, const vec<N,T> & b ) 203 vec<N,T> operator * ( T d, const vec<N,T> & b )
204 { return b*d; } 204 { return b*d; }
205 205
206 template <int N, class T> inline 206 template <int N, class T> inline
207 vec<N,T> operator * ( const vec<N,T> & b, const vec<N,T> & d ) 207 vec<N,T> operator * ( const vec<N,T> & b, const vec<N,T> & d )
208 { 208 {
209 vec<N,T> rt(b); 209 vec<N,T> rt(b);
210 return rt *= d; 210 return rt *= d;
211 } 211 }
212 212
213 template <int N, class T> inline 213 template <int N, class T> inline
214 vec<N,T> operator / ( const vec<N,T> & b, T d ) 214 vec<N,T> operator / ( const vec<N,T> & b, T d )
215 { vec<N,T> rt(b); return rt /= d; } 215 { vec<N,T> rt(b); return rt /= d; }
216 216
217 template <int N, class T> inline 217 template <int N, class T> inline
218 vec<N,T> operator + ( const vec<N,T> & v1, const vec<N,T> & v2 ) 218 vec<N,T> operator + ( const vec<N,T> & v1, const vec<N,T> & v2 )
219 { vec<N,T> rt(v1); return rt += v2; } 219 { vec<N,T> rt(v1); return rt += v2; }
220 220
221 template <int N, class T> inline 221 template <int N, class T> inline
222 vec<N,T> operator - ( const vec<N,T> & v1, const vec<N,T> & v2 ) 222 vec<N,T> operator - ( const vec<N,T> & v1, const vec<N,T> & v2 )
223 { vec<N,T> rt(v1); return rt -= v2; } 223 { vec<N,T> rt(v1); return rt -= v2; }
224 224
225 225
226 template <int N, class T> inline 226 template <int N, class T> inline
227 bool operator == ( const vec<N,T> & v1, const vec<N,T> & v2 ) 227 bool operator == ( const vec<N,T> & v1, const vec<N,T> & v2 )
228 { 228 {
229 for(int i = 0; i < N; i++) 229 for(int i = 0; i < N; i++)
230 if(v1.v[i] != v2.v[i]) 230 if(v1.v[i] != v2.v[i])
231 return false; 231 return false;
232 return true; 232 return true;
233 } 233 }
234 234
235 template <int N, class T> inline 235 template <int N, class T> inline
236 bool operator != ( const vec<N,T> & v1, const vec<N,T> & v2 ) 236 bool operator != ( const vec<N,T> & v1, const vec<N,T> & v2 )
237 { return !(v1 == v2); } 237 { return !(v1 == v2); }
238 238
239 239
240 typedef vec<3,unsigned char> vec3ub; 240 typedef vec<3,unsigned char> vec3ub;
241 typedef vec<4,unsigned char> vec4ub; 241 typedef vec<4,unsigned char> vec4ub;
242 242
243 243
244 244
245 245
246 246
247 namespace GLH_REAL_NAMESPACE 247 namespace GLH_REAL_NAMESPACE
248 { 248 {
249 typedef GLH_REAL real; 249 typedef GLH_REAL real;
250 250
251 class line; 251 class line;
252 class plane; 252 class plane;
253 class matrix4; 253 class matrix4;
254 class quaternion; 254 class quaternion;
255 typedef quaternion rotation; 255 typedef quaternion rotation;
256 256
257 class vec2 : public vec<2,real> 257 class vec2 : public vec<2,real>
258 { 258 {
259 public: 259 public:
260 vec2(const real & t = real()) : vec<2,real>(t) 260 vec2(const real & t = real()) : vec<2,real>(t)
261 {} 261 {}
262 vec2(const vec<2,real> & t) : vec<2,real>(t) 262 vec2(const vec<2,real> & t) : vec<2,real>(t)
263 {} 263 {}
264 vec2(const real * tp) : vec<2,real>(tp) 264 vec2(const real * tp) : vec<2,real>(tp)
265 {} 265 {}
266 266
267 vec2(real x, real y ) 267 vec2(real x, real y )
268 { v[0] = x; v[1] = y; } 268 { v[0] = x; v[1] = y; }
269 269
270 void get_value(real & x, real & y) const 270 void get_value(real & x, real & y) const
271 { x = v[0]; y = v[1]; } 271 { x = v[0]; y = v[1]; }
272 272
273 vec2 & set_value( const real & x, const real & y) 273 vec2 & set_value( const real & x, const real & y)
274 { v[0] = x; v[1] = y; return *this; } 274 { v[0] = x; v[1] = y; return *this; }
275 275
276 }; 276 };
277 277
278 278
279 class vec3 : public vec<3,real> 279 class vec3 : public vec<3,real>
280 { 280 {
281 public: 281 public:
282 vec3(const real & t = real()) : vec<3,real>(t) 282 vec3(const real & t = real()) : vec<3,real>(t)
283 {} 283 {}
284 vec3(const vec<3,real> & t) : vec<3,real>(t) 284 vec3(const vec<3,real> & t) : vec<3,real>(t)
285 {} 285 {}
286 vec3(const real * tp) : vec<3,real>(tp) 286 vec3(const real * tp) : vec<3,real>(tp)
287 {} 287 {}
288 288
289 vec3(real x, real y, real z) 289 vec3(real x, real y, real z)
290 { v[0] = x; v[1] = y; v[2] = z; } 290 { v[0] = x; v[1] = y; v[2] = z; }
291 291
292 void get_value(real & x, real & y, real & z) const 292 void get_value(real & x, real & y, real & z) const
293 { x = v[0]; y = v[1]; z = v[2]; } 293 { x = v[0]; y = v[1]; z = v[2]; }
294 294
295 vec3 cross( const vec3 &rhs ) const 295 vec3 cross( const vec3 &rhs ) const
296 { 296 {
297 vec3 rt; 297 vec3 rt;
298 rt.v[0] = v[1]*rhs.v[2]-v[2]*rhs.v[1]; 298 rt.v[0] = v[1]*rhs.v[2]-v[2]*rhs.v[1];
299 rt.v[1] = v[2]*rhs.v[0]-v[0]*rhs.v[2]; 299 rt.v[1] = v[2]*rhs.v[0]-v[0]*rhs.v[2];
300 rt.v[2] = v[0]*rhs.v[1]-v[1]*rhs.v[0]; 300 rt.v[2] = v[0]*rhs.v[1]-v[1]*rhs.v[0];
301 return rt; 301 return rt;
302 } 302 }
303 303
304 vec3 & set_value( const real & x, const real & y, const real & z) 304 vec3 & set_value( const real & x, const real & y, const real & z)
305 { v[0] = x; v[1] = y; v[2] = z; return *this; } 305 { v[0] = x; v[1] = y; v[2] = z; return *this; }
306 306
307 }; 307 };
308 308
309 309
310 class vec4 : public vec<4,real> 310 class vec4 : public vec<4,real>
311 { 311 {
312 public: 312 public:
313 vec4(const real & t = real()) : vec<4,real>(t) 313 vec4(const real & t = real()) : vec<4,real>(t)
314 {} 314 {}
315 vec4(const vec<4,real> & t) : vec<4,real>(t) 315 vec4(const vec<4,real> & t) : vec<4,real>(t)
316 {} 316 {}
317 317
318 vec4(const vec<3,real> & t, real fourth) 318 vec4(const vec<3,real> & t, real fourth)
319 319
320 { v[0] = t.v[0]; v[1] = t.v[1]; v[2] = t.v[2]; v[3] = fourth; } 320 { v[0] = t.v[0]; v[1] = t.v[1]; v[2] = t.v[2]; v[3] = fourth; }
321 vec4(const real * tp) : vec<4,real>(tp) 321 vec4(const real * tp) : vec<4,real>(tp)
322 {} 322 {}
323 vec4(real x, real y, real z, real w) 323 vec4(real x, real y, real z, real w)
324 { v[0] = x; v[1] = y; v[2] = z; v[3] = w; } 324 { v[0] = x; v[1] = y; v[2] = z; v[3] = w; }
325 325
326 void get_value(real & x, real & y, real & z, real & w) const 326 void get_value(real & x, real & y, real & z, real & w) const
327 { x = v[0]; y = v[1]; z = v[2]; w = v[3]; } 327 { x = v[0]; y = v[1]; z = v[2]; w = v[3]; }
328 328
329 vec4 & set_value( const real & x, const real & y, const real & z, const real & w) 329 vec4 & set_value( const real & x, const real & y, const real & z, const real & w)
330 { v[0] = x; v[1] = y; v[2] = z; v[3] = w; return *this; } 330 { v[0] = x; v[1] = y; v[2] = z; v[3] = w; return *this; }
331 }; 331 };
332 332
333 inline 333 inline
334 vec3 homogenize(const vec4 & v) 334 vec3 homogenize(const vec4 & v)
335 { 335 {
336 vec3 rt; 336 vec3 rt;
337 assert(v.v[3] != GLH_ZERO); 337 assert(v.v[3] != GLH_ZERO);
338 rt.v[0] = v.v[0]/v.v[3]; 338 rt.v[0] = v.v[0]/v.v[3];
339 rt.v[1] = v.v[1]/v.v[3]; 339 rt.v[1] = v.v[1]/v.v[3];
340 rt.v[2] = v.v[2]/v.v[3]; 340 rt.v[2] = v.v[2]/v.v[3];
341 return rt; 341 return rt;
342 } 342 }
343 343
344 344
345 345
346 class line 346 class line
347 { 347 {
348 public: 348 public:
349 349
350 line() 350 line()
351 { set_value(vec3(0,0,0),vec3(0,0,1)); } 351 { set_value(vec3(0,0,0),vec3(0,0,1)); }
352 352
353 line( const vec3 & p0, const vec3 &p1) 353 line( const vec3 & p0, const vec3 &p1)
354 { set_value(p0,p1); } 354 { set_value(p0,p1); }
355 355
356 void set_value( const vec3 &p0, const vec3 &p1) 356 void set_value( const vec3 &p0, const vec3 &p1)
357 { 357 {
358 position = p0; 358 position = p0;
359 direction = p1-p0; 359 direction = p1-p0;
360 direction.normalize(); 360 direction.normalize();
361 } 361 }
362 362
363 bool get_closest_points(const line &line2, 363 bool get_closest_points(const line &line2,
364 vec3 &pointOnThis, 364 vec3 &pointOnThis,
365 vec3 &pointOnThat) 365 vec3 &pointOnThat)
366 { 366 {
367 367
368 // quick check to see if parallel -- if so, quit. 368 // quick check to see if parallel -- if so, quit.
369 if(fabs(direction.dot(line2.direction)) == 1.0) 369 if(fabs(direction.dot(line2.direction)) == 1.0)
370 return 0; 370 return 0;
371 line l2 = line2; 371 line l2 = line2;
372 372
373 // Algorithm: Brian Jean 373 // Algorithm: Brian Jean
374 // 374 //
375 register real u; 375 register real u;
376 register real v; 376 register real v;
377 vec3 Vr = direction; 377 vec3 Vr = direction;
378 vec3 Vs = l2.direction; 378 vec3 Vs = l2.direction;
379 register real Vr_Dot_Vs = Vr.dot(Vs); 379 register real Vr_Dot_Vs = Vr.dot(Vs);
380 register real detA = real(1.0 - (Vr_Dot_Vs * Vr_Dot_Vs)); 380 register real detA = real(1.0 - (Vr_Dot_Vs * Vr_Dot_Vs));
381 vec3 C = l2.position - position; 381 vec3 C = l2.position - position;
382 register real C_Dot_Vr = C.dot(Vr); 382 register real C_Dot_Vr = C.dot(Vr);
383 register real C_Dot_Vs = C.dot(Vs); 383 register real C_Dot_Vs = C.dot(Vs);
384 384
385 u = (C_Dot_Vr - Vr_Dot_Vs * C_Dot_Vs)/detA; 385 u = (C_Dot_Vr - Vr_Dot_Vs * C_Dot_Vs)/detA;
386 v = (C_Dot_Vr * Vr_Dot_Vs - C_Dot_Vs)/detA; 386 v = (C_Dot_Vr * Vr_Dot_Vs - C_Dot_Vs)/detA;
387 387
388 pointOnThis = position; 388 pointOnThis = position;
389 pointOnThis += direction * u; 389 pointOnThis += direction * u;
390 pointOnThat = l2.position; 390 pointOnThat = l2.position;
391 pointOnThat += l2.direction * v; 391 pointOnThat += l2.direction * v;
392 392
393 return 1; 393 return 1;
394 } 394 }
395 395
396 vec3 get_closest_point(const vec3 &point) 396 vec3 get_closest_point(const vec3 &point)
397 { 397 {
398 vec3 np = point - position; 398 vec3 np = point - position;
399 vec3 rp = direction*direction.dot(np)+position; 399 vec3 rp = direction*direction.dot(np)+position;
400 return rp; 400 return rp;
401 } 401 }
402 402
403 const vec3 & get_position() const {return position;} 403 const vec3 & get_position() const {return position;}
404 404
405 const vec3 & get_direction() const {return direction;} 405 const vec3 & get_direction() const {return direction;}
406 406
407 //protected: 407 //protected:
408 vec3 position; 408 vec3 position;
409 vec3 direction; 409 vec3 direction;
410 }; 410 };
411 411
412 412
413 413
414 414
415 415
416 416
417 417
418 418
419 419
420 420
421 421
422 422
423 423
424 424
425 425
426 426
427 427
428 428
429 429
430 430
431 431
432 432
433 433
434 434
435 435
436 436
437 437
438 438
439 439
440 // matrix 440 // matrix
441 441
442 442
443 class matrix4 443 class matrix4
444 { 444 {
445 445
446 public: 446 public:
447 447
448 matrix4() { make_identity(); } 448 matrix4() { make_identity(); }
449 449
450 matrix4( real r ) 450 matrix4( real r )
451 { set_value(r); } 451 { set_value(r); }
452 452
453 matrix4( real * m ) 453 matrix4( real * m )
454 { set_value(m); } 454 { set_value(m); }
455 455
456 matrix4( real a00, real a01, real a02, real a03, 456 matrix4( real a00, real a01, real a02, real a03,
457 real a10, real a11, real a12, real a13, 457 real a10, real a11, real a12, real a13,
458 real a20, real a21, real a22, real a23, 458 real a20, real a21, real a22, real a23,
459 real a30, real a31, real a32, real a33 ) 459 real a30, real a31, real a32, real a33 )
460 { 460 {
461 element(0,0) = a00; 461 element(0,0) = a00;
462 element(0,1) = a01; 462 element(0,1) = a01;
463 element(0,2) = a02; 463 element(0,2) = a02;
464 element(0,3) = a03; 464 element(0,3) = a03;
465 465
466 element(1,0) = a10; 466 element(1,0) = a10;
467 element(1,1) = a11; 467 element(1,1) = a11;
468 element(1,2) = a12; 468 element(1,2) = a12;
469 element(1,3) = a13; 469 element(1,3) = a13;
470 470
471 element(2,0) = a20; 471 element(2,0) = a20;
472 element(2,1) = a21; 472 element(2,1) = a21;
473 element(2,2) = a22; 473 element(2,2) = a22;
474 element(2,3) = a23; 474 element(2,3) = a23;
475 475
476 element(3,0) = a30; 476 element(3,0) = a30;
477 element(3,1) = a31; 477 element(3,1) = a31;
478 element(3,2) = a32; 478 element(3,2) = a32;
479 element(3,3) = a33; 479 element(3,3) = a33;
480 } 480 }
481 481
482 482
483 void get_value( real * mp ) const 483 void get_value( real * mp ) const
484 { 484 {
485 int c = 0; 485 int c = 0;
486 for(int j=0; j < 4; j++) 486 for(int j=0; j < 4; j++)
487 for(int i=0; i < 4; i++) 487 for(int i=0; i < 4; i++)
488 mp[c++] = element(i,j); 488 mp[c++] = element(i,j);
489 } 489 }
490 490
491 491
492 const real * get_value() const 492 const real * get_value() const
493 { return m; } 493 { return m; }
494 494
495 void set_value( real * mp) 495 void set_value( real * mp)
496 { 496 {
497 int c = 0; 497 int c = 0;
498 for(int j=0; j < 4; j++) 498 for(int j=0; j < 4; j++)
499 for(int i=0; i < 4; i++) 499 for(int i=0; i < 4; i++)
500 element(i,j) = mp[c++]; 500 element(i,j) = mp[c++];
501 } 501 }
502 502
503 void set_value( real r ) 503 void set_value( real r )
504 { 504 {
505 for(int i=0; i < 4; i++) 505 for(int i=0; i < 4; i++)
506 for(int j=0; j < 4; j++) 506 for(int j=0; j < 4; j++)
507 element(i,j) = r; 507 element(i,j) = r;
508 } 508 }
509 509
510 void make_identity() 510 void make_identity()
511 { 511 {
512 element(0,0) = 1.0; 512 element(0,0) = 1.0;
513 element(0,1) = 0.0; 513 element(0,1) = 0.0;
514 element(0,2) = 0.0; 514 element(0,2) = 0.0;
515 element(0,3) = 0.0; 515 element(0,3) = 0.0;
516 516
517 element(1,0) = 0.0; 517 element(1,0) = 0.0;
518 element(1,1) = 1.0; 518 element(1,1) = 1.0;
519 element(1,2) = 0.0; 519 element(1,2) = 0.0;
520 element(1,3) = 0.0; 520 element(1,3) = 0.0;
521 521
522 element(2,0) = 0.0; 522 element(2,0) = 0.0;
523 element(2,1) = 0.0; 523 element(2,1) = 0.0;
524 element(2,2) = 1.0; 524 element(2,2) = 1.0;
525 element(2,3) = 0.0; 525 element(2,3) = 0.0;
526 526
527 element(3,0) = 0.0; 527 element(3,0) = 0.0;
528 element(3,1) = 0.0; 528 element(3,1) = 0.0;
529 element(3,2) = 0.0; 529 element(3,2) = 0.0;
530 element(3,3) = 1.0; 530 element(3,3) = 1.0;
531 } 531 }
532 532
533 533
534 static matrix4 identity() 534 static matrix4 identity()
535 { 535 {
536 static matrix4 mident ( 536 static matrix4 mident (
537 1.0, 0.0, 0.0, 0.0, 537 1.0, 0.0, 0.0, 0.0,
538 0.0, 1.0, 0.0, 0.0, 538 0.0, 1.0, 0.0, 0.0,
539 0.0, 0.0, 1.0, 0.0, 539 0.0, 0.0, 1.0, 0.0,
540 0.0, 0.0, 0.0, 1.0 ); 540 0.0, 0.0, 0.0, 1.0 );
541 return mident; 541 return mident;
542 } 542 }
543 543
544 544
545 void set_scale( real s ) 545 void set_scale( real s )
546 { 546 {
547 element(0,0) = s; 547 element(0,0) = s;
548 element(1,1) = s; 548 element(1,1) = s;
549 element(2,2) = s; 549 element(2,2) = s;
550 } 550 }
551 551
552 void set_scale( const vec3 & s ) 552 void set_scale( const vec3 & s )
553 { 553 {
554 element(0,0) = s.v[0]; 554 element(0,0) = s.v[0];
555 element(1,1) = s.v[1]; 555 element(1,1) = s.v[1];
556 element(2,2) = s.v[2]; 556 element(2,2) = s.v[2];
557 } 557 }
558 558
559 559
560 void set_translate( const vec3 & t ) 560 void set_translate( const vec3 & t )
561 { 561 {
562 element(0,3) = t.v[0]; 562 element(0,3) = t.v[0];
563 element(1,3) = t.v[1]; 563 element(1,3) = t.v[1];
564 element(2,3) = t.v[2]; 564 element(2,3) = t.v[2];
565 } 565 }
566 566
567 void set_row(int r, const vec4 & t) 567 void set_row(int r, const vec4 & t)
568 { 568 {
569 element(r,0) = t.v[0]; 569 element(r,0) = t.v[0];
570 element(r,1) = t.v[1]; 570 element(r,1) = t.v[1];
571 element(r,2) = t.v[2]; 571 element(r,2) = t.v[2];
572 element(r,3) = t.v[3]; 572 element(r,3) = t.v[3];
573 } 573 }
574 574
575 void set_column(int c, const vec4 & t) 575 void set_column(int c, const vec4 & t)
576 { 576 {
577 element(0,c) = t.v[0]; 577 element(0,c) = t.v[0];
578 element(1,c) = t.v[1]; 578 element(1,c) = t.v[1];
579 element(2,c) = t.v[2]; 579 element(2,c) = t.v[2];
580 element(3,c) = t.v[3]; 580 element(3,c) = t.v[3];
581 } 581 }
582 582
583 583
584 void get_row(int r, vec4 & t) const 584 void get_row(int r, vec4 & t) const
585 { 585 {
586 t.v[0] = element(r,0); 586 t.v[0] = element(r,0);
587 t.v[1] = element(r,1); 587 t.v[1] = element(r,1);
588 t.v[2] = element(r,2); 588 t.v[2] = element(r,2);
589 t.v[3] = element(r,3); 589 t.v[3] = element(r,3);
590 } 590 }
591 591
592 vec4 get_row(int r) const 592 vec4 get_row(int r) const
593 { 593 {
594 vec4 v; get_row(r, v); 594 vec4 v; get_row(r, v);
595 return v; 595 return v;
596 } 596 }
597 597
598 void get_column(int c, vec4 & t) const 598 void get_column(int c, vec4 & t) const
599 { 599 {
600 t.v[0] = element(0,c); 600 t.v[0] = element(0,c);
601 t.v[1] = element(1,c); 601 t.v[1] = element(1,c);
602 t.v[2] = element(2,c); 602 t.v[2] = element(2,c);
603 t.v[3] = element(3,c); 603 t.v[3] = element(3,c);
604 } 604 }
605 605
606 vec4 get_column(int c) const 606 vec4 get_column(int c) const
607 { 607 {
608 vec4 v; get_column(c, v); 608 vec4 v; get_column(c, v);
609 return v; 609 return v;
610 } 610 }
611 611
612 matrix4 inverse() const 612 matrix4 inverse() const
613 { 613 {
614 matrix4 minv; 614 matrix4 minv;
615 615
616 real r1[8], r2[8], r3[8], r4[8]; 616 real r1[8], r2[8], r3[8], r4[8];
617 real *s[4], *tmprow; 617 real *s[4], *tmprow;
618 618
619 s[0] = &r1[0]; 619 s[0] = &r1[0];
620 s[1] = &r2[0]; 620 s[1] = &r2[0];
621 s[2] = &r3[0]; 621 s[2] = &r3[0];
622 s[3] = &r4[0]; 622 s[3] = &r4[0];
623 623
624 register int i,j,p,jj; 624 register int i,j,p,jj;
625 for(i=0;i<4;i++) 625 for(i=0;i<4;i++)
626 { 626 {
627 for(j=0;j<4;j++) 627 for(j=0;j<4;j++)
628 { 628 {
629 s[i][j] = element(i,j); 629 s[i][j] = element(i,j);
630 if(i==j) s[i][j+4] = 1.0; 630 if(i==j) s[i][j+4] = 1.0;
631 else s[i][j+4] = 0.0; 631 else s[i][j+4] = 0.0;
632 } 632 }
633 } 633 }
634 real scp[4]; 634 real scp[4];
635 for(i=0;i<4;i++) 635 for(i=0;i<4;i++)
636 { 636 {
637 scp[i] = real(fabs(s[i][0])); 637 scp[i] = real(fabs(s[i][0]));
638 for(j=1;j<4;j++) 638 for(j=1;j<4;j++)
639 if(real(fabs(s[i][j])) > scp[i]) scp[i] = real(fabs(s[i][j])); 639 if(real(fabs(s[i][j])) > scp[i]) scp[i] = real(fabs(s[i][j]));
640 if(scp[i] == 0.0) return minv; // singular matrix! 640 if(scp[i] == 0.0) return minv; // singular matrix!
641 } 641 }
642 642
643 int pivot_to; 643 int pivot_to;
644 real scp_max; 644 real scp_max;
645 for(i=0;i<4;i++) 645 for(i=0;i<4;i++)
646 { 646 {
647 // select pivot row 647 // select pivot row
648 pivot_to = i; 648 pivot_to = i;
649 scp_max = real(fabs(s[i][i]/scp[i])); 649 scp_max = real(fabs(s[i][i]/scp[i]));
650 // find out which row should be on top 650 // find out which row should be on top
651 for(p=i+1;p<4;p++) 651 for(p=i+1;p<4;p++)
652 if(real(fabs(s[p][i]/scp[p])) > scp_max) 652 if(real(fabs(s[p][i]/scp[p])) > scp_max)
653 { scp_max = real(fabs(s[p][i]/scp[p])); pivot_to = p; } 653 { scp_max = real(fabs(s[p][i]/scp[p])); pivot_to = p; }
654 // Pivot if necessary 654 // Pivot if necessary
655 if(pivot_to != i) 655 if(pivot_to != i)
656 { 656 {
657 tmprow = s[i]; 657 tmprow = s[i];
658 s[i] = s[pivot_to]; 658 s[i] = s[pivot_to];
659 s[pivot_to] = tmprow; 659 s[pivot_to] = tmprow;
660 real tmpscp; 660 real tmpscp;
661 tmpscp = scp[i]; 661 tmpscp = scp[i];
662 scp[i] = scp[pivot_to]; 662 scp[i] = scp[pivot_to];
663 scp[pivot_to] = tmpscp; 663 scp[pivot_to] = tmpscp;
664 } 664 }
665 665
666 real mji; 666 real mji;
667 // perform gaussian elimination 667 // perform gaussian elimination
668 for(j=i+1;j<4;j++) 668 for(j=i+1;j<4;j++)
669 { 669 {
670 mji = s[j][i]/s[i][i]; 670 mji = s[j][i]/s[i][i];
671 s[j][i] = 0.0; 671 s[j][i] = 0.0;
672 for(jj=i+1;jj<8;jj++) 672 for(jj=i+1;jj<8;jj++)
673 s[j][jj] -= mji*s[i][jj]; 673 s[j][jj] -= mji*s[i][jj];
674 } 674 }
675 } 675 }
676 if(s[3][3] == 0.0) return minv; // singular matrix! 676 if(s[3][3] == 0.0) return minv; // singular matrix!
677 677
678 // 678 //
679 // Now we have an upper triangular matrix. 679 // Now we have an upper triangular matrix.
680 // 680 //
681 // x x x x | y y y y 681 // x x x x | y y y y
682 // 0 x x x | y y y y 682 // 0 x x x | y y y y
683 // 0 0 x x | y y y y 683 // 0 0 x x | y y y y
684 // 0 0 0 x | y y y y 684 // 0 0 0 x | y y y y
685 // 685 //
686 // we'll back substitute to get the inverse 686 // we'll back substitute to get the inverse
687 // 687 //
688 // 1 0 0 0 | z z z z 688 // 1 0 0 0 | z z z z
689 // 0 1 0 0 | z z z z 689 // 0 1 0 0 | z z z z
690 // 0 0 1 0 | z z z z 690 // 0 0 1 0 | z z z z
691 // 0 0 0 1 | z z z z 691 // 0 0 0 1 | z z z z
692 // 692 //
693 693
694 real mij; 694 real mij;
695 for(i=3;i>0;i--) 695 for(i=3;i>0;i--)
696 { 696 {
697 for(j=i-1;j > -1; j--) 697 for(j=i-1;j > -1; j--)
698 { 698 {
699 mij = s[j][i]/s[i][i]; 699 mij = s[j][i]/s[i][i];
700 for(jj=j+1;jj<8;jj++) 700 for(jj=j+1;jj<8;jj++)
701 s[j][jj] -= mij*s[i][jj]; 701 s[j][jj] -= mij*s[i][jj];
702 } 702 }
703 } 703 }
704 704
705 for(i=0;i<4;i++) 705 for(i=0;i<4;i++)
706 for(j=0;j<4;j++) 706 for(j=0;j<4;j++)
707 minv(i,j) = s[i][j+4] / s[i][i]; 707 minv(i,j) = s[i][j+4] / s[i][i];
708 708
709 return minv; 709 return minv;
710 } 710 }
711 711
712 712
713 matrix4 transpose() const 713 matrix4 transpose() const
714 { 714 {
715 matrix4 mtrans; 715 matrix4 mtrans;
716 716
717 for(int i=0;i<4;i++) 717 for(int i=0;i<4;i++)
718 for(int j=0;j<4;j++) 718 for(int j=0;j<4;j++)
719 mtrans(i,j) = element(j,i); 719 mtrans(i,j) = element(j,i);
720 return mtrans; 720 return mtrans;
721 } 721 }
722 722
723 matrix4 & mult_right( const matrix4 & b ) 723 matrix4 & mult_right( const matrix4 & b )
724 { 724 {
725 matrix4 mt(*this); 725 matrix4 mt(*this);
726 set_value(real(0)); 726 set_value(real(0));
727 727
728 for(int i=0; i < 4; i++) 728 for(int i=0; i < 4; i++)
729 for(int j=0; j < 4; j++) 729 for(int j=0; j < 4; j++)
730 for(int c=0; c < 4; c++) 730 for(int c=0; c < 4; c++)
731 element(i,j) += mt(i,c) * b(c,j); 731 element(i,j) += mt(i,c) * b(c,j);
732 return *this; 732 return *this;
733 } 733 }
734 734
735 matrix4 & mult_left( const matrix4 & b ) 735 matrix4 & mult_left( const matrix4 & b )
736 { 736 {
737 matrix4 mt(*this); 737 matrix4 mt(*this);
738 set_value(real(0)); 738 set_value(real(0));
739 739
740 for(int i=0; i < 4; i++) 740 for(int i=0; i < 4; i++)
741 for(int j=0; j < 4; j++) 741 for(int j=0; j < 4; j++)
742 for(int c=0; c < 4; c++) 742 for(int c=0; c < 4; c++)
743 element(i,j) += b(i,c) * mt(c,j); 743 element(i,j) += b(i,c) * mt(c,j);
744 return *this; 744 return *this;
745 } 745 }
746 746
747 // dst = M * src 747 // dst = M * src
748 void mult_matrix_vec( const vec3 &src, vec3 &dst ) const 748 void mult_matrix_vec( const vec3 &src, vec3 &dst ) const
749 { 749 {
750 real w = ( 750 real w = (
751 src.v[0] * element(3,0) + 751 src.v[0] * element(3,0) +
752 src.v[1] * element(3,1) + 752 src.v[1] * element(3,1) +
753 src.v[2] * element(3,2) + 753 src.v[2] * element(3,2) +
754 element(3,3) ); 754 element(3,3) );
755 755
756 assert(w != GLH_ZERO); 756 assert(w != GLH_ZERO);
757 757
758 dst.v[0] = ( 758 dst.v[0] = (
759 src.v[0] * element(0,0) + 759 src.v[0] * element(0,0) +
760 src.v[1] * element(0,1) + 760 src.v[1] * element(0,1) +
761 src.v[2] * element(0,2) + 761 src.v[2] * element(0,2) +
762 element(0,3) ) / w; 762 element(0,3) ) / w;
763 dst.v[1] = ( 763 dst.v[1] = (
764 src.v[0] * element(1,0) + 764 src.v[0] * element(1,0) +
765 src.v[1] * element(1,1) + 765 src.v[1] * element(1,1) +
766 src.v[2] * element(1,2) + 766 src.v[2] * element(1,2) +
767 element(1,3) ) / w; 767 element(1,3) ) / w;
768 dst.v[2] = ( 768 dst.v[2] = (
769 src.v[0] * element(2,0) + 769 src.v[0] * element(2,0) +
770 src.v[1] * element(2,1) + 770 src.v[1] * element(2,1) +
771 src.v[2] * element(2,2) + 771 src.v[2] * element(2,2) +
772 element(2,3) ) / w; 772 element(2,3) ) / w;
773 } 773 }
774 774
775 void mult_matrix_vec( vec3 & src_and_dst) const 775 void mult_matrix_vec( vec3 & src_and_dst) const
776 { mult_matrix_vec(vec3(src_and_dst), src_and_dst); } 776 { mult_matrix_vec(vec3(src_and_dst), src_and_dst); }
777 777
778 778
779 // dst = src * M 779 // dst = src * M
780 void mult_vec_matrix( const vec3 &src, vec3 &dst ) const 780 void mult_vec_matrix( const vec3 &src, vec3 &dst ) const
781 { 781 {
782 real w = ( 782 real w = (
783 src.v[0] * element(0,3) + 783 src.v[0] * element(0,3) +
784 src.v[1] * element(1,3) + 784 src.v[1] * element(1,3) +
785 src.v[2] * element(2,3) + 785 src.v[2] * element(2,3) +
786 element(3,3) ); 786 element(3,3) );
787 787
788 assert(w != GLH_ZERO); 788 assert(w != GLH_ZERO);
789 789
790 dst.v[0] = ( 790 dst.v[0] = (
791 src.v[0] * element(0,0) + 791 src.v[0] * element(0,0) +
792 src.v[1] * element(1,0) + 792 src.v[1] * element(1,0) +
793 src.v[2] * element(2,0) + 793 src.v[2] * element(2,0) +
794 element(3,0) ) / w; 794 element(3,0) ) / w;
795 dst.v[1] = ( 795 dst.v[1] = (
796 src.v[0] * element(0,1) + 796 src.v[0] * element(0,1) +
797 src.v[1] * element(1,1) + 797 src.v[1] * element(1,1) +
798 src.v[2] * element(2,1) + 798 src.v[2] * element(2,1) +
799 element(3,1) ) / w; 799 element(3,1) ) / w;
800 dst.v[2] = ( 800 dst.v[2] = (
801 src.v[0] * element(0,2) + 801 src.v[0] * element(0,2) +
802 src.v[1] * element(1,2) + 802 src.v[1] * element(1,2) +
803 src.v[2] * element(2,2) + 803 src.v[2] * element(2,2) +
804 element(3,2) ) / w; 804 element(3,2) ) / w;
805 } 805 }
806 806
807 807
808 void mult_vec_matrix( vec3 & src_and_dst) const 808 void mult_vec_matrix( vec3 & src_and_dst) const
809 { mult_vec_matrix(vec3(src_and_dst), src_and_dst); } 809 { mult_vec_matrix(vec3(src_and_dst), src_and_dst); }
810 810
811 // dst = M * src 811 // dst = M * src
812 void mult_matrix_vec( const vec4 &src, vec4 &dst ) const 812 void mult_matrix_vec( const vec4 &src, vec4 &dst ) const
813 { 813 {
814 dst.v[0] = ( 814 dst.v[0] = (
815 src.v[0] * element(0,0) + 815 src.v[0] * element(0,0) +
816 src.v[1] * element(0,1) + 816 src.v[1] * element(0,1) +
817 src.v[2] * element(0,2) + 817 src.v[2] * element(0,2) +
818 src.v[3] * element(0,3)); 818 src.v[3] * element(0,3));
819 dst.v[1] = ( 819 dst.v[1] = (
820 src.v[0] * element(1,0) + 820 src.v[0] * element(1,0) +
821 src.v[1] * element(1,1) + 821 src.v[1] * element(1,1) +
822 src.v[2] * element(1,2) + 822 src.v[2] * element(1,2) +
823 src.v[3] * element(1,3)); 823 src.v[3] * element(1,3));
824 dst.v[2] = ( 824 dst.v[2] = (
825 src.v[0] * element(2,0) + 825 src.v[0] * element(2,0) +
826 src.v[1] * element(2,1) + 826 src.v[1] * element(2,1) +
827 src.v[2] * element(2,2) + 827 src.v[2] * element(2,2) +
828 src.v[3] * element(2,3)); 828 src.v[3] * element(2,3));
829 dst.v[3] = ( 829 dst.v[3] = (
830 src.v[0] * element(3,0) + 830 src.v[0] * element(3,0) +
831 src.v[1] * element(3,1) + 831 src.v[1] * element(3,1) +
832 src.v[2] * element(3,2) + 832 src.v[2] * element(3,2) +
833 src.v[3] * element(3,3)); 833 src.v[3] * element(3,3));
834 } 834 }
835 835
836 void mult_matrix_vec( vec4 & src_and_dst) const 836 void mult_matrix_vec( vec4 & src_and_dst) const
837 { mult_matrix_vec(vec4(src_and_dst), src_and_dst); } 837 { mult_matrix_vec(vec4(src_and_dst), src_and_dst); }
838 838
839 839
840 // dst = src * M 840 // dst = src * M
841 void mult_vec_matrix( const vec4 &src, vec4 &dst ) const 841 void mult_vec_matrix( const vec4 &src, vec4 &dst ) const
842 { 842 {
843 dst.v[0] = ( 843 dst.v[0] = (
844 src.v[0] * element(0,0) + 844 src.v[0] * element(0,0) +
845 src.v[1] * element(1,0) + 845 src.v[1] * element(1,0) +
846 src.v[2] * element(2,0) + 846 src.v[2] * element(2,0) +
847 src.v[3] * element(3,0)); 847 src.v[3] * element(3,0));
848 dst.v[1] = ( 848 dst.v[1] = (
849 src.v[0] * element(0,1) + 849 src.v[0] * element(0,1) +
850 src.v[1] * element(1,1) + 850 src.v[1] * element(1,1) +
851 src.v[2] * element(2,1) + 851 src.v[2] * element(2,1) +
852 src.v[3] * element(3,1)); 852 src.v[3] * element(3,1));
853 dst.v[2] = ( 853 dst.v[2] = (
854 src.v[0] * element(0,2) + 854 src.v[0] * element(0,2) +
855 src.v[1] * element(1,2) + 855 src.v[1] * element(1,2) +
856 src.v[2] * element(2,2) + 856 src.v[2] * element(2,2) +
857 src.v[3] * element(3,2)); 857 src.v[3] * element(3,2));
858 dst.v[3] = ( 858 dst.v[3] = (
859 src.v[0] * element(0,3) + 859 src.v[0] * element(0,3) +
860 src.v[1] * element(1,3) + 860 src.v[1] * element(1,3) +
861 src.v[2] * element(2,3) + 861 src.v[2] * element(2,3) +
862 src.v[3] * element(3,3)); 862 src.v[3] * element(3,3));
863 } 863 }
864 864
865 865
866 void mult_vec_matrix( vec4 & src_and_dst) const 866 void mult_vec_matrix( vec4 & src_and_dst) const
867 { mult_vec_matrix(vec4(src_and_dst), src_and_dst); } 867 { mult_vec_matrix(vec4(src_and_dst), src_and_dst); }
868 868
869 869
870 // dst = M * src 870 // dst = M * src
871 void mult_matrix_dir( const vec3 &src, vec3 &dst ) const 871 void mult_matrix_dir( const vec3 &src, vec3 &dst ) const
872 { 872 {
873 dst.v[0] = ( 873 dst.v[0] = (
874 src.v[0] * element(0,0) + 874 src.v[0] * element(0,0) +
875 src.v[1] * element(0,1) + 875 src.v[1] * element(0,1) +
876 src.v[2] * element(0,2) ) ; 876 src.v[2] * element(0,2) ) ;
877 dst.v[1] = ( 877 dst.v[1] = (
878 src.v[0] * element(1,0) + 878 src.v[0] * element(1,0) +
879 src.v[1] * element(1,1) + 879 src.v[1] * element(1,1) +
880 src.v[2] * element(1,2) ) ; 880 src.v[2] * element(1,2) ) ;
881 dst.v[2] = ( 881 dst.v[2] = (
882 src.v[0] * element(2,0) + 882 src.v[0] * element(2,0) +
883 src.v[1] * element(2,1) + 883 src.v[1] * element(2,1) +
884 src.v[2] * element(2,2) ) ; 884 src.v[2] * element(2,2) ) ;
885 } 885 }
886 886
887 887
888 void mult_matrix_dir( vec3 & src_and_dst) const 888 void mult_matrix_dir( vec3 & src_and_dst) const
889 { mult_matrix_dir(vec3(src_and_dst), src_and_dst); } 889 { mult_matrix_dir(vec3(src_and_dst), src_and_dst); }
890 890
891 891
892 // dst = src * M 892 // dst = src * M
893 void mult_dir_matrix( const vec3 &src, vec3 &dst ) const 893 void mult_dir_matrix( const vec3 &src, vec3 &dst ) const
894 { 894 {
895 dst.v[0] = ( 895 dst.v[0] = (
896 src.v[0] * element(0,0) + 896 src.v[0] * element(0,0) +
897 src.v[1] * element(1,0) + 897 src.v[1] * element(1,0) +
898 src.v[2] * element(2,0) ) ; 898 src.v[2] * element(2,0) ) ;
899 dst.v[1] = ( 899 dst.v[1] = (
900 src.v[0] * element(0,1) + 900 src.v[0] * element(0,1) +
901 src.v[1] * element(1,1) + 901 src.v[1] * element(1,1) +
902 src.v[2] * element(2,1) ) ; 902 src.v[2] * element(2,1) ) ;
903 dst.v[2] = ( 903 dst.v[2] = (
904 src.v[0] * element(0,2) + 904 src.v[0] * element(0,2) +
905 src.v[1] * element(1,2) + 905 src.v[1] * element(1,2) +
906 src.v[2] * element(2,2) ) ; 906 src.v[2] * element(2,2) ) ;
907 } 907 }
908 908
909 909
910 void mult_dir_matrix( vec3 & src_and_dst) const 910 void mult_dir_matrix( vec3 & src_and_dst) const
911 { mult_dir_matrix(vec3(src_and_dst), src_and_dst); } 911 { mult_dir_matrix(vec3(src_and_dst), src_and_dst); }
912 912
913 913
914 real & operator () (int row, int col) 914 real & operator () (int row, int col)
915 { return element(row,col); } 915 { return element(row,col); }
916 916
917 const real & operator () (int row, int col) const 917 const real & operator () (int row, int col) const
918 { return element(row,col); } 918 { return element(row,col); }
919 919
920 real & element (int row, int col) 920 real & element (int row, int col)
921 { return m[row | (col<<2)]; } 921 { return m[row | (col<<2)]; }
922 922
923 const real & element (int row, int col) const 923 const real & element (int row, int col) const
924 { return m[row | (col<<2)]; } 924 { return m[row | (col<<2)]; }
925 925
926 matrix4 & operator *= ( const matrix4 & mat ) 926 matrix4 & operator *= ( const matrix4 & mat )
927 { 927 {
928 mult_right( mat ); 928 mult_right( mat );
929 return *this; 929 return *this;
930 } 930 }
931 931
932 matrix4 & operator *= ( const real & r ) 932 matrix4 & operator *= ( const real & r )
933 { 933 {
934 for (int i = 0; i < 4; ++i) 934 for (int i = 0; i < 4; ++i)
935 { 935 {
936 element(0,i) *= r; 936 element(0,i) *= r;
937 element(1,i) *= r; 937 element(1,i) *= r;
938 element(2,i) *= r; 938 element(2,i) *= r;
939 element(3,i) *= r; 939 element(3,i) *= r;
940 } 940 }
941 return *this; 941 return *this;
942 } 942 }
943 943
944 matrix4 & operator += ( const matrix4 & mat ) 944 matrix4 & operator += ( const matrix4 & mat )
945 { 945 {
946 for (int i = 0; i < 4; ++i) 946 for (int i = 0; i < 4; ++i)
947 { 947 {
948 element(0,i) += mat.element(0,i); 948 element(0,i) += mat.element(0,i);
949 element(1,i) += mat.element(1,i); 949 element(1,i) += mat.element(1,i);
950 element(2,i) += mat.element(2,i); 950 element(2,i) += mat.element(2,i);
951 element(3,i) += mat.element(3,i); 951 element(3,i) += mat.element(3,i);
952 } 952 }
953 return *this; 953 return *this;
954 } 954 }
955 955
956 friend matrix4 operator * ( const matrix4 & m1, const matrix4 & m2 ); 956 friend matrix4 operator * ( const matrix4 & m1, const matrix4 & m2 );
957 friend bool operator == ( const matrix4 & m1, const matrix4 & m2 ); 957 friend bool operator == ( const matrix4 & m1, const matrix4 & m2 );
958 friend bool operator != ( const matrix4 & m1, const matrix4 & m2 ); 958 friend bool operator != ( const matrix4 & m1, const matrix4 & m2 );
959 959
960 //protected: 960 //protected:
961 real m[16]; 961 real m[16];
962 }; 962 };
963 963
964 inline 964 inline
965 matrix4 operator * ( const matrix4 & m1, const matrix4 & m2 ) 965 matrix4 operator * ( const matrix4 & m1, const matrix4 & m2 )
966 { 966 {
967 matrix4 product; 967 matrix4 product;
968 968
969 product = m1; 969 product = m1;
970 product.mult_right(m2); 970 product.mult_right(m2);
971 971
972 return product; 972 return product;
973 } 973 }
974 974
975 inline 975 inline
976 bool operator ==( const matrix4 &m1, const matrix4 &m2 ) 976 bool operator ==( const matrix4 &m1, const matrix4 &m2 )
977 { 977 {
978 return ( 978 return (
979 m1(0,0) == m2(0,0) && 979 m1(0,0) == m2(0,0) &&
980 m1(0,1) == m2(0,1) && 980 m1(0,1) == m2(0,1) &&
981 m1(0,2) == m2(0,2) && 981 m1(0,2) == m2(0,2) &&
982 m1(0,3) == m2(0,3) && 982 m1(0,3) == m2(0,3) &&
983 m1(1,0) == m2(1,0) && 983 m1(1,0) == m2(1,0) &&
984 m1(1,1) == m2(1,1) && 984 m1(1,1) == m2(1,1) &&
985 m1(1,2) == m2(1,2) && 985 m1(1,2) == m2(1,2) &&
986 m1(1,3) == m2(1,3) && 986 m1(1,3) == m2(1,3) &&
987 m1(2,0) == m2(2,0) && 987 m1(2,0) == m2(2,0) &&
988 m1(2,1) == m2(2,1) && 988 m1(2,1) == m2(2,1) &&
989 m1(2,2) == m2(2,2) && 989 m1(2,2) == m2(2,2) &&
990 m1(2,3) == m2(2,3) && 990 m1(2,3) == m2(2,3) &&
991 m1(3,0) == m2(3,0) && 991 m1(3,0) == m2(3,0) &&
992 m1(3,1) == m2(3,1) && 992 m1(3,1) == m2(3,1) &&
993 m1(3,2) == m2(3,2) && 993 m1(3,2) == m2(3,2) &&
994 m1(3,3) == m2(3,3) ); 994 m1(3,3) == m2(3,3) );
995 } 995 }
996 996
997 inline 997 inline
998 bool operator != ( const matrix4 & m1, const matrix4 & m2 ) 998 bool operator != ( const matrix4 & m1, const matrix4 & m2 )
999 { return !( m1 == m2 ); } 999 { return !( m1 == m2 ); }
1000 1000
1001 1001
1002 1002
1003 1003
1004 1004
1005 1005
1006 1006
1007 1007
1008 1008
1009 1009
1010 1010
1011 1011
1012 1012
1013 class quaternion 1013 class quaternion
1014 { 1014 {
1015 public: 1015 public:
1016 1016
1017 quaternion() 1017 quaternion()
1018 { 1018 {
1019 *this = identity(); 1019 *this = identity();
1020 } 1020 }
1021 1021
1022 quaternion( const real v[4] ) 1022 quaternion( const real v[4] )
1023 { 1023 {
1024 set_value( v ); 1024 set_value( v );
1025 } 1025 }
1026 1026
1027 1027
1028 quaternion( real q0, real q1, real q2, real q3 ) 1028 quaternion( real q0, real q1, real q2, real q3 )
1029 { 1029 {
1030 set_value( q0, q1, q2, q3 ); 1030 set_value( q0, q1, q2, q3 );
1031 } 1031 }
1032 1032
1033 1033
1034 quaternion( const matrix4 & m ) 1034 quaternion( const matrix4 & m )
1035 { 1035 {
1036 set_value( m ); 1036 set_value( m );
1037 } 1037 }
1038 1038
1039 1039
1040 quaternion( const vec3 &axis, real radians ) 1040 quaternion( const vec3 &axis, real radians )
1041 { 1041 {
1042 set_value( axis, radians ); 1042 set_value( axis, radians );
1043 } 1043 }
1044 1044
1045 1045
1046 quaternion( const vec3 &rotateFrom, const vec3 &rotateTo ) 1046 quaternion( const vec3 &rotateFrom, const vec3 &rotateTo )
1047 { 1047 {
1048 set_value( rotateFrom, rotateTo ); 1048 set_value( rotateFrom, rotateTo );
1049 } 1049 }
1050 1050
1051 quaternion( const vec3 & from_look, const vec3 & from_up, 1051 quaternion( const vec3 & from_look, const vec3 & from_up,
1052 const vec3 & to_look, const vec3& to_up) 1052 const vec3 & to_look, const vec3& to_up)
1053 { 1053 {
1054 set_value(from_look, from_up, to_look, to_up); 1054 set_value(from_look, from_up, to_look, to_up);
1055 } 1055 }
1056 1056
1057 const real * get_value() const 1057 const real * get_value() const
1058 { 1058 {
1059 return &q[0]; 1059 return &q[0];
1060 } 1060 }
1061 1061
1062 void get_value( real &q0, real &q1, real &q2, real &q3 ) const 1062 void get_value( real &q0, real &q1, real &q2, real &q3 ) const
1063 { 1063 {
1064 q0 = q[0]; 1064 q0 = q[0];
1065 q1 = q[1]; 1065 q1 = q[1];
1066 q2 = q[2]; 1066 q2 = q[2];
1067 q3 = q[3]; 1067 q3 = q[3];
1068 } 1068 }
1069 1069
1070 quaternion & set_value( real q0, real q1, real q2, real q3 ) 1070 quaternion & set_value( real q0, real q1, real q2, real q3 )
1071 { 1071 {
1072 q[0] = q0; 1072 q[0] = q0;
1073 q[1] = q1; 1073 q[1] = q1;
1074 q[2] = q2; 1074 q[2] = q2;
1075 q[3] = q3; 1075 q[3] = q3;
1076 counter = 0; 1076 counter = 0;
1077 return *this; 1077 return *this;
1078 } 1078 }
1079 1079
1080 void get_value( vec3 &axis, real &radians ) const 1080 void get_value( vec3 &axis, real &radians ) const
1081 { 1081 {
1082 radians = real(acos( q[3] ) * GLH_TWO); 1082 radians = real(acos( q[3] ) * GLH_TWO);
1083 if ( radians == GLH_ZERO ) 1083 if ( radians == GLH_ZERO )
1084 axis = vec3( 0.0, 0.0, 1.0 ); 1084 axis = vec3( 0.0, 0.0, 1.0 );
1085 else 1085 else
1086 { 1086 {
1087 axis.v[0] = q[0]; 1087 axis.v[0] = q[0];
1088 axis.v[1] = q[1]; 1088 axis.v[1] = q[1];
1089 axis.v[2] = q[2]; 1089 axis.v[2] = q[2];
1090 axis.normalize(); 1090 axis.normalize();
1091 } 1091 }
1092 } 1092 }
1093 1093
1094 void get_value( matrix4 & m ) const 1094 void get_value( matrix4 & m ) const
1095 { 1095 {
1096 real s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz; 1096 real s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
1097 1097
1098 real norm = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; 1098 real norm = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
1099 1099
1100 s = (equivalent(norm,GLH_ZERO)) ? GLH_ZERO : ( GLH_TWO / norm ); 1100 s = (equivalent(norm,GLH_ZERO)) ? GLH_ZERO : ( GLH_TWO / norm );
1101 1101
1102 xs = q[0] * s; 1102 xs = q[0] * s;
1103 ys = q[1] * s; 1103 ys = q[1] * s;
1104 zs = q[2] * s; 1104 zs = q[2] * s;
1105 1105
1106 wx = q[3] * xs; 1106 wx = q[3] * xs;
1107 wy = q[3] * ys; 1107 wy = q[3] * ys;
1108 wz = q[3] * zs; 1108 wz = q[3] * zs;
1109 1109
1110 xx = q[0] * xs; 1110 xx = q[0] * xs;
1111 xy = q[0] * ys; 1111 xy = q[0] * ys;
1112 xz = q[0] * zs; 1112 xz = q[0] * zs;
1113 1113
1114 yy = q[1] * ys; 1114 yy = q[1] * ys;
1115 yz = q[1] * zs; 1115 yz = q[1] * zs;
1116 zz = q[2] * zs; 1116 zz = q[2] * zs;
1117 1117
1118 m(0,0) = real( GLH_ONE - ( yy + zz )); 1118 m(0,0) = real( GLH_ONE - ( yy + zz ));
1119 m(1,0) = real ( xy + wz ); 1119 m(1,0) = real ( xy + wz );
1120 m(2,0) = real ( xz - wy ); 1120 m(2,0) = real ( xz - wy );
1121 1121
1122 m(0,1) = real ( xy - wz ); 1122 m(0,1) = real ( xy - wz );
1123 m(1,1) = real ( GLH_ONE - ( xx + zz )); 1123 m(1,1) = real ( GLH_ONE - ( xx + zz ));
1124 m(2,1) = real ( yz + wx ); 1124 m(2,1) = real ( yz + wx );
1125 1125
1126 m(0,2) = real ( xz + wy ); 1126 m(0,2) = real ( xz + wy );
1127 m(1,2) = real ( yz - wx ); 1127 m(1,2) = real ( yz - wx );
1128 m(2,2) = real ( GLH_ONE - ( xx + yy )); 1128 m(2,2) = real ( GLH_ONE - ( xx + yy ));
1129 1129
1130 m(3,0) = m(3,1) = m(3,2) = m(0,3) = m(1,3) = m(2,3) = GLH_ZERO; 1130 m(3,0) = m(3,1) = m(3,2) = m(0,3) = m(1,3) = m(2,3) = GLH_ZERO;
1131 m(3,3) = GLH_ONE; 1131 m(3,3) = GLH_ONE;
1132 } 1132 }
1133 1133
1134 quaternion & set_value( const real * qp ) 1134 quaternion & set_value( const real * qp )
1135 { 1135 {
1136 memcpy(q,qp,sizeof(real) * 4); 1136 memcpy(q,qp,sizeof(real) * 4);
1137 1137
1138 counter = 0; 1138 counter = 0;
1139 return *this; 1139 return *this;
1140 } 1140 }
1141 1141
1142 quaternion & set_value( const matrix4 & m ) 1142 quaternion & set_value( const matrix4 & m )
1143 { 1143 {
1144 real tr, s; 1144 real tr, s;
1145 int i, j, k; 1145 int i, j, k;
1146 const int nxt[3] = { 1, 2, 0 }; 1146 const int nxt[3] = { 1, 2, 0 };
1147 1147
1148 tr = m(0,0) + m(1,1) + m(2,2); 1148 tr = m(0,0) + m(1,1) + m(2,2);
1149 1149
1150 if ( tr > GLH_ZERO ) 1150 if ( tr > GLH_ZERO )
1151 { 1151 {
1152 s = real(sqrt( tr + m(3,3) )); 1152 s = real(sqrt( tr + m(3,3) ));
1153 q[3] = real ( s * 0.5 ); 1153 q[3] = real ( s * 0.5 );
1154 s = real(0.5) / s; 1154 s = real(0.5) / s;
1155 1155
1156 q[0] = real ( ( m(1,2) - m(2,1) ) * s ); 1156 q[0] = real ( ( m(1,2) - m(2,1) ) * s );
1157 q[1] = real ( ( m(2,0) - m(0,2) ) * s ); 1157 q[1] = real ( ( m(2,0) - m(0,2) ) * s );
1158 q[2] = real ( ( m(0,1) - m(1,0) ) * s ); 1158 q[2] = real ( ( m(0,1) - m(1,0) ) * s );
1159 } 1159 }
1160 else 1160 else
1161 { 1161 {
1162 i = 0; 1162 i = 0;
1163 if ( m(1,1) > m(0,0) ) 1163 if ( m(1,1) > m(0,0) )
1164 i = 1; 1164 i = 1;
1165 1165
1166 if ( m(2,2) > m(i,i) ) 1166 if ( m(2,2) > m(i,i) )
1167 i = 2; 1167 i = 2;
1168 1168
1169 j = nxt[i]; 1169 j = nxt[i];
1170 k = nxt[j]; 1170 k = nxt[j];
1171 1171
1172 s = real(sqrt( ( m(i,j) - ( m(j,j) + m(k,k) )) + GLH_ONE )); 1172 s = real(sqrt( ( m(i,j) - ( m(j,j) + m(k,k) )) + GLH_ONE ));
1173 1173
1174 q[i] = real ( s * 0.5 ); 1174 q[i] = real ( s * 0.5 );
1175 s = real(0.5 / s); 1175 s = real(0.5 / s);
1176 1176
1177 q[3] = real ( ( m(j,k) - m(k,j) ) * s ); 1177 q[3] = real ( ( m(j,k) - m(k,j) ) * s );
1178 q[j] = real ( ( m(i,j) + m(j,i) ) * s ); 1178 q[j] = real ( ( m(i,j) + m(j,i) ) * s );
1179 q[k] = real ( ( m(i,k) + m(k,i) ) * s ); 1179 q[k] = real ( ( m(i,k) + m(k,i) ) * s );
1180 } 1180 }
1181 1181
1182 counter = 0; 1182 counter = 0;
1183 return *this; 1183 return *this;
1184 } 1184 }
1185 1185
1186 quaternion & set_value( const vec3 &axis, real theta ) 1186 quaternion & set_value( const vec3 &axis, real theta )
1187 { 1187 {
1188 real sqnorm = axis.square_norm(); 1188 real sqnorm = axis.square_norm();
1189 1189
1190 if (sqnorm <= GLH_EPSILON) 1190 if (sqnorm <= GLH_EPSILON)
1191 { 1191 {
1192 // axis too small. 1192 // axis too small.
1193 x = y = z = 0.0; 1193 x = y = z = 0.0;
1194 w = 1.0; 1194 w = 1.0;
1195 } 1195 }
1196 else 1196 else
1197 { 1197 {
1198 theta *= real(0.5); 1198 theta *= real(0.5);
1199 real sin_theta = real(sin(theta)); 1199 real sin_theta = real(sin(theta));
1200 1200
1201 if (!equivalent(sqnorm,GLH_ONE)) 1201 if (!equivalent(sqnorm,GLH_ONE))
1202 sin_theta /= real(sqrt(sqnorm)); 1202 sin_theta /= real(sqrt(sqnorm));
1203 x = sin_theta * axis.v[0]; 1203 x = sin_theta * axis.v[0];
1204 y = sin_theta * axis.v[1]; 1204 y = sin_theta * axis.v[1];
1205 z = sin_theta * axis.v[2]; 1205 z = sin_theta * axis.v[2];
1206 w = real(cos(theta)); 1206 w = real(cos(theta));
1207 } 1207 }
1208 return *this; 1208 return *this;
1209 } 1209 }
1210 1210
1211 quaternion & set_value( const vec3 & rotateFrom, const vec3 & rotateTo ) 1211 quaternion & set_value( const vec3 & rotateFrom, const vec3 & rotateTo )
1212 { 1212 {
1213 vec3 p1, p2; 1213 vec3 p1, p2;
1214 real alpha; 1214 real alpha;
1215 1215
1216 p1 = rotateFrom; 1216 p1 = rotateFrom;
1217 p1.normalize(); 1217 p1.normalize();
1218 p2 = rotateTo; 1218 p2 = rotateTo;
1219 p2.normalize(); 1219 p2.normalize();
1220 1220
1221 alpha = p1.dot(p2); 1221 alpha = p1.dot(p2);
1222 1222
1223 if(equivalent(alpha,GLH_ONE)) 1223 if(equivalent(alpha,GLH_ONE))
1224 { 1224 {
1225 *this = identity(); 1225 *this = identity();
1226 return *this; 1226 return *this;
1227 } 1227 }
1228 1228
1229 // ensures that the anti-parallel case leads to a positive dot 1229 // ensures that the anti-parallel case leads to a positive dot
1230 if(equivalent(alpha,-GLH_ONE)) 1230 if(equivalent(alpha,-GLH_ONE))
1231 { 1231 {
1232 vec3 v; 1232 vec3 v;
1233 1233
1234 if(p1.v[0] != p1.v[1] || p1.v[0] != p1.v[2]) 1234 if(p1.v[0] != p1.v[1] || p1.v[0] != p1.v[2])
1235 v = vec3(p1.v[1], p1.v[2], p1.v[0]); 1235 v = vec3(p1.v[1], p1.v[2], p1.v[0]);
1236 else 1236 else
1237 v = vec3(-p1.v[0], p1.v[1], p1.v[2]); 1237 v = vec3(-p1.v[0], p1.v[1], p1.v[2]);
1238 1238
1239 v -= p1 * p1.dot(v); 1239 v -= p1 * p1.dot(v);
1240 v.normalize(); 1240 v.normalize();
1241 1241
1242 set_value(v, GLH_PI); 1242 set_value(v, GLH_PI);
1243 return *this; 1243 return *this;
1244 } 1244 }
1245 1245
1246 p1 = p1.cross(p2); 1246 p1 = p1.cross(p2);
1247 p1.normalize(); 1247 p1.normalize();
1248 set_value(p1,real(acos(alpha))); 1248 set_value(p1,real(acos(alpha)));
1249 1249
1250 counter = 0; 1250 counter = 0;
1251 return *this; 1251 return *this;
1252 } 1252 }
1253 1253
1254 quaternion & set_value( const vec3 & from_look, const vec3 & from_up, 1254 quaternion & set_value( const vec3 & from_look, const vec3 & from_up,
1255 const vec3 & to_look, const vec3 & to_up) 1255 const vec3 & to_look, const vec3 & to_up)
1256 { 1256 {
1257 quaternion r_look = quaternion(from_look, to_look); 1257 quaternion r_look = quaternion(from_look, to_look);
1258 1258
1259 vec3 rotated_from_up(from_up); 1259 vec3 rotated_from_up(from_up);
1260 r_look.mult_vec(rotated_from_up); 1260 r_look.mult_vec(rotated_from_up);
1261 1261
1262 quaternion r_twist = quaternion(rotated_from_up, to_up); 1262 quaternion r_twist = quaternion(rotated_from_up, to_up);
1263 1263
1264 *this = r_twist; 1264 *this = r_twist;
1265 *this *= r_look; 1265 *this *= r_look;
1266 return *this; 1266 return *this;
1267 } 1267 }
1268 1268
1269 quaternion & operator *= ( const quaternion & qr ) 1269 quaternion & operator *= ( const quaternion & qr )
1270 { 1270 {
1271 quaternion ql(*this); 1271 quaternion ql(*this);
1272 1272
1273 w = ql.w * qr.w - ql.x * qr.x - ql.y * qr.y - ql.z * qr.z; 1273 w = ql.w * qr.w - ql.x * qr.x - ql.y * qr.y - ql.z * qr.z;
1274 x = ql.w * qr.x + ql.x * qr.w + ql.y * qr.z - ql.z * qr.y; 1274 x = ql.w * qr.x + ql.x * qr.w + ql.y * qr.z - ql.z * qr.y;
1275 y = ql.w * qr.y + ql.y * qr.w + ql.z * qr.x - ql.x * qr.z; 1275 y = ql.w * qr.y + ql.y * qr.w + ql.z * qr.x - ql.x * qr.z;
1276 z = ql.w * qr.z + ql.z * qr.w + ql.x * qr.y - ql.y * qr.x; 1276 z = ql.w * qr.z + ql.z * qr.w + ql.x * qr.y - ql.y * qr.x;
1277 1277
1278 counter += qr.counter; 1278 counter += qr.counter;
1279 counter++; 1279 counter++;
1280 counter_normalize(); 1280 counter_normalize();
1281 return *this; 1281 return *this;
1282 } 1282 }
1283 1283
1284 void normalize() 1284 void normalize()
1285 { 1285 {
1286 real rnorm = GLH_ONE / real(sqrt(w * w + x * x + y * y + z * z)); 1286 real rnorm = GLH_ONE / real(sqrt(w * w + x * x + y * y + z * z));
1287 if (equivalent(rnorm, GLH_ZERO)) 1287 if (equivalent(rnorm, GLH_ZERO))
1288 return; 1288 return;
1289 x *= rnorm; 1289 x *= rnorm;
1290 y *= rnorm; 1290 y *= rnorm;
1291 z *= rnorm; 1291 z *= rnorm;
1292 w *= rnorm; 1292 w *= rnorm;
1293 counter = 0; 1293 counter = 0;
1294 } 1294 }
1295 1295
1296 friend bool operator == ( const quaternion & q1, const quaternion & q2 ); 1296 friend bool operator == ( const quaternion & q1, const quaternion & q2 );
1297 1297
1298 friend bool operator != ( const quaternion & q1, const quaternion & q2 ); 1298 friend bool operator != ( const quaternion & q1, const quaternion & q2 );
1299 1299
1300 friend quaternion operator * ( const quaternion & q1, const quaternion & q2 ); 1300 friend quaternion operator * ( const quaternion & q1, const quaternion & q2 );
1301 1301
1302 bool equals( const quaternion & r, real tolerance ) const 1302 bool equals( const quaternion & r, real tolerance ) const
1303 { 1303 {
1304 real t; 1304 real t;
1305 1305
1306 t = ( 1306 t = (
1307 (q[0]-r.q[0])*(q[0]-r.q[0]) + 1307 (q[0]-r.q[0])*(q[0]-r.q[0]) +
1308 (q[1]-r.q[1])*(q[1]-r.q[1]) + 1308 (q[1]-r.q[1])*(q[1]-r.q[1]) +
1309 (q[2]-r.q[2])*(q[2]-r.q[2]) + 1309 (q[2]-r.q[2])*(q[2]-r.q[2]) +
1310 (q[3]-r.q[3])*(q[3]-r.q[3]) ); 1310 (q[3]-r.q[3])*(q[3]-r.q[3]) );
1311 if(t > GLH_EPSILON) 1311 if(t > GLH_EPSILON)
1312 return false; 1312 return false;
1313 return 1; 1313 return 1;
1314 } 1314 }
1315 1315
1316 quaternion & conjugate() 1316 quaternion & conjugate()
1317 { 1317 {
1318 q[0] *= -GLH_ONE; 1318 q[0] *= -GLH_ONE;
1319 q[1] *= -GLH_ONE; 1319 q[1] *= -GLH_ONE;
1320 q[2] *= -GLH_ONE; 1320 q[2] *= -GLH_ONE;
1321 return *this; 1321 return *this;
1322 } 1322 }
1323 1323
1324 quaternion & invert() 1324 quaternion & invert()
1325 { 1325 {
1326 return conjugate(); 1326 return conjugate();
1327 } 1327 }
1328 1328
1329 quaternion inverse() const 1329 quaternion inverse() const
1330 { 1330 {
1331 quaternion r = *this; 1331 quaternion r = *this;
1332 return r.invert(); 1332 return r.invert();
1333 } 1333 }
1334 1334
1335 // 1335 //
1336 // Quaternion multiplication with cartesian vector 1336 // Quaternion multiplication with cartesian vector
1337 // v' = q*v*q(star) 1337 // v' = q*v*q(star)
1338 // 1338 //
1339 void mult_vec( const vec3 &src, vec3 &dst ) const 1339 void mult_vec( const vec3 &src, vec3 &dst ) const
1340 { 1340 {
1341 real v_coef = w * w - x * x - y * y - z * z; 1341 real v_coef = w * w - x * x - y * y - z * z;
1342 real u_coef = GLH_TWO * (src.v[0] * x + src.v[1] * y + src.v[2] * z); 1342 real u_coef = GLH_TWO * (src.v[0] * x + src.v[1] * y + src.v[2] * z);
1343 real c_coef = GLH_TWO * w; 1343 real c_coef = GLH_TWO * w;
1344 1344
1345 dst.v[0] = v_coef * src.v[0] + u_coef * x + c_coef * (y * src.v[2] - z * src.v[1]); 1345 dst.v[0] = v_coef * src.v[0] + u_coef * x + c_coef * (y * src.v[2] - z * src.v[1]);
1346 dst.v[1] = v_coef * src.v[1] + u_coef * y + c_coef * (z * src.v[0] - x * src.v[2]); 1346 dst.v[1] = v_coef * src.v[1] + u_coef * y + c_coef * (z * src.v[0] - x * src.v[2]);
1347 dst.v[2] = v_coef * src.v[2] + u_coef * z + c_coef * (x * src.v[1] - y * src.v[0]); 1347 dst.v[2] = v_coef * src.v[2] + u_coef * z + c_coef * (x * src.v[1] - y * src.v[0]);
1348 } 1348 }
1349 1349
1350 void mult_vec( vec3 & src_and_dst) const 1350 void mult_vec( vec3 & src_and_dst) const
1351 { 1351 {
1352 mult_vec(vec3(src_and_dst), src_and_dst); 1352 mult_vec(vec3(src_and_dst), src_and_dst);
1353 } 1353 }
1354 1354
1355 void scale_angle( real scaleFactor ) 1355 void scale_angle( real scaleFactor )
1356 { 1356 {
1357 vec3 axis; 1357 vec3 axis;
1358 real radians; 1358 real radians;
1359 1359
1360 get_value(axis, radians); 1360 get_value(axis, radians);
1361 radians *= scaleFactor; 1361 radians *= scaleFactor;
1362 set_value(axis, radians); 1362 set_value(axis, radians);
1363 } 1363 }
1364 1364
1365 static quaternion slerp( const quaternion & p, const quaternion & q, real alpha ) 1365 static quaternion slerp( const quaternion & p, const quaternion & q, real alpha )
1366 { 1366 {
1367 quaternion r; 1367 quaternion r;
1368 1368
1369 real cos_omega = p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w; 1369 real cos_omega = p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w;
1370 // if B is on opposite hemisphere from A, use -B instead 1370 // if B is on opposite hemisphere from A, use -B instead
1371 1371
1372 int bflip; 1372 int bflip;
1373 if ( ( bflip = (cos_omega < GLH_ZERO)) ) 1373 if ( ( bflip = (cos_omega < GLH_ZERO)) )
1374 cos_omega = -cos_omega; 1374 cos_omega = -cos_omega;
1375 1375
1376 // complementary interpolation parameter 1376 // complementary interpolation parameter
1377 real beta = GLH_ONE - alpha; 1377 real beta = GLH_ONE - alpha;
1378 1378
1379 if(cos_omega <= GLH_ONE - GLH_EPSILON) 1379 if(cos_omega <= GLH_ONE - GLH_EPSILON)
1380 return p; 1380 return p;
1381 1381
1382 real omega = real(acos(cos_omega)); 1382 real omega = real(acos(cos_omega));
1383 real one_over_sin_omega = GLH_ONE / real(sin(omega)); 1383 real one_over_sin_omega = GLH_ONE / real(sin(omega));
1384 1384
1385 beta = real(sin(omega*beta) * one_over_sin_omega); 1385 beta = real(sin(omega*beta) * one_over_sin_omega);
1386 alpha = real(sin(omega*alpha) * one_over_sin_omega); 1386 alpha = real(sin(omega*alpha) * one_over_sin_omega);
1387 1387
1388 if (bflip) 1388 if (bflip)
1389 alpha = -alpha; 1389 alpha = -alpha;
1390 1390
1391 r.x = beta * p.q[0]+ alpha * q.q[0]; 1391 r.x = beta * p.q[0]+ alpha * q.q[0];
1392 r.y = beta * p.q[1]+ alpha * q.q[1]; 1392 r.y = beta * p.q[1]+ alpha * q.q[1];
1393 r.z = beta * p.q[2]+ alpha * q.q[2]; 1393 r.z = beta * p.q[2]+ alpha * q.q[2];
1394 r.w = beta * p.q[3]+ alpha * q.q[3]; 1394 r.w = beta * p.q[3]+ alpha * q.q[3];
1395 return r; 1395 return r;
1396 } 1396 }
1397 1397
1398 static quaternion identity() 1398 static quaternion identity()
1399 { 1399 {
1400 static quaternion ident( vec3( 0.0, 0.0, 0.0 ), GLH_ONE ); 1400 static quaternion ident( vec3( 0.0, 0.0, 0.0 ), GLH_ONE );
1401 return ident; 1401 return ident;
1402 } 1402 }
1403 1403
1404 real & operator []( int i ) 1404 real & operator []( int i )
1405 { 1405 {
1406 assert(i < 4); 1406 assert(i < 4);
1407 return q[i]; 1407 return q[i];
1408 } 1408 }
1409 1409
1410 const real & operator []( int i ) const 1410 const real & operator []( int i ) const
1411 { 1411 {
1412 assert(i < 4); 1412 assert(i < 4);
1413 return q[i]; 1413 return q[i];
1414 } 1414 }
1415 1415
1416 protected: 1416 protected:
1417 1417
1418 void counter_normalize() 1418 void counter_normalize()
1419 { 1419 {
1420 if (counter > GLH_QUATERNION_NORMALIZATION_THRESHOLD) 1420 if (counter > GLH_QUATERNION_NORMALIZATION_THRESHOLD)
1421 normalize(); 1421 normalize();
1422 } 1422 }
1423 1423
1424 union 1424 union
1425 { 1425 {
1426 struct 1426 struct
1427 { 1427 {
1428 real q[4]; 1428 real q[4];
1429 }; 1429 };
1430 struct 1430 struct
1431 { 1431 {
1432 real x; 1432 real x;
1433 real y; 1433 real y;
1434 real z; 1434 real z;
1435 real w; 1435 real w;
1436 }; 1436 };
1437 }; 1437 };
1438 1438
1439 // renormalization counter 1439 // renormalization counter
1440 unsigned char counter; 1440 unsigned char counter;
1441 }; 1441 };
1442 1442
1443 inline 1443 inline
1444 bool operator == ( const quaternion & q1, const quaternion & q2 ) 1444 bool operator == ( const quaternion & q1, const quaternion & q2 )
1445 { 1445 {
1446 return (equivalent(q1.x, q2.x) && 1446 return (equivalent(q1.x, q2.x) &&
1447 equivalent(q1.y, q2.y) && 1447 equivalent(q1.y, q2.y) &&
1448 equivalent(q1.z, q2.z) && 1448 equivalent(q1.z, q2.z) &&
1449 equivalent(q1.w, q2.w) ); 1449 equivalent(q1.w, q2.w) );
1450 } 1450 }
1451 1451
1452 inline 1452 inline
1453 bool operator != ( const quaternion & q1, const quaternion & q2 ) 1453 bool operator != ( const quaternion & q1, const quaternion & q2 )
1454 { 1454 {
1455 return ! ( q1 == q2 ); 1455 return ! ( q1 == q2 );
1456 } 1456 }
1457 1457
1458 inline 1458 inline
1459 quaternion operator * ( const quaternion & q1, const quaternion & q2 ) 1459 quaternion operator * ( const quaternion & q1, const quaternion & q2 )
1460 { 1460 {
1461 quaternion r(q1); 1461 quaternion r(q1);
1462 r *= q2; 1462 r *= q2;
1463 return r; 1463 return r;
1464 } 1464 }
1465 1465
1466 1466
1467 1467
1468 1468
1469 1469
1470 1470
1471 1471
1472 1472
1473 1473
1474 1474
1475 class plane 1475 class plane
1476 { 1476 {
1477 public: 1477 public:
1478 1478
1479 plane() 1479 plane()
1480 { 1480 {
1481 planedistance = 0.0; 1481 planedistance = 0.0;
1482 planenormal.set_value( 0.0, 0.0, 1.0 ); 1482 planenormal.set_value( 0.0, 0.0, 1.0 );
1483 } 1483 }
1484 1484
1485 1485
1486 plane( const vec3 &p0, const vec3 &p1, const vec3 &p2 ) 1486 plane( const vec3 &p0, const vec3 &p1, const vec3 &p2 )
1487 { 1487 {
1488 vec3 v0 = p1 - p0; 1488 vec3 v0 = p1 - p0;
1489 vec3 v1 = p2 - p0; 1489 vec3 v1 = p2 - p0;
1490 planenormal = v0.cross(v1); 1490 planenormal = v0.cross(v1);
1491 planenormal.normalize(); 1491 planenormal.normalize();
1492 planedistance = p0.dot(planenormal); 1492 planedistance = p0.dot(planenormal);
1493 } 1493 }
1494 1494
1495 plane( const vec3 &normal, real distance ) 1495 plane( const vec3 &normal, real distance )
1496 { 1496 {
1497 planedistance = distance; 1497 planedistance = distance;
1498 planenormal = normal; 1498 planenormal = normal;
1499 planenormal.normalize(); 1499 planenormal.normalize();
1500 } 1500 }
1501 1501
1502 plane( const vec3 &normal, const vec3 &point ) 1502 plane( const vec3 &normal, const vec3 &point )
1503 { 1503 {
1504 planenormal = normal; 1504 planenormal = normal;
1505 planenormal.normalize(); 1505 planenormal.normalize();
1506 planedistance = point.dot(planenormal); 1506 planedistance = point.dot(planenormal);
1507 } 1507 }
1508 1508
1509 void offset( real d ) 1509 void offset( real d )
1510 { 1510 {
1511 planedistance += d; 1511 planedistance += d;
1512 } 1512 }
1513 1513
1514 bool intersect( const line &l, vec3 &intersection ) const 1514 bool intersect( const line &l, vec3 &intersection ) const
1515 { 1515 {
1516 vec3 pos, dir; 1516 vec3 pos, dir;
1517 vec3 pn = planenormal; 1517 vec3 pn = planenormal;
1518 real pd = planedistance; 1518 real pd = planedistance;
1519 1519
1520 pos = l.get_position(); 1520 pos = l.get_position();
1521 dir = l.get_direction(); 1521 dir = l.get_direction();
1522 1522
1523 if(dir.dot(pn) == 0.0) return 0; 1523 if(dir.dot(pn) == 0.0) return 0;
1524 pos -= pn*pd; 1524 pos -= pn*pd;
1525 // now we're talking about a plane passing through the origin 1525 // now we're talking about a plane passing through the origin
1526 if(pos.dot(pn) < 0.0) pn.negate(); 1526 if(pos.dot(pn) < 0.0) pn.negate();
1527 if(dir.dot(pn) > 0.0) dir.negate(); 1527 if(dir.dot(pn) > 0.0) dir.negate();
1528 vec3 ppos = pn * pos.dot(pn); 1528 vec3 ppos = pn * pos.dot(pn);
1529 pos = (ppos.length()/dir.dot(-pn))*dir; 1529 pos = (ppos.length()/dir.dot(-pn))*dir;
1530 intersection = l.get_position(); 1530 intersection = l.get_position();
1531 intersection += pos; 1531 intersection += pos;
1532 return 1; 1532 return 1;
1533 } 1533 }
1534 void transform( const matrix4 &matrix ) 1534 void transform( const matrix4 &matrix )
1535 { 1535 {
1536 matrix4 invtr = matrix.inverse(); 1536 matrix4 invtr = matrix.inverse();
1537 invtr = invtr.transpose(); 1537 invtr = invtr.transpose();
1538 1538
1539 vec3 pntOnplane = planenormal * planedistance; 1539 vec3 pntOnplane = planenormal * planedistance;
1540 vec3 newPntOnplane; 1540 vec3 newPntOnplane;
1541 vec3 newnormal; 1541 vec3 newnormal;
1542 1542
1543 invtr.mult_dir_matrix(planenormal, newnormal); 1543 invtr.mult_dir_matrix(planenormal, newnormal);
1544 matrix.mult_vec_matrix(pntOnplane, newPntOnplane); 1544 matrix.mult_vec_matrix(pntOnplane, newPntOnplane);
1545 1545
1546 newnormal.normalize(); 1546 newnormal.normalize();
1547 planenormal = newnormal; 1547 planenormal = newnormal;
1548 planedistance = newPntOnplane.dot(planenormal); 1548 planedistance = newPntOnplane.dot(planenormal);
1549 } 1549 }
1550 1550
1551 bool is_in_half_space( const vec3 &point ) const 1551 bool is_in_half_space( const vec3 &point ) const
1552 { 1552 {
1553 1553
1554 if(( point.dot(planenormal) - planedistance) < 0.0) 1554 if(( point.dot(planenormal) - planedistance) < 0.0)
1555 return 0; 1555 return 0;
1556 return 1; 1556 return 1;
1557 } 1557 }
1558 1558
1559 1559
1560 real distance( const vec3 & point ) const 1560 real distance( const vec3 & point ) const
1561 { 1561 {
1562 return planenormal.dot(point - planenormal*planedistance); 1562 return planenormal.dot(point - planenormal*planedistance);
1563 } 1563 }
1564 1564
1565 const vec3 &get_normal() const 1565 const vec3 &get_normal() const
1566 { 1566 {
1567 return planenormal; 1567 return planenormal;
1568 } 1568 }
1569 1569
1570 1570
1571 real get_distance_from_origin() const 1571 real get_distance_from_origin() const
1572 { 1572 {
1573 return planedistance; 1573 return planedistance;
1574 } 1574 }
1575 1575
1576 1576
1577 friend bool operator == ( const plane & p1, const plane & p2 ); 1577 friend bool operator == ( const plane & p1, const plane & p2 );
1578 1578
1579 1579
1580 friend bool operator != ( const plane & p1, const plane & p2 ); 1580 friend bool operator != ( const plane & p1, const plane & p2 );
1581 1581
1582 //protected: 1582 //protected:
1583 vec3 planenormal; 1583 vec3 planenormal;
1584 real planedistance; 1584 real planedistance;
1585 }; 1585 };
1586 1586
1587 inline 1587 inline
1588 bool operator == (const plane & p1, const plane & p2 ) 1588 bool operator == (const plane & p1, const plane & p2 )
1589 { 1589 {
1590 return ( p1.planedistance == p2.planedistance && p1.planenormal == p2.planenormal); 1590 return ( p1.planedistance == p2.planedistance && p1.planenormal == p2.planenormal);
1591 } 1591 }
1592 1592
1593 inline 1593 inline
1594 bool operator != ( const plane & p1, const plane & p2 ) 1594 bool operator != ( const plane & p1, const plane & p2 )
1595 { return ! (p1 == p2); } 1595 { return ! (p1 == p2); }
1596 1596
1597 1597
1598 1598
1599 } // "ns_##GLH_REAL" 1599 } // "ns_##GLH_REAL"
1600 1600
1601 // make common typedefs... 1601 // make common typedefs...
1602#ifdef GLH_REAL_IS_FLOAT 1602#ifdef GLH_REAL_IS_FLOAT
1603 typedef GLH_REAL_NAMESPACE::vec2 vec2f; 1603 typedef GLH_REAL_NAMESPACE::vec2 vec2f;
1604 typedef GLH_REAL_NAMESPACE::vec3 vec3f; 1604 typedef GLH_REAL_NAMESPACE::vec3 vec3f;
1605 typedef GLH_REAL_NAMESPACE::vec4 vec4f; 1605 typedef GLH_REAL_NAMESPACE::vec4 vec4f;
1606 typedef GLH_REAL_NAMESPACE::quaternion quaternionf; 1606 typedef GLH_REAL_NAMESPACE::quaternion quaternionf;
1607 typedef GLH_REAL_NAMESPACE::quaternion rotationf; 1607 typedef GLH_REAL_NAMESPACE::quaternion rotationf;
1608 typedef GLH_REAL_NAMESPACE::line linef; 1608 typedef GLH_REAL_NAMESPACE::line linef;
1609 typedef GLH_REAL_NAMESPACE::plane planef; 1609 typedef GLH_REAL_NAMESPACE::plane planef;
1610 typedef GLH_REAL_NAMESPACE::matrix4 matrix4f; 1610 typedef GLH_REAL_NAMESPACE::matrix4 matrix4f;
1611#endif 1611#endif
1612 1612
1613 1613
1614 1614
1615 1615
1616} // namespace glh 1616} // namespace glh
1617 1617
1618 1618
1619 1619
1620#endif 1620#endif
1621 1621
diff --git a/linden/indra/newview/llcloud.cpp b/linden/indra/newview/llcloud.cpp
index 3e9b86a..b325265 100644
--- a/linden/indra/newview/llcloud.cpp
+++ b/linden/indra/newview/llcloud.cpp
@@ -427,7 +427,7 @@ void LLCloudLayer::decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp)
427 group_headerp->stride = group_headerp->patch_size; // offset required to step up one row 427 group_headerp->stride = group_headerp->patch_size; // offset required to step up one row
428 set_group_of_patch_header(group_headerp); 428 set_group_of_patch_header(group_headerp);
429 429
430 decode_patch_header(bitpack, &patch_header); 430 decode_patch_header(bitpack, &patch_header, FALSE);
431 decode_patch(bitpack, gBuffer); 431 decode_patch(bitpack, gBuffer);
432 decompress_patch(mDensityp, gBuffer, &patch_header); 432 decompress_patch(mDensityp, gBuffer, &patch_header);
433} 433}
diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp
index d4ffe22..4880308 100644
--- a/linden/indra/newview/llfloaterregioninfo.cpp
+++ b/linden/indra/newview/llfloaterregioninfo.cpp
@@ -1244,10 +1244,10 @@ BOOL LLPanelRegionTextureInfo::sendUpdate()
1244 llinfos << "LLPanelRegionTextureInfo::sendUpdate()" << llendl; 1244 llinfos << "LLPanelRegionTextureInfo::sendUpdate()" << llendl;
1245 1245
1246 // Make sure user hasn't chosen wacky textures. 1246 // Make sure user hasn't chosen wacky textures.
1247 if (!validateTextureSizes()) 1247 //if (!validateTextureSizes())
1248 { 1248 //{
1249 return FALSE; 1249 // return FALSE;
1250 } 1250 //}
1251 1251
1252 LLTextureCtrl* texture_ctrl; 1252 LLTextureCtrl* texture_ctrl;
1253 std::string buffer; 1253 std::string buffer;
diff --git a/linden/indra/newview/llglsandbox.cpp b/linden/indra/newview/llglsandbox.cpp
index 98c4d06..96fd39b 100644
--- a/linden/indra/newview/llglsandbox.cpp
+++ b/linden/indra/newview/llglsandbox.cpp
@@ -710,7 +710,7 @@ void LLViewerParcelMgr::renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 hei
710{ 710{
711 // HACK: At edge of last region of world, we need to make sure the region 711 // HACK: At edge of last region of world, we need to make sure the region
712 // resolves correctly so we can get a height value. 712 // resolves correctly so we can get a height value.
713 const F32 BORDER = REGION_WIDTH_METERS - 0.1f; 713 const F32 BORDER = regionp->getWidth() - 0.1f;
714 714
715 F32 clamped_x1 = x1; 715 F32 clamped_x1 = x1;
716 F32 clamped_y1 = y1; 716 F32 clamped_y1 = y1;
diff --git a/linden/indra/newview/llmapresponders.cpp b/linden/indra/newview/llmapresponders.cpp
index 9d974f2..b6b5c8a 100644
--- a/linden/indra/newview/llmapresponders.cpp
+++ b/linden/indra/newview/llmapresponders.cpp
@@ -120,6 +120,8 @@ void LLMapLayerResponder::result(const LLSD& result)
120 120
121 S32 x_regions = map_block["X"]; 121 S32 x_regions = map_block["X"];
122 S32 y_regions = map_block["Y"]; 122 S32 y_regions = map_block["Y"];
123 S32 size_x_regions = map_block["SizeX"];
124 S32 size_y_regions = map_block["SizeY"];
123 std::string name = map_block["Name"]; 125 std::string name = map_block["Name"];
124 S32 access = map_block["Access"]; 126 S32 access = map_block["Access"];
125 S32 region_flags = map_block["RegionFlags"]; 127 S32 region_flags = map_block["RegionFlags"];
@@ -168,6 +170,8 @@ void LLMapLayerResponder::result(const LLSD& result)
168 LLWorldMap::getInstance()->mSimInfoMap[handle] = siminfo; 170 LLWorldMap::getInstance()->mSimInfoMap[handle] = siminfo;
169 171
170 siminfo->mHandle = handle; 172 siminfo->mHandle = handle;
173 siminfo->msizeX = size_x_regions;
174 siminfo->msizeY = size_y_regions;
171 siminfo->mName.assign( name ); 175 siminfo->mName.assign( name );
172 siminfo->mAccess = access; /*Flawfinder: ignore*/ 176 siminfo->mAccess = access; /*Flawfinder: ignore*/
173 siminfo->mRegionFlags = region_flags; 177 siminfo->mRegionFlags = region_flags;
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index 5a3a8ee..0b6d75f 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -368,6 +368,8 @@ bool idle_startup()
368 static U64 first_sim_handle = 0; 368 static U64 first_sim_handle = 0;
369 static LLHost first_sim; 369 static LLHost first_sim;
370 static std::string first_sim_seed_cap; 370 static std::string first_sim_seed_cap;
371 static U32 first_sim_size_x = 256;
372 static U32 first_sim_size_y = 256;
371 373
372 static LLVector3 initial_sun_direction(1.f, 0.f, 0.f); 374 static LLVector3 initial_sun_direction(1.f, 0.f, 0.f);
373 static LLVector3 agent_start_position_region(10.f, 10.f, 10.f); // default for when no space server 375 static LLVector3 agent_start_position_region(10.f, 10.f, 10.f); // default for when no space server
@@ -1620,6 +1622,16 @@ bool idle_startup()
1620 first_sim_handle = to_region_handle(region_x, region_y); 1622 first_sim_handle = to_region_handle(region_x, region_y);
1621 } 1623 }
1622 1624
1625 text = LLUserAuth::getInstance()->getResponse("region_size_x");
1626 if(!text.empty()) {
1627 first_sim_size_x = strtoul(text.c_str(), NULL, 10);
1628 LLViewerParcelMgr::getInstance()->init(first_sim_size_x);
1629 }
1630
1631 //region Y size is currently unused, major refactoring required. - Patrick Sapinski (2/10/2011)
1632 text = LLUserAuth::getInstance()->getResponse("region_size_y");
1633 if(!text.empty()) first_sim_size_y = strtoul(text.c_str(), NULL, 10);
1634
1623 const std::string look_at_str = LLUserAuth::getInstance()->getResponse("look_at"); 1635 const std::string look_at_str = LLUserAuth::getInstance()->getResponse("look_at");
1624 if (!look_at_str.empty()) 1636 if (!look_at_str.empty())
1625 { 1637 {
@@ -1915,7 +1927,7 @@ bool idle_startup()
1915 1927
1916 gAgent.initOriginGlobal(from_region_handle(first_sim_handle)); 1928 gAgent.initOriginGlobal(from_region_handle(first_sim_handle));
1917 1929
1918 LLWorld::getInstance()->addRegion(first_sim_handle, first_sim); 1930 LLWorld::getInstance()->addRegion(first_sim_handle, first_sim, first_sim_size_x, first_sim_size_y);
1919 1931
1920 LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(first_sim_handle); 1932 LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(first_sim_handle);
1921 LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL; 1933 LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL;
diff --git a/linden/indra/newview/llsurface.cpp b/linden/indra/newview/llsurface.cpp
index aaafe0d..66f8076 100644
--- a/linden/indra/newview/llsurface.cpp
+++ b/linden/indra/newview/llsurface.cpp
@@ -303,7 +303,7 @@ void LLSurface::initTextures()
303 mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp); 303 mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);
304 gPipeline.createObject(mWaterObjp); 304 gPipeline.createObject(mWaterObjp);
305 LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle()); 305 LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle());
306 water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); 306 water_pos_global += LLVector3d(mRegionp->getWidth()/2, mRegionp->getWidth()/2, DEFAULT_WATER_HEIGHT);
307 mWaterObjp->setPositionGlobal(water_pos_global); 307 mWaterObjp->setPositionGlobal(water_pos_global);
308 } 308 }
309} 309}
@@ -356,8 +356,8 @@ void LLSurface::setOriginGlobal(const LLVector3d &origin_global)
356 // Hack! 356 // Hack!
357 if (mWaterObjp.notNull() && mWaterObjp->mDrawable.notNull()) 357 if (mWaterObjp.notNull() && mWaterObjp->mDrawable.notNull())
358 { 358 {
359 const F64 x = origin_global.mdV[VX] + 128.0; 359 const F64 x = origin_global.mdV[VX] + (F64)mRegionp->getWidth()/2;
360 const F64 y = origin_global.mdV[VY] + 128.0; 360 const F64 y = origin_global.mdV[VY] + (F64)mRegionp->getWidth()/2;
361 const F64 z = mWaterObjp->getPositionGlobal().mdV[VZ]; 361 const F64 z = mWaterObjp->getPositionGlobal().mdV[VZ];
362 362
363 LLVector3d water_origin_global(x, y, z); 363 LLVector3d water_origin_global(x, y, z);
@@ -707,14 +707,22 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL
707 707
708 while (1) 708 while (1)
709 { 709 {
710 decode_patch_header(bitpack, &ph); 710 decode_patch_header(bitpack, &ph, b_large_patch);
711 if (ph.quant_wbits == END_OF_PATCHES) 711 if (ph.quant_wbits == END_OF_PATCHES)
712 { 712 {
713 break; 713 break;
714 } 714 }
715 715
716 i = ph.patchids >> 5; 716 if (b_large_patch)
717 j = ph.patchids & 0x1F; 717 {
718 i = ph.patchids >> 16; //x
719 j = ph.patchids & 0xFFFF; //y
720 }
721 else
722 {
723 i = ph.patchids >> 5; //x
724 j = ph.patchids & 0x1F; //y
725 }
718 726
719 if ((i >= mPatchesPerEdge) || (j >= mPatchesPerEdge)) 727 if ((i >= mPatchesPerEdge) || (j >= mPatchesPerEdge))
720 { 728 {
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 9ebfd04..4de4768 100755
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -3531,6 +3531,17 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
3531 U32 teleport_flags; 3531 U32 teleport_flags;
3532 msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags); 3532 msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
3533 3533
3534 U32 region_size_x = 256;
3535 msg->getU32Fast(_PREHASH_Info, _PREHASH_RegionSizeX, region_size_x);
3536 U32 region_size_y = 256;
3537 msg->getU32Fast(_PREHASH_Info, _PREHASH_RegionSizeY, region_size_y);
3538
3539 //and a little hack for Second Life compatibility
3540 if (region_size_y == 0 || region_size_x == 0)
3541 {
3542 region_size_x = 256;
3543 region_size_y = 256;
3544 }
3534 3545
3535 std::string seedCap; 3546 std::string seedCap;
3536 msg->getStringFast(_PREHASH_Info, _PREHASH_SeedCapability, seedCap); 3547 msg->getStringFast(_PREHASH_Info, _PREHASH_SeedCapability, seedCap);
@@ -3550,7 +3561,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
3550 3561
3551 // Viewer trusts the simulator. 3562 // Viewer trusts the simulator.
3552 gMessageSystem->enableCircuit(sim_host, TRUE); 3563 gMessageSystem->enableCircuit(sim_host, TRUE);
3553 LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host); 3564 LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host, region_size_x, region_size_y);
3554 3565
3555/* 3566/*
3556 // send camera update to new region 3567 // send camera update to new region
@@ -3866,9 +3877,21 @@ void process_crossed_region(LLMessageSystem* msg, void**)
3866 std::string seedCap; 3877 std::string seedCap;
3867 msg->getStringFast(_PREHASH_RegionData, _PREHASH_SeedCapability, seedCap); 3878 msg->getStringFast(_PREHASH_RegionData, _PREHASH_SeedCapability, seedCap);
3868 3879
3880 U32 region_size_x = 256;
3881 msg->getU32(_PREHASH_RegionData, _PREHASH_RegionSizeX, region_size_x);
3882 U32 region_size_y = 256;
3883 msg->getU32(_PREHASH_RegionData, _PREHASH_RegionSizeY, region_size_y);
3884
3885 //and a little hack for Second Life compatibility
3886 if (region_size_y == 0 || region_size_x == 0)
3887 {
3888 region_size_x = 256;
3889 region_size_y = 256;
3890 }
3891
3869 send_complete_agent_movement(sim_host); 3892 send_complete_agent_movement(sim_host);
3870 3893
3871 LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host); 3894 LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host, region_size_x, region_size_y);
3872 regionp->setSeedCapability(seedCap); 3895 regionp->setSeedCapability(seedCap);
3873 3896
3874 // Tell the LightShare handler that we have changed regions. 3897 // Tell the LightShare handler that we have changed regions.
diff --git a/linden/indra/newview/llviewerparcelmgr.cpp b/linden/indra/newview/llviewerparcelmgr.cpp
index 630da54..abe0e9f 100644
--- a/linden/indra/newview/llviewerparcelmgr.cpp
+++ b/linden/indra/newview/llviewerparcelmgr.cpp
@@ -137,6 +137,18 @@ LLViewerParcelMgr::LLViewerParcelMgr()
137 mHoverParcel = new LLParcel(); 137 mHoverParcel = new LLParcel();
138 mCollisionParcel = new LLParcel(); 138 mCollisionParcel = new LLParcel();
139 139
140 mBlockedImage = gImageList.getImageFromFile("noentrylines.j2c");
141 mPassImage = gImageList.getImageFromFile("noentrypasslines.j2c");
142
143 init(256);
144}
145
146//moved this stuff out of the constructor and into a function that we can call again after we get the region size.
147//LLViewerParcelMgr needs to be changed so we either get an instance per region, or it handles various region sizes
148//on a single grid properly - Patrick Sapinski (2/10/2011)
149void LLViewerParcelMgr::init(F32 region_size)
150{
151
140 mParcelsPerEdge = S32( REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS ); 152 mParcelsPerEdge = S32( REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS );
141 mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)]; 153 mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
142 resetSegments(mHighlightSegments); 154 resetSegments(mHighlightSegments);
@@ -144,10 +156,9 @@ LLViewerParcelMgr::LLViewerParcelMgr()
144 mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)]; 156 mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
145 resetSegments(mCollisionSegments); 157 resetSegments(mCollisionSegments);
146 158
147 mBlockedImage = gImageList.getImageFromFile("noentrylines.j2c"); 159 S32 mParcelOverLayChunks = region_size * region_size / (128 * 128);
148 mPassImage = gImageList.getImageFromFile("noentrypasslines.j2c"); 160
149 161 S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / mParcelOverLayChunks;
150 S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS;
151 sPackedOverlay = new U8[overlay_size]; 162 sPackedOverlay = new U8[overlay_size];
152 163
153 mAgentParcelOverlay = new U8[mParcelsPerEdge * mParcelsPerEdge]; 164 mAgentParcelOverlay = new U8[mParcelsPerEdge * mParcelsPerEdge];
@@ -1351,8 +1362,7 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
1351 return; 1362 return;
1352 } 1363 }
1353 1364
1354 S32 parcels_per_edge = LLViewerParcelMgr::getInstance()->mParcelsPerEdge; 1365 S32 expected_size = 1024; //parcels_per_edge * parcels_per_edge / PARCEL_OVERLAY_CHUNKS;
1355 S32 expected_size = parcels_per_edge * parcels_per_edge / PARCEL_OVERLAY_CHUNKS;
1356 if (packed_overlay_size != expected_size) 1366 if (packed_overlay_size != expected_size)
1357 { 1367 {
1358 llwarns << "Got parcel overlay size " << packed_overlay_size 1368 llwarns << "Got parcel overlay size " << packed_overlay_size
diff --git a/linden/indra/newview/llviewerparcelmgr.h b/linden/indra/newview/llviewerparcelmgr.h
index 9bf6096..dcdea3c 100644
--- a/linden/indra/newview/llviewerparcelmgr.h
+++ b/linden/indra/newview/llviewerparcelmgr.h
@@ -82,6 +82,8 @@ public:
82 LLViewerParcelMgr(); 82 LLViewerParcelMgr();
83 ~LLViewerParcelMgr(); 83 ~LLViewerParcelMgr();
84 84
85 void init(F32 region_size);
86
85 static void cleanupGlobals(); 87 static void cleanupGlobals();
86 88
87 BOOL selectionEmpty() const; 89 BOOL selectionEmpty() const;
diff --git a/linden/indra/newview/llviewerparceloverlay.cpp b/linden/indra/newview/llviewerparceloverlay.cpp
index 0bcd8f3..a31f153 100644
--- a/linden/indra/newview/llviewerparceloverlay.cpp
+++ b/linden/indra/newview/llviewerparceloverlay.cpp
@@ -58,6 +58,7 @@ const U8 OVERLAY_IMG_COMPONENTS = 4;
58LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters) 58LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters)
59: mRegion( region ), 59: mRegion( region ),
60 mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ), 60 mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ),
61 mRegionSize(S32(region_width_meters)),
61 mDirty( FALSE ), 62 mDirty( FALSE ),
62 mTimeSinceLastUpdate(), 63 mTimeSinceLastUpdate(),
63 mOverlayTextureIdx(-1), 64 mOverlayTextureIdx(-1),
@@ -299,7 +300,8 @@ void LLViewerParcelOverlay::uncompressLandOverlay(S32 chunk, U8 *packed_overlay)
299{ 300{
300 // Unpack the message data into the ownership array 301 // Unpack the message data into the ownership array
301 S32 size = mParcelGridsPerEdge * mParcelGridsPerEdge; 302 S32 size = mParcelGridsPerEdge * mParcelGridsPerEdge;
302 S32 chunk_size = size / PARCEL_OVERLAY_CHUNKS; 303 S32 mParcelOverLayChunks = mRegionSize * mRegionSize / (128 * 128);
304 S32 chunk_size = size / mParcelOverLayChunks;
303 305
304 memcpy(mOwnership + chunk*chunk_size, packed_overlay, chunk_size); /*Flawfinder: ignore*/ 306 memcpy(mOwnership + chunk*chunk_size, packed_overlay, chunk_size); /*Flawfinder: ignore*/
305 307
diff --git a/linden/indra/newview/llviewerparceloverlay.h b/linden/indra/newview/llviewerparceloverlay.h
index 9bed1dd..d3b5980 100644
--- a/linden/indra/newview/llviewerparceloverlay.h
+++ b/linden/indra/newview/llviewerparceloverlay.h
@@ -98,6 +98,7 @@ private:
98 LLViewerRegion* mRegion; 98 LLViewerRegion* mRegion;
99 99
100 S32 mParcelGridsPerEdge; 100 S32 mParcelGridsPerEdge;
101 S32 mRegionSize;
101 102
102 LLPointer<LLImageGL> mTexture; 103 LLPointer<LLImageGL> mTexture;
103 LLPointer<LLImageRaw> mImageRaw; 104 LLPointer<LLImageRaw> mImageRaw;
diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp
index a8047b8..4186362 100644
--- a/linden/indra/newview/llviewerregion.cpp
+++ b/linden/indra/newview/llviewerregion.cpp
@@ -65,6 +65,7 @@
65#include "llvoclouds.h" 65#include "llvoclouds.h"
66#include "llworld.h" 66#include "llworld.h"
67#include "llspatialpartition.h" 67#include "llspatialpartition.h"
68#include "llviewerparcelmgr.h"
68 69
69// Viewer object cache version, change if object update 70// Viewer object cache version, change if object update
70// format changes. JC 71// format changes. JC
@@ -199,6 +200,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
199 if (!gNoRender) 200 if (!gNoRender)
200 { 201 {
201 mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters); 202 mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
203 //Re-init the parcel mgr for this sim
204 LLViewerParcelMgr::getInstance()->init(region_width_meters);
202 } 205 }
203 else 206 else
204 { 207 {
diff --git a/linden/indra/newview/llvlmanager.cpp b/linden/indra/newview/llvlmanager.cpp
index 177093c..68b4d7b 100644
--- a/linden/indra/newview/llvlmanager.cpp
+++ b/linden/indra/newview/llvlmanager.cpp
@@ -57,21 +57,23 @@ LLVLManager::~LLVLManager()
57 57
58void LLVLManager::addLayerData(LLVLData *vl_datap, const S32 mesg_size) 58void LLVLManager::addLayerData(LLVLData *vl_datap, const S32 mesg_size)
59{ 59{
60 if (LAND_LAYER_CODE == vl_datap->mType) 60 if (LAND_LAYER_CODE == vl_datap->mType ||
61 { 61 AURORA_LAND_LAYER_CODE == vl_datap->mType)
62 mLandBits += mesg_size * 8; 62 {
63 } 63 mLandBits += mesg_size * 8;
64 else if (WIND_LAYER_CODE == vl_datap->mType) 64 }
65 { 65 else if (WIND_LAYER_CODE == vl_datap->mType ||
66 mWindBits += mesg_size * 8; 66 AURORA_WIND_LAYER_CODE == vl_datap->mType)
67 } 67 {
68 else if (CLOUD_LAYER_CODE == vl_datap->mType) 68 mWindBits += mesg_size * 8;
69 { 69 }
70 mCloudBits += mesg_size * 8; 70 else if (CLOUD_LAYER_CODE == vl_datap->mType)
71 } 71 {
72 else 72 mCloudBits += mesg_size * 8;
73 { 73 }
74 llerrs << "Unknown layer type!" << (S32)vl_datap->mType << llendl; 74 else
75 {
76 llerrs << "Unknown layer type!" << (S32)vl_datap->mType << llendl;
75 } 77 }
76 78
77 mPacketData.put(vl_datap); 79 mPacketData.put(vl_datap);
@@ -90,18 +92,23 @@ void LLVLManager::unpackData(const S32 num_packets)
90 LLGroupHeader goph; 92 LLGroupHeader goph;
91 93
92 decode_patch_group_header(bit_pack, &goph); 94 decode_patch_group_header(bit_pack, &goph);
93 if (LAND_LAYER_CODE == datap->mType) 95 if (LAND_LAYER_CODE == datap->mType)
94 { 96 {
95 datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, FALSE); 97 datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, FALSE);
96 } 98 }
97 else if (WIND_LAYER_CODE == datap->mType) 99 else if (AURORA_LAND_LAYER_CODE == datap->mType)
98 { 100 {
99 datap->mRegionp->mWind.decompress(bit_pack, &goph); 101 datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, TRUE);
100 102 }
101 } 103 else if (WIND_LAYER_CODE == datap->mType ||
102 else if (CLOUD_LAYER_CODE == datap->mType) 104 AURORA_WIND_LAYER_CODE == datap->mType)
103 { 105 {
104 datap->mRegionp->mCloudLayer.decompress(bit_pack, &goph); 106 datap->mRegionp->mWind.decompress(bit_pack, &goph);
107 }
108 else if (CLOUD_LAYER_CODE == datap->mType ||
109 AURORA_CLOUD_LAYER_CODE == datap->mType)
110 {
111 datap->mRegionp->mCloudLayer.decompress(bit_pack, &goph);
105 } 112 }
106 } 113 }
107 114
diff --git a/linden/indra/newview/llvowater.cpp b/linden/indra/newview/llvowater.cpp
index c66295a..8af9e4a 100644
--- a/linden/indra/newview/llvowater.cpp
+++ b/linden/indra/newview/llvowater.cpp
@@ -74,7 +74,7 @@ LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regi
74{ 74{
75 // Terrain must draw during selection passes so it can block objects behind it. 75 // Terrain must draw during selection passes so it can block objects behind it.
76 mbCanSelect = FALSE; 76 mbCanSelect = FALSE;
77 setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility. 77 setScale(LLVector3(mRegionp->getWidth(), mRegionp->getWidth(), 0.f)); // Hack for setting scale for bounding boxes/visibility.
78 78
79 mUseTexture = TRUE; 79 mUseTexture = TRUE;
80 mIsEdgePatch = FALSE; 80 mIsEdgePatch = FALSE;
diff --git a/linden/indra/newview/llwind.cpp b/linden/indra/newview/llwind.cpp
index ae98bea..3dcbdf6 100644
--- a/linden/indra/newview/llwind.cpp
+++ b/linden/indra/newview/llwind.cpp
@@ -120,12 +120,12 @@ void LLWind::decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp)
120 set_group_of_patch_header(group_headerp); 120 set_group_of_patch_header(group_headerp);
121 121
122 // X component 122 // X component
123 decode_patch_header(bitpack, &patch_header); 123 decode_patch_header(bitpack, &patch_header, FALSE);
124 decode_patch(bitpack, buffer); 124 decode_patch(bitpack, buffer);
125 decompress_patch(mVelX, buffer, &patch_header); 125 decompress_patch(mVelX, buffer, &patch_header);
126 126
127 // Y component 127 // Y component
128 decode_patch_header(bitpack, &patch_header); 128 decode_patch_header(bitpack, &patch_header, FALSE);
129 decode_patch(bitpack, buffer); 129 decode_patch(bitpack, buffer);
130 decompress_patch(mVelY, buffer, &patch_header); 130 decompress_patch(mVelY, buffer, &patch_header);
131 131
diff --git a/linden/indra/newview/llworld.cpp b/linden/indra/newview/llworld.cpp
index 7866bf8..525195d 100644
--- a/linden/indra/newview/llworld.cpp
+++ b/linden/indra/newview/llworld.cpp
@@ -80,12 +80,12 @@ const S32 WORLD_PATCH_SIZE = 16;
80 80
81extern LLColor4U MAX_WATER_COLOR; 81extern LLColor4U MAX_WATER_COLOR;
82 82
83const U32 LLWorld::mWidth = 256; 83U32 LLWorld::mWidth = 256;
84 84
85// meters/point, therefore mWidth * mScale = meters per edge 85// meters/point, therefore mWidth * mScale = meters per edge
86const F32 LLWorld::mScale = 1.f; 86const F32 LLWorld::mScale = 1.f;
87 87
88const F32 LLWorld::mWidthInMeters = mWidth * mScale; 88F32 LLWorld::mWidthInMeters = mWidth * mScale;
89 89
90// 90//
91// Functions 91// Functions
@@ -140,7 +140,7 @@ F32 LLWorld::getRegionMaxHeight() const
140 return gHippoLimits->getMaxHeight(); 140 return gHippoLimits->getMaxHeight();
141} 141}
142 142
143LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host) 143LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host, const U32 &region_size_x, const U32 &region_size_y)
144{ 144{
145 LLMemType mt(LLMemType::MTYPE_REGIONS); 145 LLMemType mt(LLMemType::MTYPE_REGIONS);
146 146
@@ -172,9 +172,11 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
172 172
173 U32 iindex = 0; 173 U32 iindex = 0;
174 U32 jindex = 0; 174 U32 jindex = 0;
175 mWidth = region_size_x;
176 mWidthInMeters = mWidth * mScale;
175 from_region_handle(region_handle, &iindex, &jindex); 177 from_region_handle(region_handle, &iindex, &jindex);
176 S32 x = (S32)(iindex/mWidth); 178 S32 x = (S32)(iindex/256);
177 S32 y = (S32)(jindex/mWidth); 179 S32 y = (S32)(jindex/256);
178 llinfos << "Adding new region (" << x << ":" << y << ")" << llendl; 180 llinfos << "Adding new region (" << x << ":" << y << ")" << llendl;
179 llinfos << "Host: " << host << llendl; 181 llinfos << "Host: " << host << llendl;
180 182
@@ -902,7 +904,7 @@ void LLWorld::updateWaterObjects()
902 } 904 }
903 905
904 // Region width in meters. 906 // Region width in meters.
905 S32 const rwidth = (S32)REGION_WIDTH_U32; 907 S32 const rwidth = (S32)getRegionWidthInMeters();
906 908
907 // The distance we might see into the void 909 // The distance we might see into the void
908 // when standing on the edge of a region, in meters. 910 // when standing on the edge of a region, in meters.
@@ -1256,9 +1258,20 @@ void process_enable_simulator(LLMessageSystem *msg, void **user_data)
1256 // which simulator should we modify? 1258 // which simulator should we modify?
1257 LLHost sim(ip_u32, port); 1259 LLHost sim(ip_u32, port);
1258 1260
1261 U32 region_size_x = 256;
1262 msg->getU32Fast(_PREHASH_SimulatorInfo, _PREHASH_RegionSizeX, region_size_x);
1263 U32 region_size_y = 256;
1264 msg->getU32Fast(_PREHASH_SimulatorInfo, _PREHASH_RegionSizeY, region_size_y);
1265
1266 if (region_size_y == 0 || region_size_x == 0)
1267 {
1268 region_size_x = 256;
1269 region_size_y = 256;
1270 }
1271
1259 // Viewer trusts the simulator. 1272 // Viewer trusts the simulator.
1260 msg->enableCircuit(sim, TRUE); 1273 msg->enableCircuit(sim, TRUE);
1261 LLWorld::getInstance()->addRegion(handle, sim); 1274 LLWorld::getInstance()->addRegion(handle, sim, region_size_x, region_size_y);
1262 1275
1263 // give the simulator a message it can use to get ip and port 1276 // give the simulator a message it can use to get ip and port
1264 llinfos << "simulator_enable() Enabling " << sim << " with code " << msg->getOurCircuitCode() << llendl; 1277 llinfos << "simulator_enable() Enabling " << sim << " with code " << msg->getOurCircuitCode() << llendl;
diff --git a/linden/indra/newview/llworld.h b/linden/indra/newview/llworld.h
index 964729d..5dbef6d 100644
--- a/linden/indra/newview/llworld.h
+++ b/linden/indra/newview/llworld.h
@@ -71,7 +71,7 @@ public:
71 LLWorld(); 71 LLWorld();
72 void destroyClass(); 72 void destroyClass();
73 73
74 LLViewerRegion* addRegion(const U64 &region_handle, const LLHost &host); 74 LLViewerRegion* addRegion(const U64 &region_handle, const LLHost &host, const U32 &region_size_x, const U32 &region_size_y);
75 // safe to call if already present, does the "right thing" if 75 // safe to call if already present, does the "right thing" if
76 // hosts are same, or if hosts are different, etc... 76 // hosts are same, or if hosts are different, etc...
77 void removeRegion(const LLHost &host); 77 void removeRegion(const LLHost &host);
@@ -171,12 +171,12 @@ private:
171 region_list_t mCulledRegionList; 171 region_list_t mCulledRegionList;
172 172
173 // Number of points on edge 173 // Number of points on edge
174 static const U32 mWidth; 174 static U32 mWidth;
175 175
176 // meters/point, therefore mWidth * mScale = meters per edge 176 // meters/point, therefore mWidth * mScale = meters per edge
177 static const F32 mScale; 177 static const F32 mScale;
178 178
179 static const F32 mWidthInMeters; 179 static F32 mWidthInMeters;
180 180
181 F32 mLandFarClip; // Far clip distance for land. 181 F32 mLandFarClip; // Far clip distance for land.
182 LLPatchVertexArray mLandPatch; 182 LLPatchVertexArray mLandPatch;
diff --git a/linden/indra/newview/llworldmap.cpp b/linden/indra/newview/llworldmap.cpp
index 3ada36f..ead72fa 100644
--- a/linden/indra/newview/llworldmap.cpp
+++ b/linden/indra/newview/llworldmap.cpp
@@ -237,16 +237,27 @@ LLSimInfo* LLWorldMap::simInfoFromPosGlobal(const LLVector3d& pos_global)
237 return simInfoFromHandle(handle); 237 return simInfoFromHandle(handle);
238} 238}
239 239
240LLSimInfo* LLWorldMap::simInfoFromHandle(const U64 handle) 240LLSimInfo* LLWorldMap::simInfoFromHandle(const U64 findhandle)
241{ 241{
242 sim_info_map_t::iterator it = mSimInfoMap.find(handle); 242 std::map<U64, LLSimInfo*>::const_iterator it;
243 if (it != mSimInfoMap.end()) 243 for (it = LLWorldMap::getInstance()->mSimInfoMap.begin(); it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it)
244 { 244 {
245 LLSimInfo* sim_info = (*it).second; 245 const U64 handle = (*it).first;
246 if (sim_info) 246 LLSimInfo* info = (*it).second;
247 { 247 if(handle == findhandle)
248 return sim_info; 248 {
249 } 249 return info;
250 }
251 U32 x = 0, y = 0;
252 from_region_handle(findhandle, &x, &y);
253 U32 checkRegionX, checkRegionY;
254 from_region_handle(handle, &checkRegionX, &checkRegionY);
255
256 if(x > checkRegionX && x < (checkRegionX + info->msizeX) &&
257 y > checkRegionY && y < (checkRegionY + info->msizeY))
258 {
259 return info;
260 }
250 } 261 }
251 return NULL; 262 return NULL;
252} 263}
diff --git a/linden/indra/newview/llworldmap.h b/linden/indra/newview/llworldmap.h
index b7089f3..6725f91 100644
--- a/linden/indra/newview/llworldmap.h
+++ b/linden/indra/newview/llworldmap.h
@@ -81,6 +81,8 @@ public:
81 81
82public: 82public:
83 U64 mHandle; 83 U64 mHandle;
84 S32 msizeX;
85 S32 msizeY;
84 std::string mName; 86 std::string mName;
85 87
86 F64 mAgentsUpdateTime; 88 F64 mAgentsUpdateTime;
diff --git a/linden/indra/newview/llworldmapview.cpp b/linden/indra/newview/llworldmapview.cpp
index 443ee74..51de598 100644
--- a/linden/indra/newview/llworldmapview.cpp
+++ b/linden/indra/newview/llworldmapview.cpp
@@ -471,8 +471,8 @@ void LLWorldMapView::draw()
471 // When the view isn't panned, 0,0 = center of rectangle 471 // When the view isn't panned, 0,0 = center of rectangle
472 F32 bottom = sPanY + half_height + relative_y; 472 F32 bottom = sPanY + half_height + relative_y;
473 F32 left = sPanX + half_width + relative_x; 473 F32 left = sPanX + half_width + relative_x;
474 F32 top = bottom + sMapScale ; 474 F32 top = bottom+ (sMapScale * info->msizeY / REGION_WIDTH_METERS);
475 F32 right = left + sMapScale ; 475 F32 right = left + (sMapScale * info->msizeY / REGION_WIDTH_METERS);
476 476
477 // Switch to world map texture (if available for this region) if either: 477 // Switch to world map texture (if available for this region) if either:
478 // 1. Tiles are zoomed out small enough, or 478 // 1. Tiles are zoomed out small enough, or
@@ -567,17 +567,21 @@ void LLWorldMapView::draw()
567 center_global.mdV[VX] += 128.0; 567 center_global.mdV[VX] += 128.0;
568 center_global.mdV[VY] += 128.0; 568 center_global.mdV[VY] += 128.0;
569 569
570 S32 draw_size = llround(sMapScale); 570 S32 x_draw_size = llround(sMapScale);
571 S32 y_draw_size = llround(sMapScale);
572 x_draw_size *= info->msizeX / REGION_WIDTH_METERS;
573 y_draw_size *= info->msizeY / REGION_WIDTH_METERS;
574
571 if (simimage != NULL) 575 if (simimage != NULL)
572 { 576 {
573 simimage->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAP); 577 simimage->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAP);
574 simimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY])); 578 simimage->setKnownDrawSize(llround(x_draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(y_draw_size * LLUI::sGLScaleFactor.mV[VY]));
575 } 579 }
576 580
577 if (overlayimage != NULL) 581 if (overlayimage != NULL)
578 { 582 {
579 overlayimage->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAP); 583 overlayimage->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAP);
580 overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY])); 584 overlayimage->setKnownDrawSize(llround(x_draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(y_draw_size * LLUI::sGLScaleFactor.mV[VY]));
581 } 585 }
582 586
583// LLTextureView::addDebugImage(simimage); 587// LLTextureView::addDebugImage(simimage);