Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 7.1 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
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 "VolumeRenderable.h"
15#include <OgreCamera.h>
16#include <OgreSceneNode.h>
17#include <OgreHardwareVertexBuffer.h>
18#include <OgreHardwareIndexBuffer.h>
19#include <OgreHardwareBufferManager.h>
20#include <OgreMaterial.h>
21#include <OgreTechnique.h>
22#include <OgrePass.h>
23#include <OgreTextureUnitState.h>
24#include <OgreTextureManager.h>
25#include <OgreMaterialManager.h>
26using namespace Ogre;
27
28VolumeRenderable::VolumeRenderable(size_t nSlices, float size, const String &texture):
29        mSlices(nSlices),
30        mSize(size),
31        mTexture(texture)
32{
33        mRadius = sqrtf(size*size+size*size+size*size)/2.0f;
34        mBox = Ogre::AxisAlignedBox(-size, -size, -size, size, size, size);
35       
36        // No shadows
37        setCastShadows(false);
38       
39        initialise();
40}
41VolumeRenderable::~VolumeRenderable()
42{
43        // Remove private material
44        MaterialManager::getSingleton().remove(mTexture);
45    // need to release IndexData and vertexData created for renderable
46    delete mRenderOp.indexData;
47    delete mRenderOp.vertexData;
48
49}
50
51void VolumeRenderable::_notifyCurrentCamera( Camera* cam )
52{
53        MovableObject::_notifyCurrentCamera(cam);
54
55        // Fake orientation toward camera
56        Vector3 zVec = getParentNode()->_getDerivedPosition() - cam->getDerivedPosition();
57        zVec.normalise();
58        Vector3 fixedAxis = cam->getDerivedOrientation() * Vector3::UNIT_Y ;
59       
60        Vector3 xVec = fixedAxis.crossProduct( zVec );
61        xVec.normalise();
62
63        Vector3 yVec = zVec.crossProduct( xVec );
64        yVec.normalise();
65       
66        Quaternion oriQuat;
67        oriQuat.FromAxes( xVec, yVec, zVec );
68       
69        oriQuat.ToRotationMatrix(mFakeOrientation);
70       
71        Matrix3 tempMat;
72        Quaternion q = getParentNode()->_getDerivedOrientation().UnitInverse() * oriQuat ;
73        q.ToRotationMatrix(tempMat);
74       
75        Matrix4 rotMat = Matrix4::IDENTITY;
76        rotMat = tempMat;
77        rotMat.setTrans(Vector3(0.5f, 0.5f, 0.5f));
78        mUnit->setTextureTransform(rotMat);
79}
80
81
82//const Ogre::Quaternion& VolumeRenderable::getWorldOrientation(void) const
83//{
84//      return Ogre::Quaternion::IDENTITY;
85//}
86
87void VolumeRenderable::getWorldTransforms( Matrix4* xform ) const
88{
89        Matrix4 destMatrix(Matrix4::IDENTITY); // this initialisation is needed
90       
91        const Vector3 &position = getParentNode()->_getDerivedPosition();
92        const Vector3 &scale = getParentNode()->_getDerivedScale();
93        Matrix3 scale3x3(Matrix3::ZERO);
94        scale3x3[0][0] = scale.x;
95        scale3x3[1][1] = scale.y;
96        scale3x3[2][2] = scale.z;
97
98        destMatrix = mFakeOrientation * scale3x3;
99        destMatrix.setTrans(position);
100               
101        *xform = destMatrix;
102}
103
104void VolumeRenderable::initialise()
105{
106        // Create geometry
107        size_t nvertices = mSlices*4; // n+1 planes
108        size_t elemsize = 3*3;
109        size_t dsize = elemsize*nvertices;
110        size_t x;
111       
112        Ogre::IndexData *idata = new Ogre::IndexData();
113        Ogre::VertexData *vdata = new Ogre::VertexData();
114       
115        // Create  structures
116        float *vertices = new float[dsize];
117       
118        float coords[4][2] = {
119                {0.0f, 0.0f},
120                {0.0f, 1.0f},
121                {1.0f, 0.0f},
122                {1.0f, 1.0f}
123        };
124        for(x=0; x<mSlices; x++) 
125        {
126                for(size_t y=0; y<4; y++)
127                {
128                        float xcoord = coords[y][0]-0.5;
129                        float ycoord = coords[y][1]-0.5;
130                        float zcoord = -((float)x/(float)(mSlices-1)  - 0.5f);
131                        // 1.0f .. a/(a+1)
132                        // coordinate
133                        vertices[x*4*elemsize+y*elemsize+0] = xcoord*(mSize/2.0f);
134                        vertices[x*4*elemsize+y*elemsize+1] = ycoord*(mSize/2.0f);
135                        vertices[x*4*elemsize+y*elemsize+2] = zcoord*(mSize/2.0f);
136                        // normal
137                        vertices[x*4*elemsize+y*elemsize+3] = 0.0f;
138                        vertices[x*4*elemsize+y*elemsize+4] = 0.0f;
139                        vertices[x*4*elemsize+y*elemsize+5] = 1.0f;
140                        // tex
141                        vertices[x*4*elemsize+y*elemsize+6] = xcoord*sqrtf(3.0f);
142                        vertices[x*4*elemsize+y*elemsize+7] = ycoord*sqrtf(3.0f);
143                        vertices[x*4*elemsize+y*elemsize+8] = zcoord*sqrtf(3.0f);
144                } 
145        }
146        unsigned short *faces = new unsigned short[mSlices*6];
147        for(x=0; x<mSlices; x++) 
148        {
149                faces[x*6+0] = x*4+0;
150                faces[x*6+1] = x*4+1;
151                faces[x*6+2] = x*4+2;
152                faces[x*6+3] = x*4+1;
153                faces[x*6+4] = x*4+2;
154                faces[x*6+5] = x*4+3;
155        }
156        // Setup buffers
157        vdata->vertexStart = 0;
158        vdata->vertexCount = nvertices;
159       
160        VertexDeclaration* decl = vdata->vertexDeclaration;
161        VertexBufferBinding* bind = vdata->vertexBufferBinding;
162
163        size_t offset = 0;
164        decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
165        offset += VertexElement::getTypeSize(VET_FLOAT3);
166        decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
167        offset += VertexElement::getTypeSize(VET_FLOAT3);
168        decl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES);
169        offset += VertexElement::getTypeSize(VET_FLOAT3);
170
171        HardwareVertexBufferSharedPtr vbuf = 
172        HardwareBufferManager::getSingleton().createVertexBuffer(
173                offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
174
175        bind->setBinding(0, vbuf);
176
177        vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
178       
179        HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
180                createIndexBuffer(
181                        HardwareIndexBuffer::IT_16BIT, 
182                        mSlices*6, 
183                        HardwareBuffer::HBU_STATIC_WRITE_ONLY);
184
185        idata->indexBuffer = ibuf;
186        idata->indexCount = mSlices*6;
187        idata->indexStart = 0;
188        ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
189
190        // Delete temporary buffers
191        delete [] vertices;
192        delete [] faces;
193       
194        // Now make the render operation
195        mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
196        mRenderOp.indexData = idata;
197        mRenderOp.vertexData = vdata;
198        mRenderOp.useIndexes = true;
199       
200         // Create a brand new private material
201        MaterialPtr material = 
202                MaterialManager::getSingleton().create(mTexture, "VolumeRenderable",
203                        false, 0); // Manual, loader
204
205        // Remove pre-created technique from defaults
206        material->removeAllTechniques();
207       
208        // Create a techinique and a pass and a texture unit
209        Technique * technique = material->createTechnique();
210        Pass * pass = technique->createPass();
211        TextureUnitState * textureUnit = pass->createTextureUnitState();
212       
213        // Set pass parameters
214        pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
215        pass->setDepthWriteEnabled(false);
216        pass->setCullingMode(CULL_NONE);
217        pass->setLightingEnabled(false);
218       
219        // Set texture unit parameters
220        textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
221        textureUnit->setTextureName(mTexture, TEX_TYPE_3D);
222        textureUnit->setTextureFiltering(TFO_TRILINEAR);
223       
224        mUnit = textureUnit;
225        m_pMaterial = material;
226}
227
228Ogre::Real VolumeRenderable::getBoundingRadius() const
229{
230        return mRadius;
231}
232Ogre::Real VolumeRenderable::getSquaredViewDepth(const Ogre::Camera* cam) const
233{
234        Ogre::Vector3 min, max, mid, dist;
235
236        min = mBox.getMinimum();
237        max = mBox.getMaximum();
238        mid = ((min - max) * 0.5) + min;
239        dist = cam->getDerivedPosition() - mid;
240                                                                       
241        return dist.squaredLength();
242}
243
Note: See TracBrowser for help on using the repository browser.