256 lines
5.1 KiB
C++
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();
|
|
} |