Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions code/model/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -729,9 +729,13 @@ typedef struct cross_section {
#define MAX_INS_FACES 128
typedef struct insignia {
int detail_level;
vec3d position;
matrix orientation;
float diameter;
int num_faces;
int faces[MAX_INS_FACES][MAX_INS_FACE_VECS]; // indices into the vecs array
float u[MAX_INS_FACES][MAX_INS_FACE_VECS]; // u tex coords on a per-face-per-vertex basis
float v[MAX_INS_FACES][MAX_INS_FACE_VECS]; // v tex coords on a per-face-per-vertex bases
vec3d vecs[MAX_INS_VECS]; // vertex list
vec3d offset; // global position offset for this insignia
vec3d norm[MAX_INS_VECS] ; //normal of the insignia-Bobboau
} insignia;

#define PM_FLAG_ALLOW_TILING (1<<0) // Allow texture tiling
Expand Down Expand Up @@ -807,7 +811,7 @@ class polymodel
n_view_positions(0), rad(0.0f), core_radius(0.0f), n_textures(0), submodel(NULL), n_guns(0), n_missiles(0), n_docks(0),
n_thrusters(0), gun_banks(NULL), missile_banks(NULL), docking_bays(NULL), thrusters(NULL), ship_bay(NULL), shield(),
shield_collision_tree(NULL), sldc_size(0), n_paths(0), paths(NULL), mass(0), num_xc(0), xc(NULL), num_split_plane(0),
used_this_mission(0), n_glow_point_banks(0), glow_point_banks(nullptr),
num_ins(0), used_this_mission(0), n_glow_point_banks(0), glow_point_banks(nullptr),
vert_source()
{
filename[0] = 0;
Expand All @@ -820,6 +824,7 @@ class polymodel
memset(&bounding_box, 0, 8 * sizeof(vec3d));
memset(&view_positions, 0, MAX_EYES * sizeof(eye));
memset(&split_plane, 0, MAX_SPLIT_PLANE * sizeof(float));
memset(&ins, 0, MAX_MODEL_INSIGNIAS * sizeof(insignia));

#ifndef NDEBUG
ram_used = 0;
Expand Down Expand Up @@ -894,7 +899,8 @@ class polymodel
int num_split_plane; // number of split planes
float split_plane[MAX_SPLIT_PLANE]; // actual split plane z coords (for big ship explosions)

SCP_vector<insignia> ins;
insignia ins[MAX_MODEL_INSIGNIAS];
int num_ins;

#ifndef NDEBUG
int ram_used; // How much RAM this model uses
Expand Down
89 changes: 35 additions & 54 deletions code/model/modelread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1657,8 +1657,8 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename,

memset( &pm->view_positions, 0, sizeof(pm->view_positions) );

// reset insignia
pm->ins.clear();
// reset insignia counts
pm->num_ins = 0;

// reset glow points!! - Goober5000
pm->n_glow_point_banks = 0;
Expand Down Expand Up @@ -2806,80 +2806,61 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename,
}
break;

case ID_INSG: {
case ID_INSG:
int num_ins, num_verts, num_faces, idx, idx2, idx3;

// get the # of insignias
int num_ins = cfread_int(fp);
pm->ins = SCP_vector<insignia>(num_ins);
num_ins = cfread_int(fp);
pm->num_ins = num_ins;

// read in the insignias
for (int idx = 0; idx < num_ins; idx++){
insignia& ins = pm->ins[idx];

for(idx=0; idx<num_ins; idx++){
// get the detail level
ins.detail_level = cfread_int(fp);
if (ins.detail_level < 0) {
Warning(LOCATION, "Model '%s': insignia uses an invalid LOD (%i)\n", pm->filename, ins.detail_level);
pm->ins[idx].detail_level = cfread_int(fp);
if (pm->ins[idx].detail_level < 0) {
Warning(LOCATION, "Model '%s': insignia uses an invalid LOD (%i)\n", pm->filename, pm->ins[idx].detail_level);
}

// # of faces
int num_faces = cfread_int(fp);
num_faces = cfread_int(fp);
pm->ins[idx].num_faces = num_faces;
Assert(num_faces <= MAX_INS_FACES);

// # of vertices
int num_verts = cfread_int(fp);
SCP_vector<vec3d> vertices(num_verts);
num_verts = cfread_int(fp);
Assert(num_verts <= MAX_INS_VECS);

// read in all the vertices
for(int idx2 = 0; idx2 < num_verts; idx2++){
cfread_vector(&vertices[idx2], fp);
for(idx2=0; idx2<num_verts; idx2++){
cfread_vector(&pm->ins[idx].vecs[idx2], fp);
}

vec3d offset;
// read in world offset
cfread_vector(&offset, fp);

vec3d min {{{FLT_MAX, FLT_MAX, FLT_MAX}}};
vec3d max {{{-FLT_MAX, -FLT_MAX, -FLT_MAX}}};
vec3d avg_total = ZERO_VECTOR;
vec3d avg_normal = ZERO_VECTOR;
cfread_vector(&pm->ins[idx].offset, fp);

// read in all the faces
for(int idx2 = 0; idx2 < num_faces; idx2++){
std::array<int, 3> faces;
for(idx2=0; idx2<pm->ins[idx].num_faces; idx2++){
// read in 3 vertices
for(int idx3 = 0; idx3 < 3; idx3++){
faces[idx3] = cfread_int(fp);

//UV coords are no longer needed
cfread_float(fp);
cfread_float(fp);
for(idx3=0; idx3<3; idx3++){
pm->ins[idx].faces[idx2][idx3] = cfread_int(fp);
pm->ins[idx].u[idx2][idx3] = cfread_float(fp);
pm->ins[idx].v[idx2][idx3] = cfread_float(fp);
}
vec3d tempv;

const vec3d& v1 = vertices[faces[0]];
const vec3d& v2 = vertices[faces[1]];
const vec3d& v3 = vertices[faces[2]];

vec3d normal;
//get three points (rotated) and compute normal
vm_vec_perp(&normal, &v1, &v2, &v3);

vm_vec_min(&min, &min, &v1);
vm_vec_min(&min, &min, &v2);
vm_vec_min(&min, &min, &v3);
vm_vec_max(&max, &max, &v1);
vm_vec_max(&max, &max, &v2);
vm_vec_max(&max, &max, &v3);

vec3d avg = (v1 + v2 + v3) * (1.0f / 3.0f);
avg_total += avg;
avg_normal += normal;

vm_vec_perp(&tempv,
&pm->ins[idx].vecs[pm->ins[idx].faces[idx2][0]],
&pm->ins[idx].vecs[pm->ins[idx].faces[idx2][1]],
&pm->ins[idx].vecs[pm->ins[idx].faces[idx2][2]]);

vm_vec_normalize_safe(&tempv);

pm->ins[idx].norm[idx2] = tempv;
// mprintf(("insignorm %.2f %.2f %.2f\n",pm->ins[idx].norm[idx2].xyz.x, pm->ins[idx].norm[idx2].xyz.y, pm->ins[idx].norm[idx2].xyz.z));
}

ins.position = avg_total / static_cast<float>(num_faces) + offset;
vec3d bb = max - min;
ins.diameter = std::max({bb.xyz.x, bb.xyz.y, bb.xyz.z});
vm_vector_2_matrix(&ins.orientation, &avg_normal, &vmd_z_vector);
}
}
}
break;

Expand Down
139 changes: 116 additions & 23 deletions code/model/modelrender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,51 @@ void model_draw_list::render_arcs()
gr_zbuffer_set(mode);
}

void model_draw_list::add_insignia(const model_render_params *params, const polymodel *pm, int detail_level, int bitmap_num)
{
insignia_draw_data new_insignia;

new_insignia.transform = Transformations.get_transform();
new_insignia.pm = pm;
new_insignia.detail_level = detail_level;
new_insignia.bitmap_num = bitmap_num;

new_insignia.clip = params->is_clip_plane_set();
new_insignia.clip_normal = params->get_clip_plane_normal();
new_insignia.clip_position = params->get_clip_plane_pos();

Insignias.push_back(new_insignia);
}

void model_draw_list::render_insignia(const insignia_draw_data &insignia_info)
{
if ( insignia_info.clip ) {
vec3d tmp;
vec3d pos;

vm_matrix4_get_offset(&pos, &insignia_info.transform);
vm_vec_sub(&tmp, &pos, &insignia_info.clip_position);
vm_vec_normalize(&tmp);

if ( vm_vec_dot(&tmp, &insignia_info.clip_normal) < 0.0f) {
return;
}
}

g3_start_instance_matrix(&insignia_info.transform);

model_render_insignias(&insignia_info);

g3_done_instance(true);
}

void model_draw_list::render_insignias() const
{
for (const auto& ins : Insignias) {
render_insignia(ins);
}
}

void model_draw_list::add_outline(const vertex* vert_array, int n_verts, const color *clr)
{
outline_draw draw_info;
Expand Down Expand Up @@ -2382,6 +2427,74 @@ void model_queue_render_thrusters(const model_render_params *interp, const polym
}
}

void model_render_insignias(const insignia_draw_data *insignia_data)
{
auto pm = insignia_data->pm;
int detail_level = insignia_data->detail_level;
int bitmap_num = insignia_data->bitmap_num;

// if the model has no insignias, or we don't have a texture, then bail
if ( (pm->num_ins <= 0) || (bitmap_num < 0) )
return;

int idx, s_idx;
vertex vecs[3];
vec3d t1, t2, t3;
int i1, i2, i3;

material insignia_material;
insignia_material.set_depth_bias(1);

// set the proper texture
material_set_unlit(&insignia_material, bitmap_num, 0.65f, true, true);

if ( insignia_data->clip ) {
insignia_material.set_clip_plane(insignia_data->clip_normal, insignia_data->clip_position);
}

// otherwise render them
for(idx=0; idx<pm->num_ins; idx++){
// skip insignias not on our detail level
if(pm->ins[idx].detail_level != detail_level){
continue;
}

for(s_idx=0; s_idx<pm->ins[idx].num_faces; s_idx++){
// get vertex indices
i1 = pm->ins[idx].faces[s_idx][0];
i2 = pm->ins[idx].faces[s_idx][1];
i3 = pm->ins[idx].faces[s_idx][2];

// transform vecs and setup vertices
vm_vec_add(&t1, &pm->ins[idx].vecs[i1], &pm->ins[idx].offset);
vm_vec_add(&t2, &pm->ins[idx].vecs[i2], &pm->ins[idx].offset);
vm_vec_add(&t3, &pm->ins[idx].vecs[i3], &pm->ins[idx].offset);

g3_transfer_vertex(&vecs[0], &t1);
g3_transfer_vertex(&vecs[1], &t2);
g3_transfer_vertex(&vecs[2], &t3);

// setup texture coords
vecs[0].texture_position.u = pm->ins[idx].u[s_idx][0];
vecs[0].texture_position.v = pm->ins[idx].v[s_idx][0];

vecs[1].texture_position.u = pm->ins[idx].u[s_idx][1];
vecs[1].texture_position.v = pm->ins[idx].v[s_idx][1];

vecs[2].texture_position.u = pm->ins[idx].u[s_idx][2];
vecs[2].texture_position.v = pm->ins[idx].v[s_idx][2];

light_apply_rgb( &vecs[0].r, &vecs[0].g, &vecs[0].b, &pm->ins[idx].vecs[i1], &pm->ins[idx].norm[i1], 1.5f );
light_apply_rgb( &vecs[1].r, &vecs[1].g, &vecs[1].b, &pm->ins[idx].vecs[i2], &pm->ins[idx].norm[i2], 1.5f );
light_apply_rgb( &vecs[2].r, &vecs[2].g, &vecs[2].b, &pm->ins[idx].vecs[i3], &pm->ins[idx].norm[i3], 1.5f );
vecs[0].a = vecs[1].a = vecs[2].a = 255;

// draw the polygon
g3_render_primitives_colored_textured(&insignia_material, vecs, 3, PRIM_TYPE_TRIFAN, false);
}
}
}

SCP_vector<vec3d> Arc_segment_points;

void model_render_arc(const vec3d *v1, const vec3d *v2, const SCP_vector<vec3d> *persistent_arc_points, const color *primary, const color *secondary, float arc_width, ubyte depth_limit)
Expand Down Expand Up @@ -2541,6 +2654,7 @@ void model_render_immediate(const model_render_params* render_info, int model_nu
}

model_list.render_outlines();
model_list.render_insignias();
model_list.render_arcs();

gr_zbias(0);
Expand Down Expand Up @@ -2863,29 +2977,8 @@ void model_render_queue(const model_render_params* interp, model_draw_list* scen
}

// MARKED!
if ( !( model_flags & MR_NO_TEXTURING ) && !( model_flags & MR_NO_INSIGNIA) && objnum >= 0 ) {
int bitmap_num = interp->get_insignia_bitmap();
if ( (!pm->ins.empty()) && (bitmap_num >= 0) ) {

for (const auto& ins : pm->ins) {
// skip insignias not on our detail level
if (ins.detail_level != detail_level) {
continue;
}

decals::Decal decal;
decal.object = &Objects[objnum];
decal.position = ins.position;
decal.submodel = -1;
decal.scale = vec3d{{{ins.diameter, ins.diameter, ins.diameter}}};
decal.orig_obj_type = OBJ_SHIP;
decal.creation_time = f2fl(Missiontime);
decal.lifetime = 1.0f;
decal.orientation = ins.orientation;
decal.definition_handle = std::make_tuple(bitmap_num, -1, -1);
decals::addSingleFrameDecal(std::move(decal));
}
}
if ( !( model_flags & MR_NO_TEXTURING ) && !( model_flags & MR_NO_INSIGNIA) ) {
scene->add_insignia(interp, pm, detail_level, interp->get_insignia_bitmap());
}

if ( (model_flags & MR_AUTOCENTER) && (set_autocen) ) {
Expand Down
7 changes: 6 additions & 1 deletion code/model/modelrender.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,15 @@ class model_draw_list
light_indexing_info Current_lights_set;

void render_arc(const arc_effect &arc);
void render_insignia(const insignia_draw_data &insignia_info);
static void render_insignia(const insignia_draw_data &insignia_info);
void render_outline(const outline_draw &outline_info);
void render_buffer(const queued_buffer_draw &render_elements);

SCP_vector<queued_buffer_draw> Render_elements;
SCP_vector<int> Render_keys;

SCP_vector<arc_effect> Arcs;
SCP_vector<insignia_draw_data> Insignias;
SCP_vector<outline_draw> Outlines;

graphics::util::UniformBuffer _dataBuffer;
Expand Down Expand Up @@ -288,6 +289,9 @@ class model_draw_list
void add_arc(const vec3d *v1, const vec3d *v2, const SCP_vector<vec3d> *persistent_arc_points, const color *primary, const color *secondary, float arc_width, ubyte segment_depth);
void render_arcs();

void add_insignia(const model_render_params *params, const polymodel *pm, int detail_level, int bitmap_num);
void render_insignias() const;

void add_outline(const vertex* vert_array, int n_verts, const color *clr);
void render_outlines();

Expand All @@ -310,6 +314,7 @@ void submodel_render_queue(const model_render_params* render_info, model_draw_li
void model_render_buffers(model_draw_list* scene, model_material* rendering_material, const model_render_params* interp, const vertex_buffer* buffer, const polymodel* pm, int mn, int detail_level, uint tmap_flags);
bool model_render_check_detail_box(const vec3d* view_pos, const polymodel* pm, int submodel_num, uint64_t flags);
void model_render_arc(const vec3d* v1, const vec3d* v2, const SCP_vector<vec3d> *persistent_arc_points, const color* primary, const color* secondary, float arc_width, ubyte depth_limit);
void model_render_insignias(const insignia_draw_data* insignia);
void model_render_set_wireframe_color(const color* clr);
bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int y2, float zoom, bool lighting, int class_idx, const matrix* orient, const SCP_string& pof_filename = "", float closeup_zoom = 0, const vec3d* closeup_pos = &vmd_zero_vector, const SCP_string& tcolor = "");

Expand Down
1 change: 1 addition & 0 deletions code/object/objectsort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ void obj_render_queue_all()

// render electricity effects and insignias
scene.render_outlines();
scene.render_insignias();
scene.render_arcs();

gr_zbuffer_set(ZBUFFER_TYPE_READ);
Expand Down
Loading