16 SceneNode::SceneNode(Object *obj)
25 SceneNode::~SceneNode()
30 void SceneNode::set_name(const char *s)
33 name = new char[strlen(s) + 1];
37 const char *SceneNode::get_name() const
42 void SceneNode::add_child(SceneNode *node)
47 if(node->parent == this) {
50 node->parent->remove_child(node);
53 children.push_back(node);
58 bool SceneNode::remove_child(SceneNode *node)
60 if(!node) return false;
62 auto it = std::find(children.begin(), children.end(), node);
63 if(it != children.end()) {
64 assert(node->parent == this);
73 int SceneNode::get_num_children() const
75 return (int)children.size();
78 SceneNode *SceneNode::get_child(int idx) const
83 SceneNode *SceneNode::get_parent() const
88 void SceneNode::add_object(Object *obj)
90 if(obj->node == this) return;
93 obj->node->remove_object(obj);
96 this->obj.push_back(obj);
100 bool SceneNode::remove_object(Object *o)
102 if(o->node != this) {
107 auto it = std::find(obj.begin(), obj.end(), o);
108 if(it == obj.end()) {
115 int SceneNode::get_num_objects() const
117 return (int)obj.size();
120 Object *SceneNode::get_object(int idx) const
125 void SceneNode::set_position(const Vec3 &pos)
130 void SceneNode::set_rotation(const Quat &rot)
135 void SceneNode::set_scaling(const Vec3 &scale)
141 const Vec3 &SceneNode::get_node_position() const
146 const Quat &SceneNode::get_node_rotation() const
151 const Vec3 &SceneNode::get_node_scaling() const
157 Vec3 SceneNode::get_position() const
159 return xform * Vec3(0, 0, 0);
162 Quat SceneNode::get_rotation() const
167 Vec3 SceneNode::get_scaling() const
169 return scale; // TODO
172 const Mat4 &SceneNode::get_matrix() const
177 const Mat4 &SceneNode::get_inv_matrix() const
183 void SceneNode::update_node(float dt)
185 xform = Mat4::identity;
186 xform.pre_translate(pos);
187 xform.pre_rotate(rot);
188 xform.pre_scale(scale);
191 xform = xform * parent->xform;
193 inv_xform = inverse(xform);
196 void SceneNode::update(float dt)
198 bool expanded = false;
201 if(parent_expanded) {
202 int flags = children.empty() ? ImGuiTreeNodeFlags_Leaf : 0;
203 expanded = ImGui::TreeNodeEx(name ? name : "<nameless node>", flags);
209 int num = children.size();
210 for(int i=0; i<num; i++) {
211 parent_expanded = expanded;
212 children[i]->update(dt);
215 if(debug_gui && expanded) {
220 void SceneNode::apply_xform()
224 // apply post-order to make sure we don't affect the children xform by our reset
226 int nchild = children.size();
227 for(int i=0; i<nchild; i++) {
228 children[i]->apply_xform();
231 int nobj = obj.size();
232 for(int i=0; i<nobj; i++) {
233 if(obj[i]->get_type() == OBJ_MESH) {
234 ObjMesh *om = (ObjMesh*)obj[i];
236 om->mesh->apply_xform(xform);
242 rot = Quat::identity;
243 scale = Vec3(1, 1, 1);
246 bool SceneNode::intersect(const Ray &ray, HitPoint *hit) const
248 Ray local_ray = inv_xform * ray;
251 nearest.dist = FLT_MAX;
252 for(size_t i=0; i<obj.size(); i++) {
253 if(obj[i]->intersect(local_ray, hit)) {
254 if(!hit) return true;
255 if(hit->dist < nearest.dist) {
257 nearest.data = (void*)this;
258 nearest.local_ray = local_ray;
263 for(size_t i=0; i<children.size(); i++) {
264 if(children[i]->intersect(ray, hit)) {
265 if(!hit) return true;
266 if(hit->dist < nearest.dist) {
272 if(nearest.dist < FLT_MAX) {