DYTSrouce/src/effects/TrackWave.cpp
2025-01-04 12:12:51 +08:00

256 lines
5.1 KiB
C++

#include "effects/TrackWave.h"
#include <algorithm>
#include <math.h>
#include <osg/Drawable>
#include <osg/Geometry>
#include <osg/CullFace>
#include <osg/Depth>
TrackWave::TrackWave(ElectricWave* pElectricWave)
: DrawDecorate(pElectricWave), m_fHeight(5),m_fBottomRadius(2),m_fTopRadius(5),\
m_fSpaceHeight(5),m_fLoopHeight(4),m_fdHeight(0),m_vStart(0, 0, 0), m_vEnd(0, 0, 85),\
m_fUpdateValue(2), m_nCount(0),m_bZ(true)
{
m_fdRadius = (m_fTopRadius - m_fBottomRadius) / m_fHeight;
}
TrackWave::~TrackWave(void)
{
}
// 设置起始点和终止点
void TrackWave::SetStartAndEnd(const osg::Vec3d& vStart, const osg::Vec3d& vEnd)
{
m_vStart = vStart;
m_vEnd = vEnd;
osg::Vec3d vDir = m_vEnd - m_vStart;
// 计算长度
m_fHeight = vDir.length();
// 归一化
vDir.normalize();
m_matrix = osg::Matrix::rotate(osg::Vec3d(0, 0, 1), vDir);
// 重新计算半径
ComputeDRadius();
ForceDraw();
ForceDrawStyle();
}
// 设置起始点和终止点
void TrackWave::GetStartAndEnd(osg::Vec3d& vStart, osg::Vec3d& vEnd)
{
vStart = m_vStart;
vEnd = m_vEnd;
}
// 设置半径
void TrackWave::SetRadius(const double fTopRadius, const double fBottonRadius)
{
m_fTopRadius = fTopRadius;
m_fBottomRadius = fBottonRadius;
// 计算半径变化率
ComputeDRadius();
}
// 获得半径
void TrackWave::GetRadius(double& fTopRadius, double& fBottonRadius)
{
fTopRadius = m_fTopRadius;
fBottonRadius = m_fBottomRadius;
}
// 设置环高度
void TrackWave::SetLoopHeight(const double fLoopHeight)
{
m_fLoopHeight = fLoopHeight;
}
// 设置间隔高度
void TrackWave::SetSpaceHeight(const double fSpaceHeight)
{
m_fSpaceHeight = fSpaceHeight;
}
// 设置更新速度
void TrackWave::SetUpdateSpeed(const double fSpeed)
{
m_fUpdateValue = fSpeed;
}
// 是否是放大波
void TrackWave::SetWaveStyle(bool bZ)
{
m_bZ = bZ;
ForceDraw();
}
// 获得是否放大波
bool TrackWave::GetWaveSytle(void) const
{
return (m_bZ);
}
// 创建渲染体
osg::Drawable* TrackWave::CreateDrawable(void)
{
// 创建视图
osg::Drawable* pDrawable = DrawDecorate::CreateDrawable();
return (pDrawable);
}
// 获得顶点数组
osg::Vec3dArray* TrackWave::GetVertexArrays(void)
{
osg::Vec3dArray* pVertexArray = new osg::Vec3dArray;
double dCount = (m_fHeight / (m_fSpaceHeight + m_fLoopHeight));
// 计算环的个数
m_nCount = (dCount - (int)dCount >= 0.5f) ? (int)dCount + 1 : (int)dCount;
for (int index = 0; index < m_nCount; ++index)
{
// 计数从1开始
CreateSingleVertex(index, pVertexArray);
}
return (pVertexArray);
}
void TrackWave::CreatePrimitiveSet(osg::Geometry* pGeometry, int nStart, int nCount)
{
pGeometry->removePrimitiveSet(0, pGeometry->getNumPrimitiveSets());
for (int index = 0; index < m_nCount; ++index)
{
pGeometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, index * 122, 122));
}
}
// 创建圆环
void TrackWave::CreateSingleVertex(double index, osg::Vec3dArray* pVertexArray)
{
// 计算高度
double fHeight = index * (m_fLoopHeight + m_fSpaceHeight) + m_fLoopHeight + m_fdHeight;
if ((fHeight - m_fLoopHeight) >= m_fHeight)
{
fHeight -= m_fHeight;
}
// 计算顶部的半径
double fTopRadius = CreateTopRadius(fHeight );
// 计算底部半径
double fBottonRadius = CreateBottonRadius(fHeight);
// 临时变量
double ftemp = 0;
// 更新值
for (int angle = 0; angle <= 60; ++angle)
{
double dTheta = osg::DegreesToRadians(angle * 6.0f);
double xCos = std::cos(dTheta);
double ySin = std::sin(dTheta);
double xt = fTopRadius * xCos;
double yt = fTopRadius * ySin;
//ftemp = fHeight;
//判断值有效
ftemp = std::min(fHeight, m_fHeight);
double zt = ftemp ;
double xb = fBottonRadius * xCos ;
double yb = fBottonRadius * ySin ;
ftemp = fHeight - m_fLoopHeight;
double zb = ftemp ;
osg::Vec3d vTop(xt, yt, m_bZ ? zt : (m_fHeight - zt));
osg::Vec3d vBotton(xb, yb, m_bZ ? zb : (m_fHeight - zb));
vTop = vTop * m_matrix;
vBotton = vBotton * m_matrix;
vTop += m_vStart;
vBotton += m_vStart;
pVertexArray->push_back(vTop);
pVertexArray->push_back(vBotton);
}
}
// 计算半径
double TrackWave::CreateTopRadius(double fHeight)
{
// 判断最大有效半径
fHeight = std::min(m_fHeight, fHeight);
fHeight = m_bZ ? (fHeight) : (m_fHeight - fHeight);
// 计算高度
double fRadius = fHeight * m_fdRadius + m_fBottomRadius;
return (fRadius);
}
// 计算底部半径
double TrackWave::CreateBottonRadius(double fHeight)
{
// 判断最大有效半径
fHeight = std::min(m_fHeight, fHeight);
double btLoopHeihgt = m_fHeight - fHeight ;
if (btLoopHeihgt > 0 )
{
btLoopHeihgt += m_fLoopHeight;
}
else
{
btLoopHeihgt = 0;
}
fHeight = m_bZ ? (fHeight - m_fLoopHeight) : (btLoopHeihgt);
// 计算高度
double fRadius = (fHeight) * m_fdRadius + m_fBottomRadius;
return (fRadius);
}
// 获取两点间的距离
double TrackWave::GetDis(void)
{
const osg::Vec3d v = m_vEnd - m_vStart;
return (v.length());
}
// 计算半径斜率
double TrackWave::ComputeDRadius(void)
{
m_fdRadius = (m_fTopRadius - m_fBottomRadius) / m_fHeight;
return (m_fdRadius);
}
// 获得环的个数
int TrackWave::GetCount(void)
{
return (m_nCount);
}
// 更新
void TrackWave::UpdataDrawable(void)
{
if((m_fdHeight += m_fUpdateValue) > (m_fHeight))
{
m_fdHeight = 0;
}
ForceDraw();
DrawDecorate::UpdataDrawable();
}