add rebuild cone wave
This commit is contained in:
parent
1d7ba7c418
commit
09767ecdbd
@ -113,7 +113,7 @@ void ConeWave::Render(double dt) {
|
||||
}
|
||||
|
||||
void ConeWave::InitGeode() {
|
||||
CreateRadarScanWave();
|
||||
Rebuild();
|
||||
getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
@ -127,32 +127,13 @@ void ConeWave::Destory() {
|
||||
|
||||
void ConeWave::SetHeight(float height) {
|
||||
height_ = height;
|
||||
if (cone_.valid()) {
|
||||
cone_->setHeight(height_);
|
||||
// 更新锥形中心位置以保持顶点在原点
|
||||
cone_->setCenter(osg::Vec3(0, 0, -height_/2));
|
||||
// 强制更新ShapeDrawable
|
||||
if (coneDrawable_.valid()) {
|
||||
coneDrawable_->dirtyDisplayList();
|
||||
coneDrawable_->dirtyBound();
|
||||
}
|
||||
}
|
||||
// 确保着色器已经初始化
|
||||
if (!levelHeightUniform_.valid() && coneDrawable_.valid()) {
|
||||
CreateRadarShader();
|
||||
}
|
||||
// 更新着色器中的高度uniform
|
||||
if (levelHeightUniform_.valid()) {
|
||||
levelHeightUniform_->set(height_ > 0 ? height_ : 100.0f);
|
||||
}
|
||||
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void ConeWave::SetBaseColor(const osg::Vec4& color) {
|
||||
baseColor_ = color;
|
||||
// 确保着色器已经初始化
|
||||
if (!baseColorUniform_.valid() && coneDrawable_.valid()) {
|
||||
CreateRadarShader();
|
||||
}
|
||||
|
||||
if (baseColorUniform_.valid()) {
|
||||
baseColorUniform_->set(baseColor_);
|
||||
}
|
||||
@ -160,23 +141,12 @@ void ConeWave::SetBaseColor(const osg::Vec4& color) {
|
||||
|
||||
void ConeWave::SetWaveCount(int count) {
|
||||
waveCount_ = count;
|
||||
// 确保着色器已经初始化
|
||||
if (!waveCountUniform_.valid() && coneDrawable_.valid()) {
|
||||
CreateRadarShader();
|
||||
}
|
||||
|
||||
if (waveCountUniform_.valid()) {
|
||||
waveCountUniform_->set(static_cast<float>(waveCount_));
|
||||
}
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void ConeWave::SetWaveSpeed(float speed) {
|
||||
waveSpeed_ = speed;
|
||||
// 确保着色器已经初始化
|
||||
if (!waveSpeedUniform_.valid() && coneDrawable_.valid()) {
|
||||
CreateRadarShader();
|
||||
}
|
||||
|
||||
|
||||
if (waveSpeedUniform_.valid()) {
|
||||
waveSpeedUniform_->set(waveSpeed_);
|
||||
}
|
||||
@ -185,30 +155,13 @@ void ConeWave::SetWaveSpeed(float speed) {
|
||||
// 雷达扫描波效果相关方法实现
|
||||
void ConeWave::SetWaveRadius(float radius) {
|
||||
waveRadius_ = radius;
|
||||
// 确保着色器已经初始化
|
||||
if (!waveRadiusUniform_.valid() && coneDrawable_.valid()) {
|
||||
CreateRadarShader();
|
||||
}
|
||||
if (waveRadiusUniform_.valid()) {
|
||||
waveRadiusUniform_->set(radius);
|
||||
}
|
||||
// 更新Cone的半径以匹配扫描波半径
|
||||
if (cone_.valid()) {
|
||||
cone_->setRadius(radius);
|
||||
// 强制更新ShapeDrawable
|
||||
if (coneDrawable_.valid()) {
|
||||
coneDrawable_->dirtyDisplayList();
|
||||
coneDrawable_->dirtyBound();
|
||||
}
|
||||
}
|
||||
radius_ = radius; // 同时更新锥形的半径
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void ConeWave::SetWaveColor(const osg::Vec4& color) {
|
||||
waveColor_ = color;
|
||||
// 确保着色器已经初始化
|
||||
if (!waveColorUniform_.valid() && coneDrawable_.valid()) {
|
||||
CreateRadarShader();
|
||||
}
|
||||
|
||||
if (waveColorUniform_.valid()) {
|
||||
waveColorUniform_->set(waveColor_);
|
||||
}
|
||||
@ -217,10 +170,7 @@ void ConeWave::SetWaveColor(const osg::Vec4& color) {
|
||||
// 透明度控制方法实现
|
||||
void ConeWave::SetRingBrightAlpha(float alpha) {
|
||||
ringBrightAlpha_ = alpha;
|
||||
// 确保着色器已经初始化
|
||||
if (!ringBrightAlphaUniform_.valid() && coneDrawable_.valid()) {
|
||||
CreateRadarShader();
|
||||
}
|
||||
|
||||
if (ringBrightAlphaUniform_.valid()) {
|
||||
ringBrightAlphaUniform_->set(alpha);
|
||||
}
|
||||
@ -228,10 +178,6 @@ void ConeWave::SetRingBrightAlpha(float alpha) {
|
||||
|
||||
void ConeWave::SetRingDarkAlpha(float alpha) {
|
||||
ringDarkAlpha_ = alpha;
|
||||
// 确保着色器已经初始化
|
||||
if (!ringDarkAlphaUniform_.valid() && coneDrawable_.valid()) {
|
||||
CreateRadarShader();
|
||||
}
|
||||
if (ringDarkAlphaUniform_.valid()) {
|
||||
ringDarkAlphaUniform_->set(alpha);
|
||||
}
|
||||
@ -240,31 +186,116 @@ void ConeWave::SetRingDarkAlpha(float alpha) {
|
||||
void ConeWave::SetConeAlpha(float alpha) {
|
||||
coneAlpha_ = alpha;
|
||||
// 更新锥形的基础颜色透明度
|
||||
if (coneDrawable_.valid()) {
|
||||
osg::Vec4 currentColor = coneDrawable_->getColor();
|
||||
currentColor.a() = alpha;
|
||||
coneDrawable_->setColor(currentColor);
|
||||
if (coneGeometry_.valid()) {
|
||||
// 通过着色器uniform来控制透明度,而不是直接设置颜色
|
||||
// 这里可以在CreateRadarShader中添加coneAlpha uniform来控制
|
||||
// 或者通过StateSet的材质属性来控制
|
||||
osg::StateSet* ss = coneGeometry_->getOrCreateStateSet();
|
||||
osg::ref_ptr<osg::Material> material = new osg::Material();
|
||||
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0.0f, 0.8f, 1.0f, alpha));
|
||||
material->setTransparency(osg::Material::FRONT_AND_BACK, 1.0f - alpha);
|
||||
ss->setAttributeAndModes(material, osg::StateAttribute::ON);
|
||||
}
|
||||
}
|
||||
|
||||
void ConeWave::Clear() {
|
||||
// 清除锥形几何体和相关uniform
|
||||
if (coneCallback_.valid()) {
|
||||
setUpdateCallback(nullptr); // 移除时间更新回调
|
||||
coneCallback_ = nullptr;
|
||||
}
|
||||
|
||||
if (coneGeometry_.valid()) {
|
||||
removeDrawable(coneGeometry_);
|
||||
coneGeometry_ = nullptr;
|
||||
coneDrawable_ = nullptr;
|
||||
}
|
||||
|
||||
waveTimeUniform_ = nullptr;
|
||||
baseColorUniform_ = nullptr;
|
||||
waveColorUniform_ = nullptr;
|
||||
levelHeightUniform_ = nullptr;
|
||||
waveSpeedUniform_ = nullptr;
|
||||
ringBrightAlphaUniform_ = nullptr;
|
||||
ringDarkAlphaUniform_ = nullptr;
|
||||
}
|
||||
|
||||
void ConeWave::Rebuild() {
|
||||
// 清除当前几何体和uniform
|
||||
Clear();
|
||||
|
||||
CreateRadarScanWave();
|
||||
}
|
||||
|
||||
void ConeWave::CreateConeGeometry() {
|
||||
// 创建锥形几何体
|
||||
osg::ref_ptr<osg::Geometry> coneGeometry = new osg::Geometry();
|
||||
|
||||
// 锥形参数
|
||||
const int segments = 64; // 圆周细分数
|
||||
const float angleStep = 2.0f * osg::PI / segments;
|
||||
|
||||
// 创建顶点数组
|
||||
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
|
||||
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array();
|
||||
osg::ref_ptr<osg::Vec2Array> texCoords = new osg::Vec2Array();
|
||||
|
||||
// 锥顶(位于原点)
|
||||
vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
|
||||
normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
|
||||
texCoords->push_back(osg::Vec2(0.5f, 0.5f));
|
||||
|
||||
// 底面圆周顶点(位于height_高度处)
|
||||
for (int i = 0; i <= segments; ++i) {
|
||||
float angle = i * angleStep;
|
||||
float x = radius_ * cos(angle);
|
||||
float y = radius_ * sin(angle);
|
||||
float z = height_;
|
||||
|
||||
// 强制更新ShapeDrawable以应用颜色变化
|
||||
coneDrawable_->dirtyDisplayList();
|
||||
vertices->push_back(osg::Vec3(x, y, z));
|
||||
|
||||
// 计算法线(从锥顶指向圆周的单位向量)
|
||||
osg::Vec3 normal(x, y, radius_);
|
||||
normal.normalize();
|
||||
normals->push_back(normal);
|
||||
|
||||
// 纹理坐标
|
||||
texCoords->push_back(osg::Vec2((x/radius_ + 1.0f) * 0.5f, (y/radius_ + 1.0f) * 0.5f));
|
||||
}
|
||||
|
||||
coneGeometry->setVertexArray(vertices);
|
||||
coneGeometry->setNormalArray(normals);
|
||||
coneGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
coneGeometry->setTexCoordArray(0, texCoords);
|
||||
|
||||
// 创建三角形索引
|
||||
osg::ref_ptr<osg::DrawElementsUInt> indices = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
|
||||
|
||||
// 生成锥面三角形
|
||||
for (int i = 0; i < segments; ++i) {
|
||||
// 每个三角形:锥顶 -> 底面点i -> 底面点i+1
|
||||
indices->push_back(0); // 锥顶
|
||||
indices->push_back(i + 1); // 底面点i
|
||||
indices->push_back(i + 2); // 底面点i+1
|
||||
}
|
||||
|
||||
coneGeometry->addPrimitiveSet(indices);
|
||||
if (coneGeometry_.valid() && coneGeometry_->getNumParents() > 0) {
|
||||
removeDrawable(coneGeometry_);
|
||||
coneGeometry_ = coneGeometry;
|
||||
coneDrawable_ = coneGeometry_.get();
|
||||
waveTimeUniform_ = nullptr;
|
||||
levelHeightUniform_ = nullptr;
|
||||
addDrawable(coneDrawable_);
|
||||
} else {
|
||||
coneGeometry_ = coneGeometry;
|
||||
coneDrawable_ = coneGeometry_.get();
|
||||
}
|
||||
}
|
||||
|
||||
void ConeWave::CreateRadarScanWave() {
|
||||
// 使用OSG内置的Cone几何体来创建雷达扫描区域
|
||||
// 创建锥形,锥形顶点在原点,开口向下(负Z方向)
|
||||
cone_ = new osg::Cone(osg::Vec3(0, 0, -height_/2), radius_, height_);
|
||||
|
||||
// 设置细分参数,创建开口锥形
|
||||
osg::TessellationHints* tesselate = new osg::TessellationHints;
|
||||
tesselate->setCreateBottom(false); // 不创建底面,保持开口
|
||||
tesselate->setCreateTop(false); // 不创建顶面
|
||||
tesselate->setCreateBackFace(false); // 不创建背面
|
||||
tesselate->setDetailRatio(2.0f); // 增加细分精度
|
||||
|
||||
// 创建可绘制对象
|
||||
coneDrawable_ = new osg::ShapeDrawable(cone_, tesselate);
|
||||
coneDrawable_->setColor(osg::Vec4(0.0f, 0.8f, 1.0f, coneAlpha_)); // 使用coneAlpha_设置基础颜色
|
||||
// 手动创建锥形几何体
|
||||
CreateConeGeometry();
|
||||
|
||||
// 添加到几何节点
|
||||
addDrawable(coneDrawable_);
|
||||
@ -286,7 +317,9 @@ void ConeWave::CreateRadarScanWave() {
|
||||
CreateRadarShader();
|
||||
|
||||
// 添加时间更新回调
|
||||
setUpdateCallback(new RadarWaveTimeCallback(waveTimeUniform_));
|
||||
osg::ref_ptr<osg::NodeCallback> waveTimeCallback = new RadarWaveTimeCallback(waveTimeUniform_);
|
||||
coneCallback_ = waveTimeCallback;
|
||||
setUpdateCallback(coneCallback_);
|
||||
}
|
||||
|
||||
void ConeWave::CreateRadarShader() {
|
||||
|
@ -22,6 +22,7 @@ public:
|
||||
|
||||
// 雷达扫描波效果相关方法
|
||||
void CreateRadarScanWave();
|
||||
void CreateConeGeometry();
|
||||
void CreateRadarShader();
|
||||
void SetWaveRadius(float radius);
|
||||
float GetWaveRadius() const { return waveRadius_; }
|
||||
@ -55,9 +56,15 @@ public:
|
||||
void SetConeAlpha(float alpha);
|
||||
float GetConeAlpha() const { return coneAlpha_; }
|
||||
|
||||
protected:
|
||||
void Clear();
|
||||
void Rebuild();
|
||||
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::Cone> cone_;
|
||||
osg::ref_ptr<osg::ShapeDrawable> coneDrawable_;
|
||||
osg::ref_ptr<osg::Geometry> coneGeometry_;
|
||||
osg::ref_ptr<osg::Drawable> coneDrawable_;
|
||||
osg::ref_ptr<osg::NodeCallback> coneCallback_;
|
||||
|
||||
float height_{ 6.0f };
|
||||
float radius_{ 10.0f };
|
||||
|
@ -112,10 +112,6 @@ void ConeWaveComponent::AddToRender() {
|
||||
void ConeWaveComponent::Initialize() {
|
||||
mt_ = new osg::MatrixTransform;
|
||||
|
||||
// 创建旋转矩阵,让锥形向下发射(绕X轴旋转180度)
|
||||
// osg::Matrix rotationMatrix = osg::Matrix::rotate(osg::PI, osg::Vec3(1, 0, 0));
|
||||
// mt_->setMatrix(rotationMatrix);
|
||||
|
||||
mt_->addChild(coneWave_);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user