2025-01-04 04:12:51 +00:00
|
|
|
#include "effects/ConeWave.h"
|
2025-06-19 14:05:52 +00:00
|
|
|
|
2025-01-04 04:12:51 +00:00
|
|
|
#include <osg/BlendFunc>
|
|
|
|
#include <osg/Material>
|
|
|
|
#include <osg/Texture2D>
|
|
|
|
#include <osg/ShapeDrawable>
|
|
|
|
#include <osg/Group>
|
|
|
|
#include <osgViewer/Viewer>
|
|
|
|
#include <osgDB/ReadFile>
|
|
|
|
#include <osg/Shader>
|
|
|
|
#include <osg/Program>
|
|
|
|
#include <osg/Uniform>
|
2025-01-21 18:42:57 +00:00
|
|
|
#include <osg/Depth>
|
2025-06-24 15:40:11 +00:00
|
|
|
#include <osg/Cullface>
|
2025-01-21 18:42:57 +00:00
|
|
|
#include <osgEarth/Registry>
|
2025-01-04 04:12:51 +00:00
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
class WaveSurfaceCallback : public osg::NodeCallback {
|
|
|
|
public:
|
|
|
|
WaveSurfaceCallback() : timeElapsed(0.0f) {}
|
|
|
|
|
|
|
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
|
|
|
|
timeElapsed += (nv->getFrameStamp()->getSimulationTime() - SimulationTime);
|
|
|
|
|
|
|
|
// 获取并更新geometry的顶点
|
|
|
|
osg::Geode* geode = dynamic_cast<osg::Geode*>(node);
|
|
|
|
if (geode) {
|
|
|
|
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(geode->getDrawable(0));
|
|
|
|
if (geometry) {
|
|
|
|
osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
|
|
|
|
if (vertices) {
|
|
|
|
// 更新顶点位置来模拟波动
|
|
|
|
float amplitude = 2.0f;
|
|
|
|
float frequency = 1.0f;
|
|
|
|
for (unsigned int i = 0; i < vertices->size(); ++i) {
|
|
|
|
osg::Vec3f& vertex = (*vertices)[i];
|
|
|
|
vertex.z() = amplitude * sin(frequency * (vertex.x() + timeElapsed));
|
|
|
|
}
|
|
|
|
geometry->setVertexArray(vertices);
|
|
|
|
geometry->dirtyBound(); // 更新几何体边界
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 继续遍历场景图
|
|
|
|
traverse(node, nv);
|
|
|
|
SimulationTime = nv->getFrameStamp()->getSimulationTime();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
float timeElapsed;
|
|
|
|
double SimulationTime;
|
|
|
|
};
|
|
|
|
|
2025-06-22 17:49:35 +00:00
|
|
|
// 雷达扫描波时间更新回调
|
|
|
|
class RadarWaveTimeCallback : public osg::NodeCallback {
|
|
|
|
public:
|
|
|
|
RadarWaveTimeCallback(osg::ref_ptr<osg::Uniform> waveTimeUniform)
|
|
|
|
: waveTimeUniform_(waveTimeUniform), startTime_(0.0) {}
|
|
|
|
|
|
|
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
|
|
|
|
if (nv->getFrameStamp()) {
|
|
|
|
double currentTime = nv->getFrameStamp()->getSimulationTime();
|
|
|
|
if (startTime_ == 0.0) {
|
|
|
|
startTime_ = currentTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 计算经过的时间
|
|
|
|
float elapsedTime = static_cast<float>(currentTime - startTime_);
|
|
|
|
|
|
|
|
// 更新waveTime uniform
|
|
|
|
if (waveTimeUniform_.valid()) {
|
|
|
|
waveTimeUniform_->set(elapsedTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 继续遍历场景图
|
|
|
|
traverse(node, nv);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
osg::ref_ptr<osg::Uniform> waveTimeUniform_;
|
|
|
|
double startTime_;
|
|
|
|
};
|
|
|
|
|
2025-01-04 04:12:51 +00:00
|
|
|
|
|
|
|
ConeWave::ConeWave() {
|
2025-01-21 18:42:57 +00:00
|
|
|
osgEarth::Registry::shaderGenerator().run(this);
|
2025-06-22 17:49:35 +00:00
|
|
|
currentTime_ = 0.0;
|
2025-06-23 23:47:18 +00:00
|
|
|
|
|
|
|
// 确保成员变量有合理的默认值
|
|
|
|
height_ = 100.0f;
|
|
|
|
radius_ = 50.0f;
|
|
|
|
waveRadius_ = 100.0f;
|
|
|
|
waveSpeed_ = 20.0f;
|
|
|
|
waveCount_ = 3;
|
|
|
|
levelCount_ = 5;
|
|
|
|
levelHeight_ = 100.0f;
|
|
|
|
baseColor_ = osg::Vec4(0.0f, 0.8f, 1.0f, 1.0f);
|
|
|
|
waveColor_ = osg::Vec4(1.0f, 0.5f, 1.0f, 0.8f);
|
2025-06-24 15:40:11 +00:00
|
|
|
|
|
|
|
// 初始化透明度值
|
|
|
|
ringBrightAlpha_ = 0.8f;
|
|
|
|
ringDarkAlpha_ = 0.3f;
|
|
|
|
coneAlpha_ = 0.7f;
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ConeWave::~ConeWave(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::Render(double dt) {
|
2025-06-22 17:49:35 +00:00
|
|
|
// 时间更新现在由RadarWaveTimeCallback回调处理
|
|
|
|
// 这里可以处理其他需要更新的属性
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::InitGeode() {
|
2025-06-22 17:49:35 +00:00
|
|
|
CreateRadarScanWave();
|
2025-06-19 23:57:30 +00:00
|
|
|
getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
|
|
|
getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
|
|
|
|
getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
2025-06-22 17:49:35 +00:00
|
|
|
getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
2025-06-24 15:40:11 +00:00
|
|
|
setCullingActive(true);
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::Destory() {
|
|
|
|
OnDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::SetHeight(float height) {
|
|
|
|
height_ = height;
|
|
|
|
if (cone_) {
|
|
|
|
cone_->setHeight(height_);
|
|
|
|
}
|
2025-06-22 17:49:35 +00:00
|
|
|
//coneDrawable_->build();
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::SetRadius(float radius) {
|
|
|
|
radius_ = radius;
|
|
|
|
if (cone_) {
|
|
|
|
cone_->setRadius(radius);
|
|
|
|
}
|
2025-02-22 15:16:54 +00:00
|
|
|
// coneDrawable_->build();
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::SetBaseColor(const osg::Vec4& color) {
|
|
|
|
baseColor_ = color;
|
|
|
|
if (baseColorUniform_) {
|
|
|
|
baseColorUniform_->set(color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::SetLevelCount(int count) {
|
|
|
|
levelCount_ = count;
|
|
|
|
if (levelCountUniform_) {
|
|
|
|
levelCountUniform_->set(float(levelCount_));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::SetLevelHeight(float height) {
|
|
|
|
levelHeight_ = height;
|
|
|
|
if (levelHeightUniform_) {
|
|
|
|
levelHeightUniform_->set(levelHeight_);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-06-22 17:49:35 +00:00
|
|
|
// 雷达扫描波效果相关方法实现
|
|
|
|
void ConeWave::SetWaveRadius(float radius) {
|
|
|
|
waveRadius_ = radius;
|
|
|
|
if (waveRadiusUniform_.valid()) {
|
|
|
|
waveRadiusUniform_->set(radius);
|
|
|
|
}
|
|
|
|
// 更新Cone的半径以匹配扫描波半径
|
|
|
|
if (cone_.valid()) {
|
|
|
|
cone_->setRadius(radius);
|
|
|
|
// 强制更新ShapeDrawable
|
|
|
|
if (coneDrawable_.valid()) {
|
|
|
|
coneDrawable_->dirtyDisplayList();
|
|
|
|
coneDrawable_->dirtyBound();
|
2025-02-22 15:16:54 +00:00
|
|
|
}
|
|
|
|
}
|
2025-06-22 17:49:35 +00:00
|
|
|
}
|
2025-02-22 15:16:54 +00:00
|
|
|
|
2025-06-22 17:49:35 +00:00
|
|
|
void ConeWave::SetWaveSpeed(float speed) {
|
|
|
|
waveSpeed_ = speed;
|
|
|
|
if (waveSpeedUniform_.valid()) {
|
|
|
|
waveSpeedUniform_->set(speed);
|
2025-02-22 15:16:54 +00:00
|
|
|
}
|
2025-06-22 17:49:35 +00:00
|
|
|
}
|
2025-02-22 15:16:54 +00:00
|
|
|
|
2025-06-22 17:49:35 +00:00
|
|
|
void ConeWave::SetWaveCount(int count) {
|
|
|
|
waveCount_ = count;
|
|
|
|
if (waveCountUniform_.valid()) {
|
|
|
|
waveCountUniform_->set(static_cast<float>(count));
|
|
|
|
}
|
|
|
|
}
|
2025-02-22 15:16:54 +00:00
|
|
|
|
2025-06-22 17:49:35 +00:00
|
|
|
void ConeWave::SetWaveColor(const osg::Vec4& color) {
|
|
|
|
waveColor_ = color;
|
|
|
|
if (waveColorUniform_.valid()) {
|
|
|
|
waveColorUniform_->set(color);
|
|
|
|
}
|
|
|
|
}
|
2025-02-22 15:16:54 +00:00
|
|
|
|
2025-06-24 15:40:11 +00:00
|
|
|
// 透明度控制方法实现
|
|
|
|
void ConeWave::SetRingBrightAlpha(float alpha) {
|
|
|
|
ringBrightAlpha_ = alpha;
|
|
|
|
if (ringBrightAlphaUniform_.valid()) {
|
|
|
|
ringBrightAlphaUniform_->set(alpha);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::SetRingDarkAlpha(float alpha) {
|
|
|
|
ringDarkAlpha_ = alpha;
|
|
|
|
if (ringDarkAlphaUniform_.valid()) {
|
|
|
|
ringDarkAlphaUniform_->set(alpha);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::SetConeAlpha(float alpha) {
|
|
|
|
coneAlpha_ = alpha;
|
|
|
|
// 更新锥形的基础颜色透明度
|
|
|
|
if (coneDrawable_.valid()) {
|
|
|
|
osg::Vec4 currentColor = coneDrawable_->getColor();
|
|
|
|
currentColor.a() = alpha;
|
|
|
|
coneDrawable_->setColor(currentColor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-06-22 17:49:35 +00:00
|
|
|
void ConeWave::CreateRadarScanWave() {
|
|
|
|
// 使用OSG内置的Cone几何体来创建雷达扫描区域
|
2025-06-23 23:47:18 +00:00
|
|
|
cone_ = new osg::Cone(osg::Vec3(0, 0, height_/2), radius_, height_);
|
2025-06-22 17:49:35 +00:00
|
|
|
|
|
|
|
// 设置细分参数,创建更平滑的圆形底面
|
|
|
|
osg::TessellationHints* tesselate = new osg::TessellationHints;
|
|
|
|
tesselate->setCreateBottom(true); // 创建底面作为扫描面
|
2025-06-23 23:47:18 +00:00
|
|
|
tesselate->setCreateTop(true); // 创建顶面
|
2025-06-22 17:49:35 +00:00
|
|
|
tesselate->setCreateBackFace(false); // 不创建背面
|
|
|
|
tesselate->setDetailRatio(2.0f); // 增加细分精度
|
|
|
|
|
|
|
|
// 创建可绘制对象
|
|
|
|
coneDrawable_ = new osg::ShapeDrawable(cone_, tesselate);
|
2025-06-24 15:40:11 +00:00
|
|
|
coneDrawable_->setColor(osg::Vec4(0.0f, 0.8f, 1.0f, coneAlpha_)); // 使用coneAlpha_设置基础颜色
|
2025-06-22 17:49:35 +00:00
|
|
|
|
|
|
|
// 添加到几何节点
|
|
|
|
addDrawable(coneDrawable_);
|
|
|
|
|
|
|
|
// 设置渲染状态
|
|
|
|
osg::StateSet* ss = coneDrawable_->getOrCreateStateSet();
|
|
|
|
ss->setRenderBinDetails(120, "RenderBin");
|
2025-06-23 23:47:18 +00:00
|
|
|
ss->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); // 关闭面剔除以确保可见
|
|
|
|
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
2025-06-22 17:49:35 +00:00
|
|
|
|
|
|
|
// 设置混合模式
|
2025-06-23 23:47:18 +00:00
|
|
|
osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
|
2025-06-22 17:49:35 +00:00
|
|
|
ss->setAttributeAndModes(bf, osg::StateAttribute::ON);
|
|
|
|
ss->setMode(GL_BLEND, osg::StateAttribute::ON);
|
|
|
|
ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
2025-06-24 15:40:11 +00:00
|
|
|
ss->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
|
2025-06-22 17:49:35 +00:00
|
|
|
|
|
|
|
// 创建雷达扫描波着色器
|
|
|
|
CreateRadarShader();
|
|
|
|
|
|
|
|
// 添加时间更新回调
|
|
|
|
setUpdateCallback(new RadarWaveTimeCallback(waveTimeUniform_));
|
|
|
|
}
|
2025-01-04 04:12:51 +00:00
|
|
|
|
2025-06-22 17:49:35 +00:00
|
|
|
void ConeWave::CreateRadarShader() {
|
|
|
|
// 顶点着色器 - 使用简单的基于高度的条纹效果
|
|
|
|
static const char* vertexShaderSource =
|
2025-01-04 04:12:51 +00:00
|
|
|
"varying vec3 pos;\n"
|
|
|
|
"void main()\n"
|
|
|
|
"{\n"
|
2025-06-22 17:49:35 +00:00
|
|
|
" pos.x = gl_Vertex.x;\n"
|
|
|
|
" pos.y = gl_Vertex.y;\n"
|
|
|
|
" pos.z = gl_Vertex.z;\n"
|
|
|
|
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
|
|
|
|
"}\n";
|
|
|
|
|
2025-06-24 15:40:11 +00:00
|
|
|
// 片段着色器 - 可控透明度的同心圆波纹效果
|
2025-06-22 17:49:35 +00:00
|
|
|
static const char* fragmentShaderSource =
|
|
|
|
"uniform float num;\n"
|
|
|
|
"uniform float height;\n"
|
|
|
|
"uniform vec4 baseColor;\n"
|
|
|
|
"uniform float waveTime;\n"
|
2025-06-24 15:40:11 +00:00
|
|
|
"uniform float ringBrightAlpha;\n"
|
|
|
|
"uniform float ringDarkAlpha;\n"
|
2025-06-22 17:49:35 +00:00
|
|
|
"varying vec3 pos;\n"
|
|
|
|
"void main()\n"
|
|
|
|
"{\n"
|
2025-06-23 23:47:18 +00:00
|
|
|
" float h = abs(pos.z) / max(height, 1.0);\n"
|
|
|
|
" float radialDist = sqrt(pos.x * pos.x + pos.y * pos.y);\n"
|
2025-06-24 15:40:11 +00:00
|
|
|
" float wavePhase = radialDist * 3.2 - waveTime * 30.0;\n"
|
2025-06-23 23:47:18 +00:00
|
|
|
" float ripple = sin(wavePhase);\n"
|
2025-06-24 15:40:11 +00:00
|
|
|
" if (ripple > 0.3)\n"
|
2025-06-22 17:49:35 +00:00
|
|
|
" {\n"
|
2025-06-24 15:40:11 +00:00
|
|
|
" gl_FragColor = vec4(baseColor.rgb, ringBrightAlpha);\n"
|
2025-06-22 17:49:35 +00:00
|
|
|
" }\n"
|
|
|
|
" else\n"
|
|
|
|
" {\n"
|
2025-06-24 15:40:11 +00:00
|
|
|
" gl_FragColor = vec4(baseColor.rgb, ringDarkAlpha);\n"
|
2025-06-22 17:49:35 +00:00
|
|
|
" }\n"
|
|
|
|
"}\n";
|
|
|
|
/*
|
|
|
|
|
|
|
|
static const char* vertexShaderSource = {
|
|
|
|
"varying vec3 pos;\n"
|
|
|
|
"void main()\n"
|
|
|
|
"{\n"
|
|
|
|
"pos.x=gl_Vertex.x;\n"
|
|
|
|
"pos.y=gl_Vertex.y;\n"
|
|
|
|
"pos.z=gl_Vertex.z;\n"
|
|
|
|
"gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;\n"
|
|
|
|
"}\n"
|
2025-01-04 04:12:51 +00:00
|
|
|
};
|
2025-06-22 17:49:35 +00:00
|
|
|
static const char* fragmentShaderSource = {
|
2025-01-04 04:12:51 +00:00
|
|
|
"uniform float num; \n"
|
|
|
|
"uniform float height; \n"
|
2025-06-22 17:49:35 +00:00
|
|
|
"uniform vec4 waveColor;\n"
|
|
|
|
"uniform vec4 baseColor; \n"
|
2025-01-04 04:12:51 +00:00
|
|
|
"varying vec3 pos;\n"
|
|
|
|
"float Alpha = 1.0; \n"
|
|
|
|
"float f = pos.z;\n"
|
|
|
|
"uniform float osg_FrameTime;\n"
|
|
|
|
"void main()\n"
|
|
|
|
"{\n"
|
|
|
|
"if (sin(f/height*3.14*2*num+ osg_FrameTime*10) > 0)\n"
|
|
|
|
"{\n"
|
|
|
|
" Alpha = 0.8;\n"
|
|
|
|
"}\n"
|
|
|
|
"else\n"
|
|
|
|
"{\n"
|
|
|
|
" Alpha = 0.3;\n"
|
|
|
|
"}\n"
|
|
|
|
" gl_FragColor = vec4(baseColor.rgb, Alpha);\n"
|
|
|
|
"}\n "
|
|
|
|
};
|
2025-06-22 17:49:35 +00:00
|
|
|
*/
|
|
|
|
// 创建着色器
|
|
|
|
osg::ref_ptr<osg::Shader> vertexShader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource);
|
|
|
|
osg::ref_ptr<osg::Shader> fragmentShader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource);
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Program> program = new osg::Program;
|
|
|
|
program->addShader(vertexShader);
|
|
|
|
program->addShader(fragmentShader);
|
|
|
|
|
|
|
|
// 获取drawable的状态集并设置着色器程序
|
|
|
|
osg::StateSet* stateSet = coneDrawable_->getOrCreateStateSet();
|
|
|
|
stateSet->setAttributeAndModes(program, osg::StateAttribute::ON);
|
|
|
|
|
|
|
|
// 创建uniform变量
|
|
|
|
waveTimeUniform_ = new osg::Uniform("waveTime", 0.0f);
|
2025-06-23 23:47:18 +00:00
|
|
|
baseColorUniform_ = new osg::Uniform("baseColor", osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); // 绿色雷达色调
|
|
|
|
waveColorUniform_ = new osg::Uniform("waveColor", waveColor_);
|
|
|
|
levelCountUniform_ = new osg::Uniform("num", 5.0f); // 层数
|
|
|
|
levelHeightUniform_ = new osg::Uniform("height", height_ > 0 ? height_ : 100.0f); // 确保高度不为0
|
2025-06-22 17:49:35 +00:00
|
|
|
|
2025-06-24 15:40:11 +00:00
|
|
|
// 创建透明度控制uniform变量
|
|
|
|
ringBrightAlphaUniform_ = new osg::Uniform("ringBrightAlpha", ringBrightAlpha_);
|
|
|
|
ringDarkAlphaUniform_ = new osg::Uniform("ringDarkAlpha", ringDarkAlpha_);
|
|
|
|
|
2025-06-22 17:49:35 +00:00
|
|
|
stateSet->addUniform(waveTimeUniform_);
|
|
|
|
stateSet->addUniform(baseColorUniform_);
|
2025-06-24 15:40:11 +00:00
|
|
|
stateSet->addUniform(waveColorUniform_);
|
2025-06-22 17:49:35 +00:00
|
|
|
stateSet->addUniform(levelCountUniform_);
|
|
|
|
stateSet->addUniform(levelHeightUniform_);
|
2025-06-24 15:40:11 +00:00
|
|
|
stateSet->addUniform(ringBrightAlphaUniform_);
|
|
|
|
stateSet->addUniform(ringDarkAlphaUniform_);
|
2025-06-22 17:49:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::CreateTexturedCone(osg::Geode* geode) {
|
|
|
|
cone_ = new osg::Cone(osg::Vec3(0, 0, 0.), radius_, height_);
|
|
|
|
osg::TessellationHints* tesselate = new osg::TessellationHints;
|
|
|
|
tesselate->setCreateBottom(false);
|
|
|
|
tesselate->setCreateBackFace(false);
|
|
|
|
coneDrawable_ = new osg::ShapeDrawable(cone_, tesselate);
|
|
|
|
geode->addDrawable(coneDrawable_);
|
|
|
|
coneDrawable_->setColor(baseColor_);
|
|
|
|
osg::StateSet* ss = coneDrawable_->getOrCreateStateSet();
|
|
|
|
//stateset->setRenderBinDetails(120, "OSGEARTH_SCREEN_SPACE_LAYOUT_BIN");
|
|
|
|
ss->setRenderBinDetails(120, "RenderBin");
|
|
|
|
osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc();
|
|
|
|
ss->setAttributeAndModes(bf, osg::StateAttribute::ON);
|
|
|
|
ss->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
|
|
|
|
|
|
|
|
|
|
|
|
//osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();
|
|
|
|
|
|
|
|
//// 创建顶点数组
|
|
|
|
//osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
|
|
|
|
|
|
|
|
//int rows = 20, cols=20;
|
|
|
|
//for (unsigned int i = 0; i < rows; ++i) {
|
|
|
|
// for (unsigned int j = 0; j < cols; ++j) {
|
|
|
|
// // 坐标
|
|
|
|
// float x = (float)i / (rows - 1) * 100;
|
|
|
|
// float y = (float)j / (cols - 1) * 100;
|
|
|
|
// vertices->push_back(osg::Vec3f(x, y, 0.0f));
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
//geometry->setVertexArray(vertices);
|
|
|
|
|
|
|
|
//// 生成索引来连接顶点
|
|
|
|
//osg::ref_ptr<osg::DrawElementsUShort> indices = new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS);
|
|
|
|
//for (unsigned int i = 0; i < rows - 1; ++i) {
|
|
|
|
// for (unsigned int j = 0; j < cols - 1; ++j) {
|
|
|
|
// unsigned short bottomLeft = i * cols + j;
|
|
|
|
// unsigned short bottomRight = bottomLeft + 1;
|
|
|
|
// unsigned short topLeft = (i + 1) * cols + j;
|
|
|
|
// unsigned short topRight = topLeft + 1;
|
|
|
|
|
|
|
|
// indices->push_back(bottomLeft);
|
|
|
|
// indices->push_back(bottomRight);
|
|
|
|
// indices->push_back(topRight);
|
|
|
|
// indices->push_back(topLeft);
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//geometry->addPrimitiveSet(indices);
|
|
|
|
|
|
|
|
//// 创建表面颜色
|
|
|
|
//osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
|
|
|
|
//colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); // 蓝色
|
|
|
|
|
|
|
|
//geometry->setColorArray(colors);
|
|
|
|
//geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
|
|
|
|
|
|
|
|
//// 添加geometry到geode
|
|
|
|
//geode->addDrawable(geometry);
|
|
|
|
//geode->setUpdateCallback(new WaveSurfaceCallback());
|
|
|
|
//return;
|
|
|
|
|
|
|
|
static const char* vertSource = {
|
|
|
|
"#version 330\n"
|
|
|
|
"varying vec3 pos;\n"
|
|
|
|
"void main()\n"
|
|
|
|
"{\n"
|
|
|
|
"pos.x=gl_Vertex.x;\n"
|
|
|
|
"pos.y=gl_Vertex.y;\n"
|
|
|
|
"pos.z=gl_Vertex.z;\n"
|
|
|
|
"gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;\n"
|
|
|
|
"}\n"
|
|
|
|
};
|
|
|
|
static const char* fragSource = {
|
|
|
|
"#version 330\n"
|
|
|
|
"uniform float num; \n"
|
|
|
|
"uniform float height; \n"
|
|
|
|
"uniform vec4 baseColor;\n"
|
|
|
|
"varying vec3 pos;\n"
|
|
|
|
"float Alpha = 1.0; \n"
|
|
|
|
"float f = pos.z;\n"
|
|
|
|
"uniform float osg_FrameTime;\n"
|
|
|
|
"void main()\n"
|
|
|
|
"{\n"
|
|
|
|
"if (sin(f/height*3.14*2*num+ osg_FrameTime*10) > 0)\n"
|
|
|
|
"{\n"
|
|
|
|
" Alpha = 0.8;\n"
|
|
|
|
"}\n"
|
|
|
|
"else\n"
|
|
|
|
"{\n"
|
|
|
|
" Alpha = 0.3;\n"
|
|
|
|
"}\n"
|
|
|
|
" gl_FragColor = vec4(baseColor.rgb, Alpha);\n"
|
|
|
|
"}\n "
|
|
|
|
};
|
2025-01-04 04:12:51 +00:00
|
|
|
|
|
|
|
osg::ref_ptr<osg::Shader> vertexShader = new osg::Shader(osg::Shader::VERTEX);
|
|
|
|
vertexShader->setShaderSource(vertSource);
|
|
|
|
osg::ref_ptr<osg::Shader> fragmentShader = new osg::Shader(osg::Shader::FRAGMENT);
|
|
|
|
fragmentShader->setShaderSource(fragSource);
|
|
|
|
|
|
|
|
osg::StateSet* stateset = coneDrawable_->getOrCreateStateSet();
|
2025-02-22 15:16:54 +00:00
|
|
|
// osg::ref_ptr<osg::Material> mat = new osg::Material;
|
|
|
|
// //设置正面散射颜色
|
|
|
|
// mat->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0, 0.0, 0.0, 0.3));//1.0, 0.0, 0.0, 0.3
|
|
|
|
// //设置正面镜面颜色
|
|
|
|
// mat->setSpecular(osg::Material::FRONT, osg::Vec4(1.0, 0.0, 0.0, 0.3));//1.0, 0.0, 0.0, 0.3
|
|
|
|
//
|
|
|
|
// geode->getOrCreateStateSet()->setAttribute(mat);
|
|
|
|
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
|
|
|
stateset->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
|
|
|
|
// stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
|
|
|
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
|
|
|
|
|
|
|
//设置渲染顺序 仿真模型被波束遮盖 ,1000000-指的是若有1000000个Node 则此节点最后一个被渲染
|
|
|
|
// //stateset->setRenderBinDetails(120, "OSGEARTH_SCREEN_SPACE_LAYOUT_BIN");
|
|
|
|
stateset->setRenderBinDetails(10, "RenderBin");
|
2025-06-19 14:05:52 +00:00
|
|
|
osg::ref_ptr<osg::BlendFunc> blendFunc = new osg::BlendFunc();
|
|
|
|
stateset->setAttributeAndModes(blendFunc, osg::StateAttribute::ON);
|
|
|
|
osg::ref_ptr<osg::Program> program = new osg::Program();
|
|
|
|
program->addShader(vertexShader);
|
|
|
|
program->addShader(fragmentShader);
|
|
|
|
|
|
|
|
baseColorUniform_ = new osg::Uniform("baseColor", baseColor_);
|
|
|
|
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
|
|
|
|
stateset->addUniform(baseColorUniform_);
|
2025-03-13 00:42:41 +00:00
|
|
|
// // stateset->osg::ref_ptr<osg::Program> program = new osg::Program();
|
2025-06-19 14:05:52 +00:00
|
|
|
program->addShader(vertexShader);
|
|
|
|
program->addShader(fragmentShader);(program, osg::StateAttribute::ON);
|
2025-02-22 15:16:54 +00:00
|
|
|
// // stateset->setAttributeAndModes(new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false));
|
|
|
|
//
|
|
|
|
// levelCountUniform_ = new osg::Uniform("num", float(levelCount_));
|
|
|
|
// levelHeightUniform_ = new osg::Uniform("height", levelHeight_);
|
|
|
|
|
|
|
|
// stateset->addUniform(levelCountUniform_);
|
|
|
|
// stateset->addUniform(levelHeightUniform_.get());
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
2025-06-19 14:05:52 +00:00
|
|
|
/*
|
2025-02-22 15:16:54 +00:00
|
|
|
|
|
|
|
#include <osg/Geode>
|
|
|
|
#include <osg/Geometry>
|
|
|
|
#include <osg/Material>
|
|
|
|
#include <osgFX/Outline>
|
|
|
|
#include <osgFX/Scribe>
|
|
|
|
#include <osg/MatrixTransform>
|
2025-03-13 00:42:41 +00:00
|
|
|
#include <osg/Texture2D>
|
|
|
|
#include <osgDB/ReadFile>
|
2025-02-22 15:16:54 +00:00
|
|
|
|
|
|
|
#include "scene/SceneContent.h"
|
|
|
|
|
|
|
|
class WaveBeamConeCallBack : public osg::NodeCallback {
|
|
|
|
public:
|
|
|
|
WaveBeamConeCallBack();
|
|
|
|
~WaveBeamConeCallBack();
|
|
|
|
|
|
|
|
virtual void operator() (osg::Node *node, osg::NodeVisitor *nv);
|
|
|
|
public:
|
|
|
|
double m_latitude;
|
|
|
|
double m_longitude;
|
|
|
|
double m_height;
|
|
|
|
bool m_ifDynamic;
|
|
|
|
|
|
|
|
double m_angle;
|
|
|
|
double m_length;
|
|
|
|
osg::Vec4 m_color;
|
|
|
|
osg::Vec4 m_lineColor;
|
|
|
|
double m_lineWidth;
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Geode> m_geode;
|
|
|
|
osg::ref_ptr<osg::Geometry> m_geom;
|
|
|
|
osg::ref_ptr<osg::Vec4Array> m_colorArray;
|
|
|
|
osg::ref_ptr<osg::Vec3Array> m_pointVector;
|
|
|
|
osg::ref_ptr<osgFX::Scribe> m_nodeFX;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
WaveBeamConeCallBack::WaveBeamConeCallBack() {
|
|
|
|
m_latitude = 0.0;
|
|
|
|
m_longitude = 0.0;
|
|
|
|
m_height = -6371000;
|
|
|
|
m_ifDynamic = false;
|
|
|
|
|
|
|
|
m_angle = 20.0;
|
|
|
|
m_length = 100000;
|
|
|
|
m_color = osg::Vec4(1, 0, 0, 0.5);
|
|
|
|
m_lineColor = osg::Vec4(1.0, 0.0, 0.0, 1.0);
|
|
|
|
m_lineWidth = 1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
WaveBeamConeCallBack::~WaveBeamConeCallBack() {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void WaveBeamConeCallBack::operator()(osg::Node *node, osg::NodeVisitor *nv) {
|
|
|
|
if (m_ifDynamic == false)
|
|
|
|
return;
|
|
|
|
//std::cout << "WaveBeamConeCallBack info=" << m_latitude << "," << m_longitude << "," << m_height << std::endl;
|
|
|
|
osg::MatrixTransform* mtCone = dynamic_cast<osg::MatrixTransform*>(node);
|
|
|
|
if (mtCone != NULL) {
|
|
|
|
osg::MatrixTransform* mtR = dynamic_cast<osg::MatrixTransform*>(mtCone->getParent(0));
|
|
|
|
osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(mtR->getParent(0));
|
|
|
|
|
|
|
|
//osg::Matrix m = osg::computeWorldToLocal(mtCone->getParentalNodePaths().at(0));
|
|
|
|
osg::Matrix m = osg::Matrix::inverse(mt->getMatrix()*mtR->getMatrix());
|
|
|
|
osg::Matrix mTarget;
|
|
|
|
double x, y, z;
|
|
|
|
osg::EllipsoidModel em;
|
|
|
|
em.convertLatLongHeightToXYZ(osg::DegreesToRadians(m_latitude),
|
|
|
|
osg::DegreesToRadians(m_longitude),
|
|
|
|
m_height, x, y, z);
|
|
|
|
|
|
|
|
mTarget.setTrans(x, y, z);
|
|
|
|
osg::Matrix mConeRate = osg::Matrix::rotate(osg::Vec3d(0, 1, 0), (mTarget*m).getTrans());
|
|
|
|
mtCone->setMatrix(mConeRate);//mTarget*m
|
|
|
|
|
|
|
|
double length = (mTarget*m).getTrans().length();
|
|
|
|
|
|
|
|
double angle = osg::DegreesToRadians(m_angle);
|
|
|
|
double radius = std::tan(angle*0.5) * length;
|
|
|
|
int splitCount = 20;
|
|
|
|
double angleStep = osg::PI * 2.0 / splitCount;
|
2025-03-13 00:42:41 +00:00
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
for (int i = 1; i <= splitCount + 1; i++) {
|
|
|
|
double tempAngle = (i - 1)*angleStep;
|
|
|
|
osg::Vec3 pos(radius * cos(tempAngle), length, radius * sin(tempAngle) + 3);
|
|
|
|
m_pointVector->at(i) = pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pointVector->at(splitCount + 2) = osg::Vec3(0, length, 0);
|
2025-03-13 00:42:41 +00:00
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
for (int i = splitCount + 3; i <= splitCount + 3 + splitCount; i++) {
|
|
|
|
double tempAngle = (i - splitCount - 3) *angleStep;
|
|
|
|
osg::Vec3 pos(radius * cos(tempAngle), length, radius * sin(tempAngle) + 3);
|
|
|
|
m_pointVector->at(i) = pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_geom->dirtyBound();
|
|
|
|
m_geom->dirtyDisplayList();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ConeWave::ConeWave() {
|
|
|
|
}
|
|
|
|
|
|
|
|
ConeWave::~ConeWave() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::clearSelf() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::Render(double dt)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::createWaveBeamCone(osg::MatrixTransform* node, double angle, double length,
|
|
|
|
osg::Vec4 color, osg::Vec4 lineColor, double lineWidth) {
|
|
|
|
double angleD = osg::DegreesToRadians(angle);
|
|
|
|
double radius = std::tan(angleD*0.5) * length;
|
|
|
|
int splitCount = 20;
|
|
|
|
double angleStep = osg::PI * 2.0 / splitCount;
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
|
|
|
|
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
|
|
|
|
osg::ref_ptr<osg::Vec3Array> vertex = new osg::Vec3Array;
|
|
|
|
osg::ref_ptr<osg::Vec3Array> normal = new osg::Vec3Array;
|
|
|
|
osg::ref_ptr<osg::DrawElementsUInt> drawElemUInt = new osg::DrawElementsUInt(GL_TRIANGLE_FAN);
|
2025-03-13 00:42:41 +00:00
|
|
|
// osg::ref_ptr<osg::DrawElementsUInt> drawElemUInt2 = new osg::DrawElementsUInt(GL_TRIANGLE_FAN);
|
2025-02-22 15:16:54 +00:00
|
|
|
geom->setVertexArray(vertex);
|
|
|
|
geom->setNormalArray(normal);
|
|
|
|
geode->addDrawable(geom);
|
2025-03-13 00:42:41 +00:00
|
|
|
geode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
2025-02-22 15:16:54 +00:00
|
|
|
|
|
|
|
vertex->push_back(osg::Vec3(0, 0, 0));
|
|
|
|
drawElemUInt->push_back(0);
|
|
|
|
normal->push_back(osg::Vec3(0, -1, 0));
|
|
|
|
|
|
|
|
//侧面
|
|
|
|
for (int i = 0; i <= splitCount; i++) {
|
|
|
|
double tempAngle = i*angleStep;
|
2025-03-13 00:42:41 +00:00
|
|
|
osg::Vec3 pos(radius * cos(tempAngle), radius * sin(tempAngle) + 3, length);
|
2025-02-22 15:16:54 +00:00
|
|
|
vertex->push_back(osg::Vec3(pos));
|
|
|
|
|
|
|
|
pos.normalize();
|
|
|
|
normal->push_back(pos);
|
|
|
|
drawElemUInt->push_back(i + 1);
|
|
|
|
}
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
// //底面
|
|
|
|
// int indexBegin = vertex->size();
|
|
|
|
// vertex->push_back(osg::Vec3(0, length, 0));
|
|
|
|
// drawElemUInt2->push_back(indexBegin);
|
|
|
|
// normal->push_back(osg::Vec3(0, 1, 0));
|
|
|
|
// for (int i = 0; i <= splitCount; i++) {
|
|
|
|
// double tempAngle = i*angleStep;
|
|
|
|
// osg::Vec3 pos(radius * cos(tempAngle), length, radius * sin(tempAngle) + 3);
|
|
|
|
// vertex->push_back(osg::Vec3(pos));
|
|
|
|
//
|
|
|
|
// normal->push_back(osg::Vec3(0, 1, 0));
|
|
|
|
// drawElemUInt2->push_back(indexBegin + i + 1);
|
|
|
|
// }
|
2025-02-22 15:16:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
|
|
|
geom->addPrimitiveSet(drawElemUInt);
|
2025-03-13 00:42:41 +00:00
|
|
|
// geom->addPrimitiveSet(drawElemUInt2);
|
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
osg::ref_ptr<osg::Material> mat = new osg::Material;
|
|
|
|
mat->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0, 1.0, 0.0, 0.3));//1.0, 0.0, 0.0, 0.3
|
|
|
|
mat->setSpecular(osg::Material::FRONT, osg::Vec4(1.0, 0.0, 0.0, 0.3));//1.0, 0.0, 0.0, 0.3
|
2025-03-13 00:42:41 +00:00
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
geode->getOrCreateStateSet()->setAttribute(mat.get());
|
|
|
|
geode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
|
2025-03-13 00:42:41 +00:00
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
|
|
|
|
geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
|
|
|
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
2025-03-13 00:42:41 +00:00
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
geode->getOrCreateStateSet()->setRenderBinDetails(12, "RenderBin");
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::MatrixTransform> mtCone = new osg::MatrixTransform;
|
2025-03-13 00:42:41 +00:00
|
|
|
mtCone->addChild(geode);
|
|
|
|
|
|
|
|
const char* path = "D:/Project/DYTSrouce/bin/Release/resources/textures/block.png";
|
|
|
|
osg::Image* image = osgDB::readImageFile(path);
|
|
|
|
osg::ref_ptr<osg::Texture2D> pTexture2D = new osg::Texture2D;
|
|
|
|
pTexture2D->setImage(image);
|
|
|
|
pTexture2D->setWrap(osg::Texture::WRAP_S , osg::Texture::CLAMP_TO_EDGE);
|
|
|
|
pTexture2D->setWrap(osg::Texture::WRAP_T , osg::Texture::REPEAT);
|
|
|
|
pTexture2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR );
|
|
|
|
pTexture2D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
|
|
|
|
geode->getOrCreateStateSet()->setTextureAttribute(0, pTexture2D);
|
|
|
|
geode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
|
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
WaveBeamConeCallBack* coneCallBack = new WaveBeamConeCallBack;
|
|
|
|
coneCallBack->m_angle = angle;
|
|
|
|
coneCallBack->m_length = length;
|
|
|
|
coneCallBack->m_color = color;
|
|
|
|
coneCallBack->m_lineColor = lineColor;
|
|
|
|
coneCallBack->m_lineWidth = lineWidth;
|
|
|
|
|
|
|
|
coneCallBack->m_geode = geode;
|
|
|
|
coneCallBack->m_geom = geom;
|
|
|
|
coneCallBack->m_pointVector = vertex;
|
2025-03-13 00:42:41 +00:00
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
// osg::MatrixTransform* mtR = dynamic_cast<osg::MatrixTransform*>(node->getChild(0));
|
|
|
|
// osg::MatrixTransform* mtS = dynamic_cast<osg::MatrixTransform*>(mtR->getChild(0));
|
|
|
|
// mtR->addChild(mtCone);
|
|
|
|
_waveBeamCone = mtCone;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::changeWaveBeamConeTarget(double latitude, double longitude, double height, bool ifDynamic) {
|
|
|
|
WaveBeamConeCallBack* coneCallBack = dynamic_cast<WaveBeamConeCallBack*>(_waveBeamCone->getUpdateCallback());
|
|
|
|
if (coneCallBack != NULL) {
|
|
|
|
coneCallBack->m_ifDynamic = ifDynamic;
|
|
|
|
coneCallBack->m_latitude = latitude;
|
|
|
|
coneCallBack->m_longitude = longitude;
|
|
|
|
coneCallBack->m_height = height;
|
|
|
|
|
|
|
|
if (ifDynamic == false) {
|
|
|
|
osg::MatrixTransform* mtCone = _waveBeamCone;
|
|
|
|
|
|
|
|
osg::MatrixTransform* mtR = dynamic_cast<osg::MatrixTransform*>(mtCone->getParent(0));
|
|
|
|
osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(mtR->getParent(0));
|
|
|
|
|
|
|
|
//osg::Matrix m = osg::computeWorldToLocal(mtCone->getParentalNodePaths().at(0));
|
|
|
|
osg::Matrix m = osg::Matrix::inverse(mt->getMatrix()*mtR->getMatrix());
|
|
|
|
osg::Matrix mTarget;
|
|
|
|
double x, y, z;
|
|
|
|
osg::EllipsoidModel em;
|
|
|
|
em.convertLatLongHeightToXYZ(osg::DegreesToRadians(latitude),
|
|
|
|
osg::DegreesToRadians(longitude),
|
|
|
|
height, x, y, z);
|
|
|
|
|
|
|
|
mTarget.setTrans(x, y, z);
|
|
|
|
osg::Matrix mConeRate = osg::Matrix::rotate(osg::Vec3d(0, 1, 0), (mTarget*m).getTrans());
|
|
|
|
|
|
|
|
mtCone->setMatrix(mConeRate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConeWave::changeWaveBeamConeAppearance( osg::Vec4 color, osg::Vec4 lineColor, double lineWidth) {
|
|
|
|
WaveBeamConeCallBack* coneCallBack = dynamic_cast<WaveBeamConeCallBack*>(_waveBeamCone->getUpdateCallback());
|
|
|
|
if (coneCallBack != NULL) {
|
|
|
|
coneCallBack->m_color = color;
|
|
|
|
coneCallBack->m_lineColor = lineColor;
|
|
|
|
coneCallBack->m_lineWidth = lineWidth;
|
|
|
|
|
|
|
|
//创建材质对象
|
|
|
|
osg::ref_ptr<osg::Material> mat = new osg::Material;
|
|
|
|
//设置正面散射颜色
|
|
|
|
mat->setDiffuse(osg::Material::FRONT, color);//1.0, 0.0, 0.0, 0.3
|
|
|
|
//设置正面镜面颜色
|
|
|
|
mat->setSpecular(osg::Material::FRONT, color);//1.0, 0.0, 0.0, 0.3
|
|
|
|
coneCallBack->m_geode->getOrCreateStateSet()->setAttribute(mat.get());
|
|
|
|
|
|
|
|
if (lineWidth < 0.1) {
|
|
|
|
_waveBeamCone->addChild(coneCallBack->m_geode);
|
|
|
|
_waveBeamCone->removeChild(coneCallBack->m_nodeFX);
|
|
|
|
} else {
|
|
|
|
_waveBeamCone->removeChild(coneCallBack->m_geode);
|
|
|
|
_waveBeamCone->addChild(coneCallBack->m_nodeFX);
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
|
2025-02-22 15:16:54 +00:00
|
|
|
coneCallBack->m_nodeFX->setWireframeColor(lineColor);
|
2025-03-13 00:42:41 +00:00
|
|
|
coneCallBack->m_nodeFX->setWireframeLineWidth(static_cast<float>(lineWidth));
|
2025-02-22 15:16:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-06-19 14:05:52 +00:00
|
|
|
*/
|