Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgrePrefabFactory.cpp @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 11.6 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29
30#include "OgreStableHeaders.h"
31#include "OgrePrefabFactory.h"
32#include "OgreHardwareBufferManager.h"
33#include "OgreMesh.h"
34#include "OgreSubMesh.h"
35
36namespace Ogre {
37        //---------------------------------------------------------------------
38        bool PrefabFactory::createPrefab(Mesh* mesh)
39        {
40                const String& resourceName = mesh->getName();
41
42                if(resourceName == "Prefab_Plane")
43                {
44                        createPlane(mesh);
45                        return true;
46                }
47                else if(resourceName == "Prefab_Cube")
48                {
49                        createCube(mesh);
50                        return true;
51                }
52                else if(resourceName == "Prefab_Sphere")
53                {
54                        createSphere(mesh);
55                        return true;
56                }
57       
58                return false;
59        }
60        //---------------------------------------------------------------------
61        void PrefabFactory::createPlane(Mesh* mesh)
62        {
63                SubMesh* sub = mesh->createSubMesh();
64                float vertices[32] = {
65                        -100, -100, 0,  // pos
66                        0,0,1,                  // normal
67                        0,1,                    // texcoord
68                        100, -100, 0,
69                        0,0,1,
70                        1,1,
71                        100,  100, 0,
72                        0,0,1,
73                        1,0,
74                        -100,  100, 0 ,
75                        0,0,1,
76                        0,0 
77                };
78                mesh->sharedVertexData = new VertexData();
79                mesh->sharedVertexData->vertexCount = 4;
80                VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
81                VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;
82
83                size_t offset = 0;
84                decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
85                offset += VertexElement::getTypeSize(VET_FLOAT3);
86                decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
87                offset += VertexElement::getTypeSize(VET_FLOAT3);
88                decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
89                offset += VertexElement::getTypeSize(VET_FLOAT2);
90
91                HardwareVertexBufferSharedPtr vbuf = 
92                        HardwareBufferManager::getSingleton().createVertexBuffer(
93                        offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
94                bind->setBinding(0, vbuf);
95
96                vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
97
98                sub->useSharedVertices = true;
99                HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
100                        createIndexBuffer(
101                        HardwareIndexBuffer::IT_16BIT, 
102                        6, 
103                        HardwareBuffer::HBU_STATIC_WRITE_ONLY);
104
105                unsigned short faces[6] = {0,1,2,
106                        0,2,3 };
107                sub->indexData->indexBuffer = ibuf;
108                sub->indexData->indexCount = 6;
109                sub->indexData->indexStart =0;
110                ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
111
112                mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true);
113                mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100));
114        }
115        //---------------------------------------------------------------------
116        void PrefabFactory::createCube(Mesh* mesh)
117        {
118                SubMesh* sub = mesh->createSubMesh();
119
120                const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides
121                const int NUM_ENTRIES_PER_VERTEX = 8;
122                const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX;
123                const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides
124
125                const Real CUBE_SIZE = 100.0;
126                const Real CUBE_HALF_SIZE = CUBE_SIZE / 2.0;
127
128                // Create 4 vertices per side instead of 6 that are shared for the whole cube.
129                // The reason for this is with only 6 vertices the normals will look bad
130                // since each vertex can "point" in a different direction depending on the face it is included in.
131                float vertices[NUM_VERTEX_ENTRIES] = {
132                        // front side
133                        -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,       // pos
134                        0,0,1,  // normal
135                        0,1,    // texcoord
136                        CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
137                        0,0,1,
138                        1,1,
139                        CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE,
140                        0,0,1,
141                        1,0,
142                        -CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE ,
143                        0,0,1,
144                        0,0,
145
146                        // back side
147                        CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
148                        0,0,-1,
149                        0,1,
150                        -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
151                        0,0,-1,
152                        1,1,
153                        -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
154                        0,0,-1,
155                        1,0,
156                        CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
157                        0,0,-1,
158                        0,0,
159
160                        // left side
161                        -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
162                        -1,0,0,
163                        0,1,
164                        -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
165                        -1,0,0,
166                        1,1,
167                        -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
168                        -1,0,0,
169                        1,0,
170                        -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
171                        -1,0,0,
172                        0,0, 
173
174                        // right side
175                        CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
176                        1,0,0,
177                        0,1,
178                        CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
179                        1,0,0,
180                        1,1,
181                        CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
182                        1,0,0,
183                        1,0,
184                        CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
185                        1,0,0,
186                        0,0,
187
188                        // up side
189                        -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
190                        0,1,0,
191                        0,1,
192                        CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
193                        0,1,0,
194                        1,1,
195                        CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
196                        0,1,0,
197                        1,0,
198                        -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
199                        0,1,0,
200                        0,0,
201
202                        // down side
203                        -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
204                        0,-1,0,
205                        0,1,
206                        CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
207                        0,-1,0,
208                        1,1,
209                        CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
210                        0,-1,0,
211                        1,0,
212                        -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
213                        0,-1,0,
214                        0,0 
215                };
216
217                mesh->sharedVertexData = new VertexData();
218                mesh->sharedVertexData->vertexCount = NUM_VERTICES;
219                VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
220                VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;
221
222                size_t offset = 0;
223                decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
224                offset += VertexElement::getTypeSize(VET_FLOAT3);
225                decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
226                offset += VertexElement::getTypeSize(VET_FLOAT3);
227                decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
228                offset += VertexElement::getTypeSize(VET_FLOAT2);
229
230                HardwareVertexBufferSharedPtr vbuf = 
231                        HardwareBufferManager::getSingleton().createVertexBuffer(
232                        offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
233                bind->setBinding(0, vbuf);
234
235                vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
236
237                sub->useSharedVertices = true;
238                HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
239                        createIndexBuffer(
240                        HardwareIndexBuffer::IT_16BIT, 
241                        NUM_INDICES,
242                        HardwareBuffer::HBU_STATIC_WRITE_ONLY);
243
244                unsigned short faces[NUM_INDICES] = {
245                        // front
246                        0,1,2,
247                        0,2,3,
248
249                        // back
250                        4,5,6,
251                        4,6,7,
252
253                        // left
254                        8,9,10,
255                        8,10,11,
256
257                        // right
258                        12,13,14,
259                        12,14,15,
260
261                        // up
262                        16,17,18,
263                        16,18,19,
264
265                        // down
266                        20,21,22,
267                        20,22,23
268                };
269
270                sub->indexData->indexBuffer = ibuf;
271                sub->indexData->indexCount = NUM_INDICES;
272                sub->indexData->indexStart = 0;
273                ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
274
275                mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
276                        CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true);
277
278                mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE);
279        }
280        //---------------------------------------------------------------------
281        void PrefabFactory::createSphere(Mesh* mesh)
282        {
283                // sphere creation code taken from the DeferredShading sample, originally from the wiki
284                SubMesh *pSphereVertex = mesh->createSubMesh();
285
286                const int NUM_SEGMENTS = 16;
287                const int NUM_RINGS = 16;
288                const Real SPHERE_RADIUS = 50.0;
289
290                mesh->sharedVertexData = new VertexData();
291                VertexData* vertexData = mesh->sharedVertexData;
292
293                // define the vertex format
294                VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
295                size_t currOffset = 0;
296                // positions
297                vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
298                currOffset += VertexElement::getTypeSize(VET_FLOAT3);
299                // normals
300                vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
301                currOffset += VertexElement::getTypeSize(VET_FLOAT3);
302                // two dimensional texture coordinates
303                vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
304                currOffset += VertexElement::getTypeSize(VET_FLOAT2);
305
306                // allocate the vertex buffer
307                vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+1);
308                HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
309                VertexBufferBinding* binding = vertexData->vertexBufferBinding;
310                binding->setBinding(0, vBuf);
311                float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));
312
313                // allocate index buffer
314                pSphereVertex->indexData->indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1);
315                pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
316                HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer;
317                unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));
318
319                float fDeltaRingAngle = (Math::PI / NUM_RINGS);
320                float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS);
321                unsigned short wVerticeIndex = 0 ;
322
323                // Generate the group of rings for the sphere
324                for( int ring = 0; ring <= NUM_RINGS; ring++ ) {
325                        float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle);
326                        float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle);
327
328                        // Generate the group of segments for the current ring
329                        for(int seg = 0; seg <= NUM_SEGMENTS; seg++) {
330                                float x0 = r0 * sinf(seg * fDeltaSegAngle);
331                                float z0 = r0 * cosf(seg * fDeltaSegAngle);
332
333                                // Add one vertex to the strip which makes up the sphere
334                                *pVertex++ = x0;
335                                *pVertex++ = y0;
336                                *pVertex++ = z0;
337
338                                Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
339                                *pVertex++ = vNormal.x;
340                                *pVertex++ = vNormal.y;
341                                *pVertex++ = vNormal.z;
342
343                                *pVertex++ = (float) seg / (float) NUM_SEGMENTS;
344                                *pVertex++ = (float) ring / (float) NUM_RINGS;
345
346                                if (ring != NUM_RINGS) {
347                                        // each vertex (except the last) has six indicies pointing to it
348                                        *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
349                                        *pIndices++ = wVerticeIndex;               
350                                        *pIndices++ = wVerticeIndex + NUM_SEGMENTS;
351                                        *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
352                                        *pIndices++ = wVerticeIndex + 1;
353                                        *pIndices++ = wVerticeIndex;
354                                        wVerticeIndex ++;
355                                }
356                        }; // end for seg
357                } // end for ring
358
359                // Unlock
360                vBuf->unlock();
361                iBuf->unlock();
362                // Generate face list
363                pSphereVertex->useSharedVertices = true;
364
365                // the original code was missing this line:
366                mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS), 
367                        Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false );
368
369                mesh->_setBoundingSphereRadius(SPHERE_RADIUS);
370        }
371        //---------------------------------------------------------------------
372}
Note: See TracBrowser for help on using the repository browser.