17 SceneNode::SceneNode(Object *obj)
27 SceneNode::~SceneNode()
32 void SceneNode::set_name(const char *s)
35 name = new char[strlen(s) + 1];
39 const char *SceneNode::get_name() const
44 void SceneNode::add_child(SceneNode *node)
49 if(node->parent == this) {
52 node->parent->remove_child(node);
55 children.push_back(node);
62 bool SceneNode::remove_child(SceneNode *node)
64 if(!node) return false;
66 auto it = std::find(children.begin(), children.end(), node);
67 if(it != children.end()) {
68 assert(node->parent == this);
79 int SceneNode::get_num_children() const
81 return (int)children.size();
84 SceneNode *SceneNode::get_child(int idx) const
89 SceneNode *SceneNode::get_parent() const
94 void SceneNode::add_object(Object *obj)
96 if(obj->node == this) return;
99 obj->node->remove_object(obj);
102 this->obj.push_back(obj);
108 bool SceneNode::remove_object(Object *o)
110 if(o->node != this) {
115 auto it = std::find(obj.begin(), obj.end(), o);
116 if(it == obj.end()) {
125 int SceneNode::get_num_objects() const
127 return (int)obj.size();
130 Object *SceneNode::get_object(int idx) const
135 void SceneNode::set_position(const Vec3 &pos)
140 void SceneNode::set_rotation(const Quat &rot)
145 void SceneNode::set_scaling(const Vec3 &scale)
151 const Vec3 &SceneNode::get_node_position() const
156 const Quat &SceneNode::get_node_rotation() const
161 const Vec3 &SceneNode::get_node_scaling() const
167 Vec3 SceneNode::get_position() const
169 return xform * Vec3(0, 0, 0);
172 Quat SceneNode::get_rotation() const
177 Vec3 SceneNode::get_scaling() const
179 return scale; // TODO
182 const Mat4 &SceneNode::get_matrix() const
187 const Mat4 &SceneNode::get_inv_matrix() const
193 void SceneNode::update_node(float dt)
195 xform = Mat4::identity;
196 xform.pre_translate(pos);
197 xform.pre_rotate(rot);
198 xform.pre_scale(scale);
201 xform = xform * parent->xform;
203 inv_xform = inverse(xform);
206 void SceneNode::update(float dt)
208 bool expanded = false;
211 if(parent_expanded) {
212 int flags = children.empty() ? ImGuiTreeNodeFlags_Leaf : 0;
213 expanded = ImGui::TreeNodeEx(name ? name : "<nameless node>", flags);
219 int num = children.size();
220 for(int i=0; i<num; i++) {
221 parent_expanded = expanded;
222 children[i]->update(dt);
225 if(debug_gui && expanded) {
230 void SceneNode::apply_xform()
234 // apply post-order to make sure we don't affect the children xform by our reset
236 int nchild = children.size();
237 for(int i=0; i<nchild; i++) {
238 children[i]->apply_xform();
241 int nobj = obj.size();
242 for(int i=0; i<nobj; i++) {
243 if(obj[i]->get_type() == OBJ_MESH) {
244 ObjMesh *om = (ObjMesh*)obj[i];
246 om->mesh->apply_xform(xform);
252 rot = Quat::identity;
253 scale = Vec3(1, 1, 1);
256 bool SceneNode::intersect(const Ray &ray, HitPoint *hit) const
258 Ray local_ray = inv_xform * ray;
261 nearest.dist = FLT_MAX;
262 for(size_t i=0; i<obj.size(); i++) {
263 if(obj[i]->intersect(local_ray, hit)) {
264 if(!hit) return true;
265 if(hit->dist < nearest.dist) {
267 nearest.data = (void*)this;
268 nearest.local_ray = local_ray;
273 for(size_t i=0; i<children.size(); i++) {
274 if(children[i]->intersect(ray, hit)) {
275 if(!hit) return true;
276 if(hit->dist < nearest.dist) {
282 if(nearest.dist < FLT_MAX) {
290 const Box &SceneNode::calc_bounds()
295 const Box &SceneNode::get_bounds() const
298 return ((SceneNode*)this)->calc_bounds();