Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Samples/VolumeTex/src/ThingRenderable.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 5.5 KB
RevLine 
[1]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
10You may use this sample code for anything you like, it is not covered by the
11LGPL like the rest of the engine.
12-----------------------------------------------------------------------------
13*/
14#include "ThingRenderable.h"
15#include <OgreHardwareVertexBuffer.h>
16#include <OgreHardwareIndexBuffer.h>
17#include <OgreHardwareBufferManager.h>
18#include <OgreCamera.h>
19using namespace Ogre;
20
21ThingRenderable::ThingRenderable(float radius, size_t count, float qsize):
22        mRadius(radius),
23        mCount(count),
24        mQSize(qsize)
25{
26        mBox = Ogre::AxisAlignedBox(-radius, -radius, -radius, radius, radius, radius);
27        initialise();
28        fillBuffer();
29}
30ThingRenderable::~ThingRenderable()
31{
32    // need to release IndexData and vertexData created for renderable
33    delete mRenderOp.indexData;
34    delete mRenderOp.vertexData;
35}
36
37void ThingRenderable::addTime(float t)
38{
39        for(size_t x=0; x<mCount; x++)
40        {
41                Quaternion dest = things[x] * orbits[x];
42                things[x] = things[x] + t * (dest - things[x]);
43                things[x].normalise();
44        }
45        fillBuffer();
46}
47// Generate float between -1 and 1
48float randFloat()
49{
50        return ((float)rand()/RAND_MAX)*2.0f-1.0f;
51}
52void ThingRenderable::initialise()
53{
54        // Fill array with randomly oriented quads
55        Vector3 ax, ay, az;
56        size_t x;
57        Quaternion q;
58        things.clear(); orbits.clear();
59        for(x=0; x<mCount; x++)
60        {
61                ax = Vector3(randFloat(), randFloat(), randFloat());
62                ay = Vector3(randFloat(), randFloat(), randFloat());
63                az = ax.crossProduct(ay);
64                ay = az.crossProduct(ax);
65                ax.normalise(); ay.normalise(); az.normalise();
66                q.FromAxes(ax, ay, az);
67                //std::cerr << ax.dotProduct(ay) << " " << ay.dotProduct(az) << " " << az.dotProduct(ax) << std::endl;
68                things.push_back(q);
69               
70                ax = Vector3(randFloat(), randFloat(), randFloat());
71                ay = Vector3(randFloat(), randFloat(), randFloat());
72                az = ax.crossProduct(ay);
73                ay = az.crossProduct(ax);
74                ax.normalise(); ay.normalise(); az.normalise();
75                q.FromAxes(ax, ay, az);
76                orbits.push_back(q);
77        }
78       
79        // Create buffers
80        size_t nvertices = mCount*4; // n+1 planes
81        //size_t elemsize = 2*3; // position, normal
82        //size_t dsize = elemsize*nvertices;
83       
84        Ogre::IndexData *idata = new Ogre::IndexData();
85        Ogre::VertexData *vdata = new Ogre::VertexData();
86
87        // Quads
88        unsigned short *faces = new unsigned short[mCount*6];
89        for(x=0; x<mCount; x++) 
90        {
91                faces[x*6+0] = x*4+0;
92                faces[x*6+1] = x*4+1;
93                faces[x*6+2] = x*4+2;
94                faces[x*6+3] = x*4+0;
95                faces[x*6+4] = x*4+2;
96                faces[x*6+5] = x*4+3;
97        }
98        // Setup buffers
99        vdata->vertexStart = 0;
100        vdata->vertexCount = nvertices;
101       
102        VertexDeclaration* decl = vdata->vertexDeclaration;
103        VertexBufferBinding* bind = vdata->vertexBufferBinding;
104
105        size_t offset = 0;
106        decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
107        offset += VertexElement::getTypeSize(VET_FLOAT3);
108
109        vbuf = 
110        HardwareBufferManager::getSingleton().createVertexBuffer(
111                offset, nvertices, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
112
113        bind->setBinding(0, vbuf);
114
115        //vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
116       
117        HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
118                createIndexBuffer(
119                        HardwareIndexBuffer::IT_16BIT, 
120                        mCount*6, 
121                        HardwareBuffer::HBU_STATIC_WRITE_ONLY);
122
123        idata->indexBuffer = ibuf;
124        idata->indexCount = mCount*6;
125        idata->indexStart = 0;
126        ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
127
128        // Delete temporary buffers
129        delete [] faces;
130       
131        // Now make the render operation
132        mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
133        mRenderOp.indexData = idata;
134        mRenderOp.vertexData = vdata;
135        mRenderOp.useIndexes = true;
136}
137
138void ThingRenderable::fillBuffer()
139{
140        // Transfer vertices and normals
141        float *vIdx = static_cast<float*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
142        size_t elemsize = 1*3; // position only
143        size_t planesize = 4*elemsize; // four vertices per plane
144        for(size_t x=0; x<mCount; x++) 
145        {
146                Vector3 ax, ay, az;
147                things[x].ToAxes(ax, ay, az);
148                Vector3 pos = az * mRadius; // scale to radius
149                ax *= mQSize;
150                ay *= mQSize;
151                Vector3 pos1 = pos - ax - ay;
152                Vector3 pos2 = pos + ax - ay;
153                Vector3 pos3 = pos + ax + ay;
154                Vector3 pos4 = pos - ax + ay;
155                vIdx[x*planesize + 0*elemsize + 0] = pos1.x;
156                vIdx[x*planesize + 0*elemsize + 1] = pos1.y;
157                vIdx[x*planesize + 0*elemsize + 2] = pos1.z;
158                vIdx[x*planesize + 1*elemsize + 0] = pos2.x;
159                vIdx[x*planesize + 1*elemsize + 1] = pos2.y;
160                vIdx[x*planesize + 1*elemsize + 2] = pos2.z;
161                vIdx[x*planesize + 2*elemsize + 0] = pos3.x;
162                vIdx[x*planesize + 2*elemsize + 1] = pos3.y;
163                vIdx[x*planesize + 2*elemsize + 2] = pos3.z;
164                vIdx[x*planesize + 3*elemsize + 0] = pos4.x;
165                vIdx[x*planesize + 3*elemsize + 1] = pos4.y;
166                vIdx[x*planesize + 3*elemsize + 2] = pos4.z;
167        }
168        vbuf->unlock();
169}
170Ogre::Real ThingRenderable::getBoundingRadius() const
171{
172        return mRadius;
173}
174Ogre::Real ThingRenderable::getSquaredViewDepth(const Ogre::Camera* cam) const
175{
176        Ogre::Vector3 min, max, mid, dist;
177
178        min = mBox.getMinimum();
179        max = mBox.getMaximum();
180        mid = ((min - max) * 0.5) + min;
181        dist = cam->getDerivedPosition() - mid;
182                                                                       
183        return dist.squaredLength();
184}
185
Note: See TracBrowser for help on using the repository browser.