mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-24 16:06:51 +08:00
86 lines
2.5 KiB
C++
86 lines
2.5 KiB
C++
// Released under the MIT License. See LICENSE for details.
|
|
|
|
#include "ballistica/scene/node/bomb_node.h"
|
|
|
|
#include "ballistica/graphics/graphics.h"
|
|
#include "ballistica/media/component/collide_model.h"
|
|
#include "ballistica/scene/scene.h"
|
|
|
|
namespace ballistica {
|
|
|
|
const float kFuseOffset = 0.35f;
|
|
|
|
// Returns noise value between 0 and 1.
|
|
// TODO(ericf): Need to interpolate between 2 values.
|
|
static auto SimpleNoise(uint32_t x) -> float {
|
|
x = (x << 13u) ^ x;
|
|
return (0.5f
|
|
* static_cast<float>((x * (x * x * 15731u + 789221u) + 1376312589u)
|
|
& 0x7fffffffu)
|
|
/ 1073741824.0f);
|
|
}
|
|
|
|
class BombNodeType : public PropNodeType {
|
|
public:
|
|
#define BA_NODE_TYPE_CLASS BombNode
|
|
BA_NODE_CREATE_CALL(CreateBomb);
|
|
BA_FLOAT_ATTR(fuse_length, fuse_length, set_fuse_length);
|
|
#undef BA_NODE_TYPE_CLASS
|
|
|
|
BombNodeType() : PropNodeType("bomb", CreateBomb), fuse_length(this) {}
|
|
};
|
|
|
|
static NodeType* node_type{};
|
|
|
|
auto BombNode::InitType() -> NodeType* {
|
|
node_type = new BombNodeType();
|
|
return node_type;
|
|
}
|
|
|
|
BombNode::BombNode(Scene* scene) : PropNode(scene, node_type) {}
|
|
|
|
void BombNode::OnCreate() {
|
|
// We can't do this in our constructor because
|
|
// it would prevent the user from setting density/etc attrs.
|
|
// (user attrs get applied after constructors fire)
|
|
SetBody("sphere");
|
|
}
|
|
|
|
void BombNode::Step() {
|
|
PropNode::Step();
|
|
if (body_.exists()) {
|
|
// Update our fuse and light position.
|
|
dVector3 fuse_tip_pos;
|
|
dGeomGetRelPointPos(body_->geom(), 0, (fuse_length_ + kFuseOffset), 0,
|
|
fuse_tip_pos);
|
|
light_translate_ = fuse_tip_pos;
|
|
light_translate_.x += body_->blend_offset().x;
|
|
light_translate_.y += body_->blend_offset().y;
|
|
light_translate_.z += body_->blend_offset().z;
|
|
#if !BA_HEADLESS_BUILD
|
|
fuse_.SetTransform(Matrix44fTranslate(0, kFuseOffset * model_scale_, 0)
|
|
* body_->GetTransform());
|
|
fuse_.SetLength(fuse_length_);
|
|
#endif // !BA_HEADLESS_BUILD
|
|
}
|
|
}
|
|
|
|
void BombNode::Draw(FrameDef* frame_def) {
|
|
#if !BA_HEADLESS_BUILD
|
|
PropNode::Draw(frame_def);
|
|
float s_scale, s_density;
|
|
shadow_.GetValues(&s_scale, &s_density);
|
|
float intensity = SimpleNoise(static_cast<uint32_t>(id() + scene()->time()))
|
|
* s_density * 0.2f;
|
|
float s = 4.0f * s_scale;
|
|
float r = 1.5f * intensity;
|
|
float g = 0.1f * intensity;
|
|
float b = 0.1f * intensity;
|
|
float a = 0.0f;
|
|
g_graphics->DrawBlotchSoft(light_translate_, s, r, g, b, a);
|
|
g_graphics->DrawBlotchSoftObj(light_translate_, s, r, g, b, a);
|
|
#endif // !BA_HEADLESS_BUILD
|
|
}
|
|
|
|
} // namespace ballistica
|