source: GTP/trunk/App/Demos/Illum/IBRBillboardCloudTrees/OGRE/IBRTreesOGRE/include/Grass.h @ 1546

Revision 1546, 8.8 KB checked in by igarcia, 18 years ago (diff)
Line 
1#include "Ogre.h"
2
3
4        class Grass
5        {
6        protected:
7                StaticGeometry* mStaticGeom;
8                Real mGrassHeight;
9                Real mGrassWidth;
10                String mGrassMeshName;
11                String mGrassMaterial;
12                Real mOffsetParam;
13                SceneManager *mSceneMgr;
14                Real mHeightPosition;
15                Real mGrassFrequency;
16                Real mGrassInterFrequency;
17                Vector3 mGrassScaleRandomRangeMin;
18                Vector3 mGrassScaleRandomRangeMax;
19                Real mGrassLandscapeSizeX;
20                Real mGrassLandscapeSizeZ;
21                bool mShadowCaster;
22                bool mGrassShadowReceiver;
23
24        public:
25                Grass()
26                {
27                        mOffsetParam = 999;
28                        mGrassMeshName = String("grassblades");
29                        mGrassMaterial = String("Examples/GrassBlades");
30                        mShadowCaster = false;
31                }
32
33                void setGrassCastShadows(bool shadowCaster)
34                {
35                        if (shadowCaster)
36                        {
37                                mStaticGeom->setCastShadows(true);
38                                mShadowCaster = true;
39                        }
40                        else
41                        {
42                                mStaticGeom->setCastShadows(false);
43                                mShadowCaster = false;
44                        }
45                }
46
47                void setGrassLandscapeSizeX(Real landscapeSizeX)
48                {
49                        mGrassLandscapeSizeX = landscapeSizeX;
50                }
51
52                void setGrassLandscapeSizeZ(Real landscapeSizeZ)
53                {
54                        mGrassLandscapeSizeZ = landscapeSizeZ;
55                }
56
57                Real getGrassLandscapeSizeX()
58                {
59                        return mGrassLandscapeSizeX;
60                }
61
62                Real getGrassLandscapeSizeZ()
63                {
64                        return mGrassLandscapeSizeZ;
65                }
66
67                void setGrassScaleRandomRangeMin(Vector3 scaleRRmin)
68                {
69                        mGrassScaleRandomRangeMin = scaleRRmin;
70                }
71
72                Vector3 getGrassScaleRandomRangeMin()
73                {
74                        return mGrassScaleRandomRangeMin;
75                }
76
77                void setGrassScaleRandomRangeMax(Vector3 scaleRRmax)
78                {
79                        mGrassScaleRandomRangeMax = scaleRRmax;
80                }
81
82                Vector3 getGrassScaleRandomRangeMax()
83                {
84                        return mGrassScaleRandomRangeMax;
85                }
86
87                void setGrassInterFrequency(Real interFrequency)
88                {
89                        mGrassInterFrequency = interFrequency;
90                }
91
92                Real getGrassInterFrequency()
93                {
94                        return mGrassInterFrequency;
95                }
96
97                void setGrassFrequency(Real frequency)
98                {
99                        mGrassFrequency = frequency;
100                }
101
102                Real getGrassFrequency()
103                {
104                        return mGrassFrequency;
105                }
106
107                void setGrassHeightPosition(Real heightPosition)
108                {
109                        mHeightPosition = heightPosition;
110                }
111
112                Real getGrassHeightPosition()
113                {
114                        return mHeightPosition;
115                }
116
117                void setSceneManager(SceneManager* sceneMgr)
118                {
119                        mSceneMgr = sceneMgr;
120                }
121
122                Real getGrassHeight()
123                {
124                        return mGrassHeight;
125                }
126
127                Real getGrassWidth()
128                {
129                        return mGrassWidth;
130                }
131
132                String getGrassMeshName()
133                {
134                        return mGrassMeshName;
135                }
136
137                String getGrassMaterial()
138                {
139                        return mGrassMaterial;
140                }
141
142                StaticGeometry* getStaticGeometry()
143                {
144                        return mStaticGeom;
145                }
146
147                void setGrassHeight(Real height)
148                {
149                        mGrassHeight = height;
150                }
151
152                void setGrassWidth(Real width)
153                {
154                        mGrassWidth = width;
155                }
156
157                void setGrassMeshName(String meshName)
158                {
159                        mGrassMeshName = meshName;
160                }
161
162                void setGrassMaterial(String material)
163                {
164                        mGrassMaterial = material;
165                }
166
167                void waveGrass(Real timeElapsed)
168                {
169                        static Real xinc = Math::PI * 0.4;
170                        static Real zinc = Math::PI * 0.55;
171                        static Real xpos = Math::RangeRandom(-Math::PI, Math::PI);
172                        static Real zpos = Math::RangeRandom(-Math::PI, Math::PI);
173
174                        xpos += xinc * timeElapsed;
175                        zpos += zinc * timeElapsed;
176
177                        // Update vertex program parameters by binding a value to each renderable
178                        static Vector4 offset(0,0,0,0);
179
180                        StaticGeometry::RegionIterator rit =  mStaticGeom->getRegionIterator();
181                        while (rit.hasMoreElements())
182                        {
183                                StaticGeometry::Region* reg = rit.getNext();
184
185                                // a little randomness
186                                xpos += reg->getCentre().x * 0.001;
187                                zpos += reg->getCentre().z * 0.001;
188                                offset.x = Math::Sin(xpos) * 0.05;
189                                offset.z = Math::Sin(zpos) * 0.05;
190
191                                StaticGeometry::Region::LODIterator lodit = reg->getLODIterator();
192                                while (lodit.hasMoreElements())
193                                {
194                                        StaticGeometry::LODBucket* lod = lodit.getNext();
195                                        StaticGeometry::LODBucket::MaterialIterator matit =
196                                                lod->getMaterialIterator();
197                                        while (matit.hasMoreElements())
198                                        {
199                                                StaticGeometry::MaterialBucket* mat = matit.getNext();
200                                                StaticGeometry::MaterialBucket::GeometryIterator geomit =
201                                                        mat->getGeometryIterator();
202                                                while (geomit.hasMoreElements())
203                                                {
204                                                        StaticGeometry::GeometryBucket* geom = geomit.getNext();
205                                                        geom->setCustomParameter(mOffsetParam, offset);
206
207                                                }
208                                        }
209                                }
210                        }
211                }
212
213                void createGrassMesh()
214                {
215                        // Each grass section is 3 planes at 60 degrees to each other
216                        // Normals point straight up to simulate correct lighting
217                        MeshPtr msh = MeshManager::getSingleton().createManual(mGrassMeshName,
218                                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
219                        SubMesh* sm = msh->createSubMesh();
220                        sm->useSharedVertices = false;
221                        sm->vertexData = new VertexData();
222                        sm->vertexData->vertexStart = 0;
223                        sm->vertexData->vertexCount = 12;
224                        VertexDeclaration* dcl = sm->vertexData->vertexDeclaration;
225                        size_t offset = 0;
226                        dcl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
227                        offset += VertexElement::getTypeSize(VET_FLOAT3);
228                        dcl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
229                        offset += VertexElement::getTypeSize(VET_FLOAT3);
230                        dcl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES);
231                        offset += VertexElement::getTypeSize(VET_FLOAT2);
232
233                        HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton()
234                                .createVertexBuffer(
235                                        offset, 12, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
236                        float* pReal = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
237                        Vector3 baseVec(mGrassWidth/2, 0, 0);
238                        Vector3 vec = baseVec;
239                        Quaternion rot;
240                        rot.FromAngleAxis(Degree(60), Vector3::UNIT_Y);
241                        int i;
242                        for (i = 0; i < 3; ++i)
243                        {
244                                // position
245                                *pReal++ = -vec.x;
246                                *pReal++ = mGrassHeight;
247                                *pReal++ = -vec.z;
248                                // normal
249                                *pReal++ = 0;
250                                *pReal++ = 1;
251                                *pReal++ = 0;
252                                // uv
253                                *pReal++ = 0;
254                                *pReal++ = 0;
255
256                                // position
257                                *pReal++ = vec.x;
258                                *pReal++ = mGrassHeight;
259                                *pReal++ = vec.z;
260                                // normal
261                                *pReal++ = 0;
262                                *pReal++ = 1;
263                                *pReal++ = 0;
264                                // uv
265                                *pReal++ = 1;
266                                *pReal++ = 0;
267
268                                // position
269                                *pReal++ = -vec.x;
270                                *pReal++ = 0;
271                                *pReal++ = -vec.z;
272                                // normal
273                                *pReal++ = 0;
274                                *pReal++ = 1;
275                                *pReal++ = 0;
276                                // uv
277                                *pReal++ = 0;
278                                *pReal++ = 1;
279
280                                // position
281                                *pReal++ = vec.x;
282                                *pReal++ = 0;
283                                *pReal++ = vec.z;
284                                // normal
285                                *pReal++ = 0;
286                                *pReal++ = 1;
287                                *pReal++ = 0;
288                                // uv
289                                *pReal++ = 1;
290                                *pReal++ = 1;
291
292                                vec = rot * vec;
293                        }
294                        vbuf->unlock();
295                        sm->vertexData->vertexBufferBinding->setBinding(0, vbuf);
296                        sm->indexData->indexCount = 6*3;
297                        sm->indexData->indexBuffer = HardwareBufferManager::getSingleton()
298                                .createIndexBuffer(HardwareIndexBuffer::IT_16BIT, 6*3,
299                                        HardwareBuffer::HBU_STATIC_WRITE_ONLY);
300                        uint16* pI = static_cast<uint16*>(
301                                sm->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
302                        for (i = 0; i < 3; ++i)
303                        {
304                                int off = i*4;
305                                *pI++ = 0 + off;
306                                *pI++ = 3 + off;
307                                *pI++ = 1 + off;
308
309                                *pI++ = 0 + off;
310                                *pI++ = 2 + off;
311                                *pI++ = 3 + off;
312                        }
313
314                        sm->indexData->indexBuffer->unlock();                   
315                        sm->setMaterialName(mGrassMaterial);
316                        MaterialPtr material = MaterialManager::getSingleton().getByName(mGrassMaterial);
317                        material->setReceiveShadows(mGrassShadowReceiver);
318                        msh->load();
319
320                }
321
322                // This method should be called in the createScene method...
323                void initGrass()
324                {
325                        createGrassMesh();
326
327                        Entity* e = mSceneMgr->createEntity("1", mGrassMeshName);
328
329                        StaticGeometry* s = mSceneMgr->createStaticGeometry("bing");
330                        s->setRegionDimensions(Vector3(1000,1000,1000));
331                        // Set the region origin so the centre is at 0 world
332                        s->setOrigin(Vector3(-500, 500, -500));
333
334                        for (int x = -mGrassLandscapeSizeX; x < mGrassLandscapeSizeX; x += mGrassFrequency)
335                        {
336                                for (int z = -mGrassLandscapeSizeZ; z < mGrassLandscapeSizeZ; z += mGrassFrequency)
337                                {
338                                        Vector3 pos(
339                                                x + Math::RangeRandom(-mGrassInterFrequency,mGrassInterFrequency),
340                                                mHeightPosition,
341                                                z + Math::RangeRandom(-mGrassInterFrequency,mGrassInterFrequency));
342                                        Quaternion orientation;
343                                        orientation.FromAngleAxis(
344                                                Degree(Math::RangeRandom(0, 359)),
345                                                Vector3::UNIT_Y);
346                                        Vector3 grassScale = Vector3(Math::RangeRandom(mGrassScaleRandomRangeMin[0],mGrassScaleRandomRangeMax[0]),
347                                                                                 Math::RangeRandom(mGrassScaleRandomRangeMin[1],mGrassScaleRandomRangeMax[1]),
348                                                                                 Math::RangeRandom(mGrassScaleRandomRangeMin[2],mGrassScaleRandomRangeMax[2]));
349                                        Vector3 scale(grassScale);
350                                        s->addEntity(e, pos, orientation, scale);
351                                }
352
353                        }
354
355                        s->build();
356                        mStaticGeom = s;
357
358                        setGrassCastShadows(mShadowCaster);
359                }
360
361                void setGrassShadowReceiver(bool value)
362                {
363                        mGrassShadowReceiver = value;
364                }
365        };
Note: See TracBrowser for help on using the repository browser.