diff --git a/code/jumpnode/jumpnode.cpp b/code/jumpnode/jumpnode.cpp index 16e258c80f..810ebdd5a6 100644 --- a/code/jumpnode/jumpnode.cpp +++ b/code/jumpnode/jumpnode.cpp @@ -18,7 +18,7 @@ SCP_list Jump_nodes; /** * Constructor for CJumpNode class, default */ -CJumpNode::CJumpNode() : m_radius(0.0f), m_modelnum(-1), m_objnum(-1), m_flags(0) +CJumpNode::CJumpNode() { gr_init_alphacolor(&m_display_color, 0, 255, 0, 255); @@ -32,7 +32,7 @@ CJumpNode::CJumpNode() : m_radius(0.0f), m_modelnum(-1), m_objnum(-1), m_flags(0 /** * Constructor for CJumpNode class, with world position argument */ -CJumpNode::CJumpNode(vec3d *position) : m_radius(0.0f), m_modelnum(-1), m_objnum(-1), m_flags(0) +CJumpNode::CJumpNode(vec3d* position) { Assert(position != NULL); @@ -43,10 +43,18 @@ CJumpNode::CJumpNode(vec3d *position) : m_radius(0.0f), m_modelnum(-1), m_objnum // Set m_modelnum and m_radius m_modelnum = model_load(NOX("subspacenode.pof"), 0, NULL, 0); - if (m_modelnum == -1) + if (m_modelnum == -1) { Warning(LOCATION, "Could not load default model for %s", m_name); - else + } else { m_radius = model_get_radius(m_modelnum); + + // set up animation in case of instrinsic_rotate + polymodel* pm = model_get(m_modelnum); + + if (pm->flags & PM_FLAG_HAS_INTRINSIC_ROTATE) { + m_polymodel_instance_num = model_create_instance(false, m_modelnum); + } + } m_pos.xyz.x = position->xyz.x; m_pos.xyz.y = position->xyz.y; @@ -59,11 +67,12 @@ CJumpNode::CJumpNode(vec3d *position) : m_radius(0.0f), m_modelnum(-1), m_objnum } CJumpNode::CJumpNode(CJumpNode&& other) SCP_NOEXCEPT - : m_radius(other.m_radius), m_modelnum(other.m_modelnum), m_objnum(other.m_objnum), m_flags(other.m_flags) + : m_radius(other.m_radius), m_modelnum(other.m_modelnum), m_objnum(other.m_objnum), m_polymodel_instance_num(other.m_polymodel_instance_num), m_flags(other.m_flags) { other.m_radius = 0.0f; other.m_modelnum = -1; other.m_objnum = -1; + other.m_polymodel_instance_num = -1; other.m_flags = 0; m_display_color = other.m_display_color; @@ -80,11 +89,13 @@ CJumpNode& CJumpNode::operator=(CJumpNode&& other) SCP_NOEXCEPT m_modelnum = other.m_modelnum; m_objnum = other.m_objnum; m_flags = other.m_flags; + m_polymodel_instance_num = other.m_polymodel_instance_num; other.m_radius = 0.0f; other.m_modelnum = -1; other.m_objnum = -1; other.m_flags = 0; + other.m_polymodel_instance_num = -1; m_display_color = other.m_display_color; m_pos = other.m_pos; @@ -162,6 +173,14 @@ vec3d *CJumpNode::GetPosition() return &m_pos; } +/* +* @return Polymodel Instance Index +*/ +int CJumpNode::GetPolymodelInstanceNum() +{ + return m_polymodel_instance_num; +} + // Settor functions for private variables /** @@ -331,6 +350,7 @@ void CJumpNode::Render(model_draw_list* scene, vec3d *pos, vec3d *view_pos) model_render_params render_info; + render_info.set_object_number(m_objnum); render_info.set_detail_level_lock(0); render_info.set_flags(mr_flags); @@ -392,6 +412,24 @@ CJumpNode *jumpnode_get_by_name(const char* name) return NULL; } +/** + * Get jump node object by the object number + * + * @param objnum to search for + * @return Jump node object pointer + */ +CJumpNode *jumpnode_get_by_objnum(int objnum) +{ + Assert(objnum > -1); + + for (CJumpNode &jnp : Jump_nodes) { + if (jnp.GetSCPObjectNumber() == objnum) + return &(jnp); + } + + return nullptr; +} + /** * Given an object, returns which jump node it's inside (if any) * diff --git a/code/jumpnode/jumpnode.h b/code/jumpnode/jumpnode.h index b6386cab33..83d11188c3 100644 --- a/code/jumpnode/jumpnode.h +++ b/code/jumpnode/jumpnode.h @@ -32,12 +32,13 @@ class CJumpNode { private: char m_name[NAME_LENGTH]; - float m_radius; + float m_radius {0.0f}; - int m_modelnum; - int m_objnum; // objnum of this jump node + int m_modelnum {-1}; + int m_objnum {-1}; // objnum of this jump node + int m_polymodel_instance_num {-1}; // polymodel instance number, used for rotations - int m_flags; + int m_flags {0}; color m_display_color; // Color node will be shown in (Default:0/255/0/255) vec3d m_pos; @@ -58,6 +59,7 @@ public: char *GetName(); int GetModelNumber(); int GetSCPObjectNumber(); + int GetPolymodelInstanceNum(); object *GetSCPObject(); color GetColor(); vec3d *GetPosition(); @@ -83,6 +85,7 @@ extern SCP_list Jump_nodes; //-----Functions----- CJumpNode *jumpnode_get_by_name(const char *name); +CJumpNode *jumpnode_get_by_objnum(int objnum); CJumpNode *jumpnode_get_which_in(object *objp); void jumpnode_render_all(); diff --git a/code/model/modelrender.cpp b/code/model/modelrender.cpp index 75c79f3867..dbb8d8c11c 100644 --- a/code/model/modelrender.cpp +++ b/code/model/modelrender.cpp @@ -19,6 +19,7 @@ #include "graphics/light.h" #include "graphics/uniforms.h" #include "io/timer.h" +#include "jumpnode/jumpnode.h" #include "math/staticrand.h" #include "mod_table/mod_table.h" #include "model/modelrender.h" @@ -2628,12 +2629,17 @@ void model_render_queue(model_render_params* interp, model_draw_list* scene, int pmi = model_get_instance(shipp->model_instance_num); } else if (pm->flags & PM_FLAG_HAS_INTRINSIC_ROTATE) { - if (objp->type == OBJ_ASTEROID) + if (objp->type == OBJ_ASTEROID) { pmi = model_get_instance(Asteroids[objp->instance].model_instance_num); - else if (objp->type == OBJ_WEAPON) + } else if (objp->type == OBJ_WEAPON) { pmi = model_get_instance(Weapons[objp->instance].model_instance_num); - else + } else if (objp->type == OBJ_JUMP_NODE) { + CJumpNode* jnp = jumpnode_get_by_objnum(objnum); + Assertion(jnp != nullptr, "Could not find jump node with object number %d!", objnum); + pmi = model_get_instance(jnp->GetPolymodelInstanceNum()); + } else { Warning(LOCATION, "Unsupported object type %d for rendering intrinsic-rotate submodels!", objp->type); + } } }