#pragma once
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/MatrixTransform>
class CSphereCallBack : public osg::NodeCallback
{
public:
CSphereCallBack();
~CSphereCallBack();
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
void setPlanetPama(const double &autoRotSpeed, const double &revolRadius, const double &revolRotSpeed);
void setTranslateMat(const osg::Matrix &translateMat = osg::Matrix());
void setRotatable(const bool rot) { m_bRotable = rot; }
public:
double m_dAutoAngle;
double m_dRevolAngle;
double m_dAutoRotSpeed; //自转速度
double m_dRevolRadius; //公转半径
double m_dRevolRotSpeed; //公转速度
bool m_bRotable; //是否转动
osg::Matrix m_translateMat;
};
class TailCallback : public osg::NodeCallback
{
public:
TailCallback(const double &revolRadius, const double &revolRotSpeed)
: m_dRevolRadius(revolRadius)
, m_dRevolRotSpeed(revolRotSpeed)
, m_dRevolAngle(0)
, m_bRotable(true)
{}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (m_bRotable)
{
//获取当前运行时间
double rotateTime = nv->getFrameStamp()->getReferenceTime();
osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(node);
osg::Matrix mat1, mat2, mat3;
//mat1.makeRotate(-osg::PI_4, osg::Y_AXIS);
//mat3.makeRotate(0, osg::Z_AXIS, 0, osg::Z_AXIS, 0, osg::Y_AXIS);
mat2.makeTranslate(m_dRevolRadius * cos(m_dRevolAngle), m_dRevolRadius*sin(m_dRevolAngle), 0.0);
mt->setMatrix(mat1*mat3*mat2);
traverse(node, nv);
m_dRevolAngle += m_dRevolRotSpeed;// = m_dRevolRotSpeed * rotateTime * 100;
}
}
void updatePara(const double &revolRadius, const double &revolRotSpeed)
{
m_dRevolRadius = revolRadius;
m_dRevolRotSpeed = revolRotSpeed;
}
void setRotatable(const bool rot) { m_bRotable = rot; }
private:
double m_dRevolRadius; //公转半径
double m_dRevolRotSpeed; //公转速度
double m_dRevolAngle;
bool m_bRotable; //是否转动
};
//尾迹
class CTrailerCallback :public osg::NodeCallback
{
public:
CTrailerCallback(osg::Geometry* ribbon, int vertexNum);
~CTrailerCallback();
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) override;
private:
int m_size;
osg::observer_ptr<osg::Geometry> m_opGeometry;
};
#include "CSphereCallBack.h"
#include <qDebug>
CSphereCallBack::CSphereCallBack()
: m_dAutoAngle(0)
, m_dRevolAngle(0)
, m_bRotable(true)
{
}
CSphereCallBack::~CSphereCallBack()
{
}
void CSphereCallBack::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (m_bRotable)
{
//获取当前运行时间
double rotateTime = nv->getFrameStamp()->getReferenceTime();
osg::ref_ptr<osg::MatrixTransform> matrixTrans = dynamic_cast<osg::MatrixTransform*>(node);
osg::Matrix mat1, mat2, mat3;
mat1.makeRotate(m_dAutoAngle, osg::Vec3(0.0, 0.0, 1.0));//自传
if (!m_translateMat.isIdentity())//小行星带位置特殊处理
mat2 = m_translateMat;
else
mat2.makeTranslate(m_dRevolRadius, 0.0, 0.0);//平移
mat3.makeRotate(m_dRevolAngle, osg::Vec3(0.0, 0.0, 1.0));//自传
matrixTrans->setMatrix(mat1 * mat2 * mat3);
m_dAutoAngle += m_dAutoRotSpeed;// = m_dAutoRotSpeed * rotateTime * 100;
m_dRevolAngle += m_dRevolRotSpeed;//= m_dRevolRotSpeed * rotateTime * 100;
}
traverse(node, nv);
}
void CSphereCallBack::setPlanetPama(const double &autoRotSpeed, const double &revolRadius, const double &revolRotSpeed)
{
m_dAutoRotSpeed = autoRotSpeed;
m_dRevolRotSpeed = revolRotSpeed;
m_dRevolRadius = revolRadius;
}
void CSphereCallBack::setTranslateMat(const osg::Matrix &translateMat)
{
m_translateMat = translateMat;
}
CTrailerCallback::CTrailerCallback(osg::Geometry* ribbon, int vertexNum)
: m_opGeometry(ribbon)
, m_size(vertexNum)
{
}
CTrailerCallback::~CTrailerCallback()
{
}
void CTrailerCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
osg::MatrixTransform* trans = dynamic_cast<osg::MatrixTransform*> (node);
if (trans && m_opGeometry.valid())
{
osg::Matrix mat = trans->getMatrix();
osg::Vec3Array* vec3array = dynamic_cast<osg::Vec3Array*>(m_opGeometry->getVertexArray());
for (unsigned int i = 0; i < m_size-1; ++i)
{
(*vec3array)[i] = (*vec3array)[i + 1];
}
(*vec3array)[m_size - 1] = osg::Vec3(0.0f, 0.0f, 0.0f) * mat;
vec3array->dirty();
m_opGeometry->dirtyBound();
}
traverse(node, nv);
}