So, nachdem ich das erst mal vergessen hatte...
Hier die Änderungen am Code:
IrrMath.h -- Hier müsst ihr erst mal diese Funktion hier ingesammt hinzufügen:
Code:
//! returns bilinear interpolation of a,b,c,d with ratios u and v
// ######### v
// # c # d # |
// ######### |
// # a # b # ---->u
// #########
template<class T>
inline T blerp(const T a, const T b, const T c, const T d, const T u, const T v)
{
return ((a*u*v) + (b*(1.0f-u)*v) + (c*u*(1.0f-v)) + (d*(1.0f-u)*(1.0f-v)));
}
CTerrainSceneNode.cpp -- Diese Funktion ist schon in der Datei enthalten, muss aber geändert werden! Ich will jetzt nicht alles Kommentieren, deshalb gibts hier die Funktion als ganzes.
Code:
f32 CTerrainSceneNode::getHeight( f32 x, f32 z )
{
f32 height = -999999.9f;
core::matrix4 rotMatrix;
rotMatrix.setRotationDegrees( TerrainData.Rotation );
core::vector3df pos( x, 0.0f, z );
rotMatrix.rotateVect( pos );
pos -= TerrainData.Position;
pos /= TerrainData.Scale;
s32 X(core::floor32( pos.X ));
s32 Z(core::floor32( pos.Z ));
if( X >= 0 && X < TerrainData.Size && Z >= 0 && Z <= TerrainData.Size )
{
video::S3DVertex2TCoords* Vertices = (video::S3DVertex2TCoords*)Mesh.getMeshBuffer( 0 )->getVertices();
core::vector3df a = Vertices[ X * TerrainData.Size + Z ].Pos;
core::vector3df b = Vertices[ (X + 1) * TerrainData.Size + Z ].Pos;
core::vector3df c = Vertices[ X * TerrainData.Size + ( Z + 1 ) ].Pos;
core::vector3df d = Vertices[ (X + 1) * TerrainData.Size + ( Z + 1 ) ].Pos;
f32 dx = pos.X - X;
f32 dz = pos.Z - Z;
f32 invDX = 1.0f - dx;
height = core::blerp(d.Y,c.Y,b.Y,a.Y,dx,dz);
height *= TerrainData.Scale.Y;
}
Das wärs eigentlich. Die Funktion ist verdammt schnell, ich hab einen kleinen Test gemacht und nebenbei pro Frame 300 Berechnungen mit der Funktion gemacht, ohne einen erkennbaren Unterschied in der Framerate.
MfG Lynxeye