Moving from using ManualObject to using HardwareBuffers directly.
This commit is contained in:
parent
2d92286889
commit
8f70a4edc5
@ -8,6 +8,7 @@ SET(SRC_FILES
|
|||||||
source/MaterialMapManager.cpp
|
source/MaterialMapManager.cpp
|
||||||
source/MaterialMapSerializer.cpp
|
source/MaterialMapSerializer.cpp
|
||||||
source/PolyVoxSceneManager.cpp
|
source/PolyVoxSceneManager.cpp
|
||||||
|
source/Surface.cpp
|
||||||
source/Volume.cpp
|
source/Volume.cpp
|
||||||
source/VolumeIterator.cpp
|
source/VolumeIterator.cpp
|
||||||
source/VolumeManager.cpp
|
source/VolumeManager.cpp
|
||||||
@ -24,6 +25,7 @@ SET(INC_FILES
|
|||||||
include/MaterialMapManager.h
|
include/MaterialMapManager.h
|
||||||
include/MaterialMapSerializer.h
|
include/MaterialMapSerializer.h
|
||||||
include/PolyVoxSceneManager.h
|
include/PolyVoxSceneManager.h
|
||||||
|
include/Surface.h
|
||||||
include/Triangle.h
|
include/Triangle.h
|
||||||
include/TypeDef.h
|
include/TypeDef.h
|
||||||
include/Vertex.h
|
include/Vertex.h
|
||||||
|
@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
|
|
||||||
#include "Constants.h"
|
#include "Constants.h"
|
||||||
#include "MaterialMap.h"
|
#include "MaterialMap.h"
|
||||||
|
#include "Surface.h"
|
||||||
#include "Triangle.h"
|
#include "Triangle.h"
|
||||||
#include "TypeDef.h"
|
#include "TypeDef.h"
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
@ -95,6 +96,8 @@ namespace Ogre
|
|||||||
bool manualObjectUpToDate[OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS];
|
bool manualObjectUpToDate[OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS];
|
||||||
bool regionIsHomogenous[OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS];
|
bool regionIsHomogenous[OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS];
|
||||||
|
|
||||||
|
std::map<uchar,Surface*> m_mapSurfaces[OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS][OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS];
|
||||||
|
|
||||||
void igniteVoxel(UIntVector3 voxelToIgnite);
|
void igniteVoxel(UIntVector3 voxelToIgnite);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -115,6 +118,8 @@ namespace Ogre
|
|||||||
|
|
||||||
std::queue<UIntVector3> m_queueVoxelsToBurn;
|
std::queue<UIntVector3> m_queueVoxelsToBurn;
|
||||||
|
|
||||||
|
bool m_bHaveGeneratedMeshes;
|
||||||
|
|
||||||
//std::string m_aMaterialNames[256];
|
//std::string m_aMaterialNames[256];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
30
include/Surface.h
Normal file
30
include/Surface.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef __SURFACE_H__
|
||||||
|
#define __SURFACE_H__
|
||||||
|
|
||||||
|
#include "Ogre.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Triangle.h"
|
||||||
|
#include "Vertex.h"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Surface : public SimpleRenderable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Surface();
|
||||||
|
Surface(const String& material);
|
||||||
|
~Surface(void);
|
||||||
|
|
||||||
|
void setGeometry(std::vector<Vertex> verticesToSet, std::vector<Triangle> indicesToSet);
|
||||||
|
|
||||||
|
Real getSquaredViewDepth(const Camera *cam) const;
|
||||||
|
Real getBoundingRadius(void) const;
|
||||||
|
protected:
|
||||||
|
//void getWorldTransforms(Matrix4 *xform) const;
|
||||||
|
const Quaternion &getWorldOrientation(void) const;
|
||||||
|
const Vector3 &getWorldPosition(void) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __SURFACE_H__ */
|
54
include/Triangle.h
Normal file
54
include/Triangle.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
This file is part of a voxel plugin for OGRE
|
||||||
|
Copyright (C) 2006 David Williams
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __Triangle_H__
|
||||||
|
#define __Triangle_H__
|
||||||
|
|
||||||
|
#include "OgrePrerequisites.h"
|
||||||
|
|
||||||
|
#include "OgreVector3.h"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Triangle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//FIXME - maybe these should be short?
|
||||||
|
ulong v0;
|
||||||
|
ulong v1;
|
||||||
|
ulong v2;
|
||||||
|
|
||||||
|
Triangle()
|
||||||
|
:v0(0)
|
||||||
|
,v1(0)
|
||||||
|
,v2(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Triangle(uint v0ToSet, uint v1ToSet, uint v2ToSet)
|
||||||
|
:v0(v0ToSet)
|
||||||
|
,v1(v1ToSet)
|
||||||
|
,v2(v2ToSet)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -68,6 +68,7 @@ namespace Ogre
|
|||||||
,useNormalSmoothing(false)
|
,useNormalSmoothing(false)
|
||||||
,normalSmoothingFilterSize(1)
|
,normalSmoothingFilterSize(1)
|
||||||
,m_normalGenerationMethod(SOBEL)
|
,m_normalGenerationMethod(SOBEL)
|
||||||
|
,m_bHaveGeneratedMeshes(false)
|
||||||
{
|
{
|
||||||
for(uint regionZ = 0; regionZ < OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionZ)
|
for(uint regionZ = 0; regionZ < OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionZ)
|
||||||
{
|
{
|
||||||
@ -145,7 +146,7 @@ namespace Ogre
|
|||||||
{
|
{
|
||||||
destroySceneNode(sceneNodes[blockX][blockY][blockZ]->getName()); //FIXME - when it's available in CVS, use destroyAllSceneNodes commented out below.
|
destroySceneNode(sceneNodes[blockX][blockY][blockZ]->getName()); //FIXME - when it's available in CVS, use destroyAllSceneNodes commented out below.
|
||||||
}
|
}
|
||||||
sceneNodes[blockX][blockY][blockZ] = 0;
|
sceneNodes[blockX][blockY][blockZ] = getRootSceneNode()->createChildSceneNode(Vector3(blockX*OGRE_REGION_SIDE_LENGTH,blockY*OGRE_REGION_SIDE_LENGTH,blockZ*OGRE_REGION_SIDE_LENGTH));;
|
||||||
manualObjectUpToDate[blockX][blockY][blockZ] = false;
|
manualObjectUpToDate[blockX][blockY][blockZ] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,8 +325,64 @@ namespace Ogre
|
|||||||
LogManager::getSingleton().logMessage("regionZ = " + StringConverter::toString(regionZ));
|
LogManager::getSingleton().logMessage("regionZ = " + StringConverter::toString(regionZ));
|
||||||
for(uint regionY = 0; regionY < OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionY)
|
for(uint regionY = 0; regionY < OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionY)
|
||||||
{
|
{
|
||||||
|
//LogManager::getSingleton().logMessage("regionY = " + StringConverter::toString(regionY));
|
||||||
for(uint regionX = 0; regionX < OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionX)
|
for(uint regionX = 0; regionX < OGRE_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionX)
|
||||||
{
|
{
|
||||||
|
//LogManager::getSingleton().logMessage("regionX = " + StringConverter::toString(regionX));
|
||||||
|
if(manualObjectUpToDate[regionX][regionY][regionZ] == false)
|
||||||
|
{
|
||||||
|
std::vector<Vertex> vertexData;
|
||||||
|
std::vector< std::vector< Triangle> > indexData;
|
||||||
|
generateMeshDataForRegion(regionX,regionY,regionZ,vertexData,indexData);
|
||||||
|
|
||||||
|
sceneNodes[regionX][regionY][regionZ]->detachAllObjects();
|
||||||
|
|
||||||
|
for(uint meshCt = 1; meshCt < 256; ++meshCt)
|
||||||
|
{
|
||||||
|
if(indexData[meshCt].size() == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::map<uchar,Surface*>::iterator iterSurface = m_mapSurfaces[regionX][regionY][regionZ].find(meshCt);
|
||||||
|
if(iterSurface == m_mapSurfaces[regionX][regionY][regionZ].end())
|
||||||
|
{
|
||||||
|
//We have to create the surface
|
||||||
|
Surface* surface = new Surface(materialMap->getMaterialAtIndex(meshCt));
|
||||||
|
|
||||||
|
sceneNodes[regionX][regionY][regionZ]->attachObject(surface);
|
||||||
|
|
||||||
|
m_mapSurfaces[regionX][regionY][regionZ].insert(std::make_pair(meshCt,surface));
|
||||||
|
|
||||||
|
surface->setGeometry(vertexData,indexData[meshCt]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//We just update the existing surface
|
||||||
|
iterSurface->second->setGeometry(vertexData,indexData[meshCt]);
|
||||||
|
sceneNodes[regionX][regionY][regionZ]->attachObject(iterSurface->second);
|
||||||
|
|
||||||
|
//sceneNodes[regionX][regionY][regionZ]->detachObject(iterSurface->second);
|
||||||
|
/*delete iterSurface->second;
|
||||||
|
m_mapSurfaces[regionX][regionY][regionZ].erase(iterSurface);
|
||||||
|
|
||||||
|
//We have to create the surface
|
||||||
|
Surface* surface = new Surface(materialMap->getMaterialAtIndex(meshCt));
|
||||||
|
|
||||||
|
//sceneNodes[regionX][regionY][regionZ] = getRootSceneNode()->createChildSceneNode(Vector3(regionX*OGRE_REGION_SIDE_LENGTH,regionY*OGRE_REGION_SIDE_LENGTH,regionZ*OGRE_REGION_SIDE_LENGTH));
|
||||||
|
sceneNodes[regionX][regionY][regionZ]->attachObject(surface);
|
||||||
|
|
||||||
|
m_mapSurfaces[regionX][regionY][regionZ].insert(std::make_pair(meshCt,surface));
|
||||||
|
|
||||||
|
surface->setGeometry(vertexData,indexData[meshCt]);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
manualObjectUpToDate[regionX][regionY][regionZ] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//m_bHaveGeneratedMeshes = true;
|
||||||
|
|
||||||
|
#ifdef USE_MAN_OBJS
|
||||||
|
|
||||||
if(manualObjectUpToDate[regionX][regionY][regionZ] == false)
|
if(manualObjectUpToDate[regionX][regionY][regionZ] == false)
|
||||||
{
|
{
|
||||||
/*for(uint materialCt2 = 0; materialCt2 < MAX_NO_OF_MATERIAL_BOUNDARIES_PER_REGION; ++materialCt2)
|
/*for(uint materialCt2 = 0; materialCt2 < MAX_NO_OF_MATERIAL_BOUNDARIES_PER_REGION; ++materialCt2)
|
||||||
@ -444,8 +501,9 @@ namespace Ogre
|
|||||||
//++materialCt;
|
//++materialCt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
manualObjectUpToDate[regionX][regionY][regionZ] = true;
|
//manualObjectUpToDate[regionX][regionY][regionZ] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -792,6 +850,7 @@ namespace Ogre
|
|||||||
material = std::max(material,v111);
|
material = std::max(material,v111);
|
||||||
|
|
||||||
//vertexScaled values are always integers and so can be used as indices.
|
//vertexScaled values are always integers and so can be used as indices.
|
||||||
|
//FIXME - these integer values can just be obtained by using floor()?
|
||||||
long int index;
|
long int index;
|
||||||
unsigned int vertexScaledX;
|
unsigned int vertexScaledX;
|
||||||
unsigned int vertexScaledY;
|
unsigned int vertexScaledY;
|
||||||
|
173
source/Surface.cpp
Normal file
173
source/Surface.cpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
#include "Surface.h"
|
||||||
|
|
||||||
|
#include "OgreVertexIndexData.h"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
|
||||||
|
Surface::Surface()
|
||||||
|
{
|
||||||
|
mRenderOp.vertexData = NULL;
|
||||||
|
mRenderOp.indexData = NULL;
|
||||||
|
|
||||||
|
this->setMaterial("BaseWhiteNoLighting");
|
||||||
|
}
|
||||||
|
|
||||||
|
Surface::Surface(const String& material)
|
||||||
|
{
|
||||||
|
mRenderOp.vertexData = NULL;
|
||||||
|
mRenderOp.indexData = NULL;
|
||||||
|
|
||||||
|
this->setMaterial(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
Surface::~Surface(void)
|
||||||
|
{
|
||||||
|
delete mRenderOp.vertexData;
|
||||||
|
delete mRenderOp.indexData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Surface::setGeometry(std::vector<Vertex> verticesToSet, std::vector<Triangle> indicesToSet)
|
||||||
|
{
|
||||||
|
if(mRenderOp.vertexData)
|
||||||
|
{
|
||||||
|
delete mRenderOp.vertexData;
|
||||||
|
mRenderOp.vertexData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mRenderOp.indexData)
|
||||||
|
{
|
||||||
|
delete mRenderOp.indexData;
|
||||||
|
mRenderOp.indexData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mRenderOp.vertexData = new VertexData();
|
||||||
|
mRenderOp.indexData = new IndexData();
|
||||||
|
//LogManager::getSingleton().logMessage("In setGeometry()");
|
||||||
|
// Initialization stuff
|
||||||
|
mRenderOp.vertexData->vertexCount = verticesToSet.size();
|
||||||
|
mRenderOp.vertexData->vertexStart = 0;
|
||||||
|
mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; // OT_LINE_LIST, OT_LINE_STRIP
|
||||||
|
mRenderOp.useIndexes = true;
|
||||||
|
mRenderOp.indexData->indexStart = 0;
|
||||||
|
mRenderOp.indexData->indexCount = indicesToSet.size()*3;
|
||||||
|
|
||||||
|
//LogManager::getSingleton().logMessage("Finished initialisaing stuff");
|
||||||
|
|
||||||
|
VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
|
||||||
|
VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding;
|
||||||
|
|
||||||
|
//FIXME - this should be moved to constructor?
|
||||||
|
//LogManager::getSingleton().logMessage("Creating Vertex Declaration");
|
||||||
|
decl->removeAllElements();
|
||||||
|
decl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
|
||||||
|
decl->addElement(0, 3 * sizeof(float), VET_FLOAT3, VES_NORMAL);
|
||||||
|
|
||||||
|
//LogManager::getSingleton().logMessage("Creating Vertex Buffer");
|
||||||
|
HardwareVertexBufferSharedPtr vbuf =
|
||||||
|
HardwareBufferManager::getSingleton().createVertexBuffer(
|
||||||
|
decl->getVertexSize(0),
|
||||||
|
mRenderOp.vertexData->vertexCount,
|
||||||
|
HardwareBuffer::HBU_STATIC_WRITE_ONLY);
|
||||||
|
|
||||||
|
bind->setBinding(0, vbuf);
|
||||||
|
|
||||||
|
//LogManager::getSingleton().logMessage("Creating Index Buffer");
|
||||||
|
HardwareIndexBufferSharedPtr ibuf =
|
||||||
|
HardwareBufferManager::getSingleton().createIndexBuffer(
|
||||||
|
HardwareIndexBuffer::IT_16BIT, // type of index
|
||||||
|
mRenderOp.indexData->indexCount * 3, // number of indexes
|
||||||
|
HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage
|
||||||
|
false); // no shadow buffer
|
||||||
|
|
||||||
|
mRenderOp.indexData->indexBuffer = ibuf;
|
||||||
|
|
||||||
|
|
||||||
|
// Drawing stuff
|
||||||
|
int size = verticesToSet.size();
|
||||||
|
Vector3 vaabMin = verticesToSet[0].position;
|
||||||
|
Vector3 vaabMax = verticesToSet[0].position;
|
||||||
|
|
||||||
|
//LogManager::getSingleton().logMessage("Setting Vertex Data of size " + StringConverter::toString(size));
|
||||||
|
|
||||||
|
Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
*prPos++ = verticesToSet[i].position.x;
|
||||||
|
*prPos++ = verticesToSet[i].position.y;
|
||||||
|
*prPos++ = verticesToSet[i].position.z;
|
||||||
|
|
||||||
|
*prPos++ = verticesToSet[i].normal.x;
|
||||||
|
*prPos++ = verticesToSet[i].normal.y;
|
||||||
|
*prPos++ = verticesToSet[i].normal.z;
|
||||||
|
|
||||||
|
if(verticesToSet[i].position.x < vaabMin.x)
|
||||||
|
vaabMin.x = verticesToSet[i].position.x;
|
||||||
|
if(verticesToSet[i].position.y < vaabMin.y)
|
||||||
|
vaabMin.y = verticesToSet[i].position.y;
|
||||||
|
if(verticesToSet[i].position.z < vaabMin.z)
|
||||||
|
vaabMin.z = verticesToSet[i].position.z;
|
||||||
|
|
||||||
|
if(verticesToSet[i].position.x > vaabMax.x)
|
||||||
|
vaabMax.x = verticesToSet[i].position.x;
|
||||||
|
if(verticesToSet[i].position.y > vaabMax.y)
|
||||||
|
vaabMax.y = verticesToSet[i].position.y;
|
||||||
|
if(verticesToSet[i].position.z > vaabMax.z)
|
||||||
|
vaabMax.z = verticesToSet[i].position.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
vbuf->unlock();
|
||||||
|
|
||||||
|
mBox.setExtents(vaabMin, vaabMax);
|
||||||
|
|
||||||
|
//LogManager::getSingleton().logMessage("Setting Index Data of size " + StringConverter::toString(indicesToSet.size()));
|
||||||
|
|
||||||
|
unsigned short* pIdx = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));
|
||||||
|
for(int i = 0; i < indicesToSet.size(); i++)
|
||||||
|
{
|
||||||
|
*pIdx = indicesToSet[i].v0;
|
||||||
|
pIdx++;
|
||||||
|
*pIdx = indicesToSet[i].v1;
|
||||||
|
pIdx++;
|
||||||
|
*pIdx = indicesToSet[i].v2;
|
||||||
|
pIdx++;
|
||||||
|
}
|
||||||
|
ibuf->unlock();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Real Surface::getSquaredViewDepth(const Camera *cam) const
|
||||||
|
{
|
||||||
|
Vector3 vMin, vMax, vMid, vDist;
|
||||||
|
vMin = mBox.getMinimum();
|
||||||
|
vMax = mBox.getMaximum();
|
||||||
|
vMid = ((vMin - vMax) * 0.5) + vMin;
|
||||||
|
vDist = cam->getDerivedPosition() - vMid;
|
||||||
|
|
||||||
|
return vDist.squaredLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
Real Surface::getBoundingRadius(void) const
|
||||||
|
{
|
||||||
|
return Math::Sqrt((std::max)(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength()));
|
||||||
|
//return mRadius;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void Line3D::getWorldTransforms(Matrix4 *xform) const
|
||||||
|
{
|
||||||
|
// return identity matrix to prevent parent transforms
|
||||||
|
*xform = Matrix4::IDENTITY;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
const Quaternion &Surface::getWorldOrientation(void) const
|
||||||
|
{
|
||||||
|
return Quaternion::IDENTITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector3 &Surface::getWorldPosition(void) const
|
||||||
|
{
|
||||||
|
return Vector3::ZERO;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user