irrlicht/source/Irrlicht/CWaterSurfaceSceneNode.cpp

187 lines
4.4 KiB
C++

// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CWaterSurfaceSceneNode.h"
#include "ISceneManager.h"
#include "IMeshManipulator.h"
#include "S3DVertex.h"
#include "SMesh.h"
#include "os.h"
namespace irr
{
namespace scene
{
//! constructor
CWaterSurfaceSceneNode::CWaterSurfaceSceneNode(f32 waveHeight, f32 waveSpeed, f32 waveLength,
IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::vector3df& rotation,
const core::vector3df& scale)
: CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale), WaveLength(waveLength),
WaveSpeed(waveSpeed), WaveHeight(waveHeight), OriginalMesh(0)
{
#ifdef _DEBUG
setDebugName("CWaterSurfaceSceneNode");
#endif
// create copy of the mesh
if (!mesh)
return;
IMesh* clone = SceneManager->getMeshManipulator()->createMeshCopy(mesh);
OriginalMesh = Mesh;
Mesh = clone;
}
//! destructor
CWaterSurfaceSceneNode::~CWaterSurfaceSceneNode()
{
if (OriginalMesh)
OriginalMesh->drop();
}
//! frame
void CWaterSurfaceSceneNode::OnRegisterSceneNode()
{
if (IsVisible)
{
SceneManager->registerNodeForRendering(this);
animateWaterSurface();
CMeshSceneNode::OnRegisterSceneNode();
}
}
void CWaterSurfaceSceneNode::animateWaterSurface()
{
if (!Mesh)
return;
u32 meshBufferCount = Mesh->getMeshBufferCount();
f32 time = os::Timer::getTime() / WaveSpeed;
for (u32 b=0; b<meshBufferCount; ++b)
{
u32 vtxCnt = Mesh->getMeshBuffer(b)->getVertexCount();
switch(Mesh->getMeshBuffer(b)->getVertexType())
{
case video::EVT_STANDARD:
{
video::S3DVertex* v =
(video::S3DVertex*)Mesh->getMeshBuffer(b)->getVertices();
video::S3DVertex* v2 =
(video::S3DVertex*)OriginalMesh->getMeshBuffer(b)->getVertices();
for (u32 i=0; i<vtxCnt; ++i)
{
v[i].Pos.Y = v2[i].Pos.Y +
(sinf(((v2[i].Pos.X/WaveLength) + time)) * WaveHeight) +
(cosf(((v2[i].Pos.Z/WaveLength) + time)) * WaveHeight);
}
}
break;
case video::EVT_2TCOORDS:
{
video::S3DVertex2TCoords* v =
(video::S3DVertex2TCoords*)Mesh->getMeshBuffer(b)->getVertices();
video::S3DVertex2TCoords* v2 =
(video::S3DVertex2TCoords*)OriginalMesh->getMeshBuffer(b)->getVertices();
for (u32 i=0; i<vtxCnt; ++i)
{
v[i].Pos.Y = v2[i].Pos.Y +
(sinf(((v2[i].Pos.X/WaveLength) + time)) * WaveHeight) +
(cosf(((v2[i].Pos.Z/WaveLength) + time)) * WaveHeight);
}
}
break;
case video::EVT_TANGENTS:
{
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)Mesh->getMeshBuffer(b)->getVertices();
video::S3DVertexTangents* v2 =
(video::S3DVertexTangents*)OriginalMesh->getMeshBuffer(b)->getVertices();
for (u32 i=0; i<vtxCnt; ++i)
{
v[i].Pos.Y = v2[i].Pos.Y +
(sinf(((v2[i].Pos.X/WaveLength) + time)) * WaveHeight) +
(cosf(((v2[i].Pos.Z/WaveLength) + time)) * WaveHeight);
}
}
break;
} // end switch
}// end for all mesh buffers
SceneManager->getMeshManipulator()->recalculateNormals(Mesh);
}
//! Writes attributes of the scene node.
void CWaterSurfaceSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options)
{
out->addFloat("WaveLength", WaveLength);
out->addFloat("WaveSpeed", WaveSpeed);
out->addFloat("WaveHeight", WaveHeight);
// serialize original mesh
scene::IMesh *swap = 0;
if (Mesh)
{
swap = Mesh;
Mesh = OriginalMesh;
}
CMeshSceneNode::serializeAttributes(out, options);
if (swap)
{
Mesh = swap;
OriginalMesh = Mesh;
}
}
//! Reads attributes of the scene node.
void CWaterSurfaceSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
WaveLength = in->getAttributeAsFloat("WaveLength");
WaveSpeed = in->getAttributeAsFloat("WaveSpeed");
WaveHeight = in->getAttributeAsFloat("WaveHeight");
if (Mesh)
{
Mesh->drop();
Mesh = OriginalMesh;
OriginalMesh = 0;
}
// deserialize original mesh
CMeshSceneNode::deserializeAttributes(in, options);
if (Mesh)
{
IMesh* clone = SceneManager->getMeshManipulator()->createMeshCopy(Mesh);
OriginalMesh = Mesh;
Mesh = clone;
}
}
} // end namespace scene
} // end namespace irr