1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
/**
* @file llvotreenew.h
* @brief LLVOTreeNew class header file
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLVOTREENEW_H
#define LL_LLVOTREENEW_H
#include "llviewerobject.h"
#include "lldarray.h"
#include "xform.h"
#include "lltreeparams.h"
#include "llstrider.h"
#include "v2math.h"
#include "v3math.h"
#include "llviewerimage.h"
class LLFace;
class LLDrawPool;
// number of static arrays created
const U8 MAX_SPECIES = 16; // max species of trees
const U8 MAX_PARTS = 15; // trunk, 2 or 3 branches per species?
const U8 MAX_RES = 6; // max # cross sections for a branch curve
const U8 MAX_FLARE = 6; // max # cross sections for flare of trunk
const U8 MAX_LEVELS = 3;
// initial vertex array allocations
const U32 NUM_INIT_VERTS = 5000; // number of vertices/normals/texcoords
const U32 NUM_INIT_INDICES = 15000; // number of indices to vert array (3 vertices per triangle, roughly 3x)
const U32 NUM_TIMES_TO_DOUBLE = 2; // if we go over initial allocations, num times to double each step
// for finding the closest parts...
// the parts are searched based on:
const F32 MAX_LOBES_DIFF = 2;
const F32 MAX_LOBEDEPTH_DIFF = .3f;
const F32 MAX_CURVEBACK_DIFF = 20.0f;
const F32 MAX_CURVE_DIFF = 15.0f;
const F32 MAX_CURVE_V_DIFF = 20.0f;
const F32 CURVEV_DIVIDER = 10.0f; // curveV/CURVEV_DIVIDER = # branch variances...
const U8 MAX_VARS = 3; // max number of variations of branches
const U8 MAX_RAND_NUMS = 100; // max number of rand numbers to pregenerate and store
// texture params
const F32 WIDTH_OF_BARK = .48f;
class LLVOTreeNew : public LLViewerObject
{
public:
// Some random number generators using the pre-generated random numbers
// return +- negPos
static S32 llrand_signed(S32 negPos)
{
return (ll_rand((U32)negPos * 2) - negPos);
};
static S32 llrand_signed(S32 negPos, U32 index)
{
return lltrunc((sRandNums[index % MAX_RAND_NUMS] * (negPos * 2.0f) - negPos));
};
static S32 llrand_unsigned(S32 pos, U32 index)
{
return lltrunc((sRandNums[index % MAX_RAND_NUMS] * pos));
};
// return +- negPos
static F32 llfrand_signed(F32 negPos)
{
return (ll_frand(negPos * 2.0f) - negPos);
};
static F32 llfrand_signed(F32 negPos, U32 index)
{
return (sRandNums[index % MAX_RAND_NUMS] * negPos * 2.0f) - negPos;
};
static F32 llfrand_unsigned(F32 pos, U32 index)
{
return sRandNums[index % MAX_RAND_NUMS] * pos;
};
// return between 0-pos
static F32 llfrand_unsigned(F32 pos)
{
return ll_frand(pos);
};
static void cleanupTextures() {}; // not needed anymore
struct TreePart
{
F32 mRadius; // scale x/y
F32 mLength; // scale z
F32 mCurve;
F32 mCurveV;
F32 mCurveRes;
F32 mCurveBack;
U8 mLobes;
F32 mLobeDepth;
U8 mLevel;
U32 mNumTris;
U8 mVertsPerSection;
U8 mNumVariants;
// first index into the drawpool arrays for this particular branch
U32 mIndiceIndex[MAX_VARS];
U32 mOffsets[MAX_VARS][MAX_RES]; // offsets for the partial branch pieces
// local section frames for this branch
LLMatrix4 mFrames[MAX_VARS][(MAX_RES*(MAX_RES + 1))/2]; // (0...n) + (1...n) + ... + (n-1..n)
LLDynamicArray<LLVector3> mFaceNormals;
};
LLVOTreeNew(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
virtual ~LLVOTreeNew();
/*virtual*/
U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num, const EObjectUpdateType update_type,
LLDataPacker *dp);
/*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
/*virtual*/ void render(LLAgent &agent);
/*virtual*/ void updateTextures();
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
F32 CalcZStep(TreePart *part, U8 section);
void createPart(U8 level, F32 length, F32 radius, LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &normals,
LLStrider<LLVector2> &tex_coords, U32 *indices,
U32 &curVertexIndex, U32 &curTexCoordIndex,
U32 &curNormalIndex, U32 &curIndiceIndex);
S32 findSimilarPart(U8 level);
F32 CalculateSectionRadius(U8 level, F32 y, F32 stemLength, F32 stemRadius);
//F32 CalculateVerticalAttraction(U8 level, LLMatrix4 §ionFrame);
void createSection(LLMatrix4 &frame, TreePart *part, F32 sectionRadius, F32 stemZ,
LLStrider<LLVector3> &vertices, LLStrider<LLVector2> &tex_coords, U32 *indices,
U32 &curVertexIndex, U32 &curTexCoordIndex, U32 &curIndiceIndex, U8 curSection, BOOL firstBranch);
void genIndicesAndFaceNormalsForLastSection(TreePart *part, U8 numVerts, LLStrider<LLVector3> &vertices, U32 curVertexIndex, U32 *indices, U32 &curIndiceIndex, BOOL firstBranch);
void genVertexNormals(TreePart *part, LLStrider<LLVector3> &normals, U8 numSections, U32 curNormalOffset);
void drawTree(LLDrawPool &draw_pool, const LLMatrix4 &frame, U8 level, F32 offsetChild, F32 curLength, F32 parentLength, F32 curRadius, F32 parentRadius, U8 part, U8 variant, U8 startSection);
void drawTree(LLDrawPool &draw_pool);
//LLTreeParams mParams;
U8 mSpecies;
LLPointer<LLViewerImage> mTreeImagep;
LLMatrix4 mTrunkFlareFrames[MAX_FLARE];
F32 mSegSplitsError[3];
U32 mRandOffset[MAX_LEVELS];
U32 mNumTrisDrawn;
U32 mTotalIndices;
U32 mTotalVerts;
static void initClass();
// tree params
static LLTreeParams sParameters;
// next indexes used to drawpool arrays
static U32 sNextVertexIndex[MAX_SPECIES];
static U32 sNextIndiceIndex[MAX_SPECIES];
// tree parts
static U32 sNextPartIndex[MAX_PARTS];
static TreePart sTreeParts[MAX_SPECIES][MAX_PARTS];
// species images
static LLUUID sTreeImageIDs[MAX_SPECIES];
// random numbers
static F32 sRandNums[MAX_RAND_NUMS];
// usage data
static U32 sTreePartsUsed[MAX_SPECIES][MAX_PARTS][MAX_VARS];
};
#endif
|