Пример #1
0
// Returns which octant point pnt is closet to. This will always return 
// a valid octant (0-7) since the point doesn't have to be in an octant.
// If model_orient and/or model_pos are NULL, pnt is assumed to already 
// be rotated into the model's local coordinates.
// If oct is not null, it will be filled in with a pointer to the octant
// data.
int model_which_octant_distant(vec3d* pnt, int model_num, matrix* model_orient, vec3d* model_pos, model_octant** oct)
{
	polymodel* pm;
	vec3d tempv, rotpnt;

	pm = model_get(model_num);

	if (model_orient && model_pos)
	{
		// First, rotate pnt into the model's frame of reference.
		vm_vec_sub(&tempv, pnt, model_pos);
		vm_vec_rotate(&rotpnt, &tempv, model_orient);
	}
	else
	{
		rotpnt = *pnt;
	}

	vec3d center;
	vm_vec_avg(&center, &pm->mins, &pm->maxs);
	int i, x, y, z;

	if (rotpnt.xyz.x > center.xyz.x)
		x = 1;
	else
		x = 0;
	if (rotpnt.xyz.y > center.xyz.y)
		y = 1;
	else
		y = 0;
	if (rotpnt.xyz.z > center.xyz.z)
		z = 1;
	else
		z = 0;

	i = ((x << 2) | (y << 1) | z);

	if (oct)
		*oct = &pm->octants[i];

	return i;
}
Пример #2
0
static void move_object_to_position(const vobjptridx_t objp, const vms_vector &newpos)
{
	if (get_seg_masks(newpos, vcsegptr(objp->segnum), objp->size).facemask == 0)
	{
		objp->pos = newpos;
	} else {
		if (verify_object_seg(objp, newpos)) {
			int		fate;
			object	temp_viewer_obj;
			fvi_query fq;
			fvi_info	hit_info;

			temp_viewer_obj = *Viewer;
			auto viewer_segnum = find_object_seg(vobjptr(Viewer));
			temp_viewer_obj.segnum = viewer_segnum;

			//	If the viewer is outside the mine, get him in the mine!
			if (viewer_segnum == segment_none) {
				editor_status("Unable to move object, viewer not in mine.  Aborting");
				return;
#if 0
				vms_vector	last_outside_pos;
				//	While outside mine, move towards object
				count = 0;
				while (viewer_segnum == segment_none) {
					vms_vector	temp_vec;

					last_outside_pos = temp_viewer_obj.pos;

					vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, newpos);
					temp_viewer_obj.pos = temp_vec;
					viewer_segnum = find_object_seg(&temp_viewer_obj);
					temp_viewer_obj.segnum = viewer_segnum;

					if (count > 5) {
						editor_status("Unable to move object, can't get viewer in mine.  Aborting");
						return;
					}
				}

				count = 0;
				//	While inside mine, move away from object.
				while (viewer_segnum != segment_none) {

					vms_vector	temp_vec;

					vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, &last_outside_pos);
					temp_viewer_obj.pos = temp_vec;
					update_object_seg(&temp_viewer_obj);
					viewer_segnum = find_object_seg(&temp_viewer_obj);
					temp_viewer_obj.segnum = viewer_segnum;

					if (count > 5) {
						editor_status("Unable to move object, can't get viewer back out of mine.  Aborting");
						return;
					}
				}
#endif
			}

			fq.p0						= &temp_viewer_obj.pos;
			fq.startseg				= temp_viewer_obj.segnum;
			fq.p1						= &newpos;
			fq.rad					= temp_viewer_obj.size;
			fq.thisobjnum			= object_none;
			fq.ignore_obj_list.first = nullptr;
			fq.flags					= 0;

			fate = find_vector_intersection(fq, hit_info);
			if (fate == HIT_WALL) {

				objp->pos = hit_info.hit_pnt;
				const auto &&segp = find_object_seg(objp);
				if (segp != segment_none)
					obj_relink(objp, segp);
			} else {
				editor_status("Attempted to move object out of mine.  Object not moved.");
			}
		}
	}

	Update_flags |= UF_WORLD_CHANGED;
}
Пример #3
0
float g3_draw_laser_htl(vec3d* p0, float width1, vec3d* p1, float width2, int r, int g, int b, uint tmap_flags)
{
	width1 *= 0.5f;
	width2 *= 0.5f;
	vec3d uvec, fvec, rvec, center, reye;

	vm_vec_sub(&fvec, p0, p1);
	vm_vec_normalize_safe(&fvec);

	vm_vec_avg(&center, p0, p1); //needed for the return value only
	vm_vec_sub(&reye, &Eye_position, &center);
	vm_vec_normalize(&reye);

	vm_vec_crossprod(&uvec, &fvec, &reye);
	vm_vec_normalize(&uvec);
	vm_vec_crossprod(&fvec, &uvec, &reye);
	vm_vec_normalize(&fvec);

	//	if(vm_vec_mag_squared(&uvec)==0) uvec.xyz.y = 1.0f; //in case fvec is exactly equal to matrx.rvec, stick some arbitrary value in uvec
	//normalize new perpendicular vector
	//	vm_vec_normalize(&uvec);

	//now recompute right vector, in case it wasn't entirely perpendiclar
	vm_vec_crossprod(&rvec, &uvec, &fvec);

	// Now have uvec, which is up vector and rvec which is the normal
	// of the face.

	int i;
	vec3d start, end;
	vm_vec_scale_add(&start, p0, &fvec, -width1);
	vm_vec_scale_add(&end, p1, &fvec, width2);
	vec3d vecs[4];
	vertex pts[4];
	vertex* ptlist[8] =
	{
		&pts[3],
		&pts[2],
		&pts[1],
		&pts[0],
		&pts[0],
		&pts[1],
		&pts[2],
		&pts[3]
	};

	vm_vec_scale_add(&vecs[0], &start, &uvec, width1);
	vm_vec_scale_add(&vecs[1], &end, &uvec, width2);
	vm_vec_scale_add(&vecs[2], &end, &uvec, -width2);
	vm_vec_scale_add(&vecs[3], &start, &uvec, -width1);

	for (i = 0; i < 4; i++)
	{
		g3_transfer_vertex(&pts[i], &vecs[i]);
	}
	ptlist[0]->u = 0.0f;
	ptlist[0]->v = 0.0f;
	ptlist[1]->u = 1.0f;
	ptlist[1]->v = 0.0f;
	ptlist[2]->u = 1.0f;
	ptlist[2]->v = 1.0f;
	ptlist[3]->u = 0.0f;
	ptlist[3]->v = 1.0f;
	ptlist[0]->r = (ubyte)r;
	ptlist[0]->g = (ubyte)g;
	ptlist[0]->b = (ubyte)b;
	ptlist[0]->a = 255;
	ptlist[1]->r = (ubyte)r;
	ptlist[1]->g = (ubyte)g;
	ptlist[1]->b = (ubyte)b;
	ptlist[1]->a = 255;
	ptlist[2]->r = (ubyte)r;
	ptlist[2]->g = (ubyte)g;
	ptlist[2]->b = (ubyte)b;
	ptlist[2]->a = 255;
	ptlist[3]->r = (ubyte)r;
	ptlist[3]->g = (ubyte)g;
	ptlist[3]->b = (ubyte)b;
	ptlist[3]->a = 255;

	gr_tmapper(4, ptlist, tmap_flags | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);

	return center.xyz.z;
}
Пример #4
0
void batching_add_laser_internal(primitive_batch *batch, vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
{
    Assert(batch->get_render_info().prim_type == PRIM_TYPE_TRIS);

    width1 *= 0.5f;
    width2 *= 0.5f;

    vec3d uvec, fvec, rvec, center, reye;

    vm_vec_sub( &fvec, p0, p1 );
    vm_vec_normalize_safe( &fvec );

    vm_vec_avg( &center, p0, p1 ); // needed for the return value only
    vm_vec_sub(&reye, &Eye_position, &center);
    vm_vec_normalize(&reye);

    // compute the up vector
    vm_vec_cross(&uvec, &fvec, &reye);
    vm_vec_normalize_safe(&uvec);
    // ... the forward vector
    vm_vec_cross(&fvec, &uvec, &reye);
    vm_vec_normalize_safe(&fvec);
    // now recompute right vector, in case it wasn't entirely perpendiclar
    vm_vec_cross(&rvec, &uvec, &fvec);

    // Now have uvec, which is up vector and rvec which is the normal
    // of the face.

    vec3d start, end;

    vm_vec_scale_add(&start, p0, &fvec, -width1);
    vm_vec_scale_add(&end, p1, &fvec, width2);

    vec3d vecs[4];
    batch_vertex verts[6];

    vm_vec_scale_add( &vecs[0], &end, &uvec, width2 );
    vm_vec_scale_add( &vecs[1], &start, &uvec, width1 );
    vm_vec_scale_add( &vecs[2], &start, &uvec, -width1 );
    vm_vec_scale_add( &vecs[3], &end, &uvec, -width2 );

    verts[0].position = vecs[0];
    verts[1].position = vecs[1];
    verts[2].position = vecs[2];

    verts[3].position = vecs[0];
    verts[4].position = vecs[2];
    verts[5].position = vecs[3];

    verts[0].tex_coord.u = 1.0f;
    verts[0].tex_coord.v = 0.0f;
    verts[1].tex_coord.u = 0.0f;
    verts[1].tex_coord.v = 0.0f;
    verts[2].tex_coord.u = 0.0f;
    verts[2].tex_coord.v = 1.0f;

    verts[3].tex_coord.u = 1.0f;
    verts[3].tex_coord.v = 0.0f;
    verts[4].tex_coord.u = 0.0f;
    verts[4].tex_coord.v = 1.0f;
    verts[5].tex_coord.u = 1.0f;
    verts[5].tex_coord.v = 1.0f;

    verts[0].r = (ubyte)r;
    verts[0].g = (ubyte)g;
    verts[0].b = (ubyte)b;
    verts[0].a = 255;
    verts[1].r = (ubyte)r;
    verts[1].g = (ubyte)g;
    verts[1].b = (ubyte)b;
    verts[1].a = 255;
    verts[2].r = (ubyte)r;
    verts[2].g = (ubyte)g;
    verts[2].b = (ubyte)b;
    verts[2].a = 255;
    verts[3].r = (ubyte)r;
    verts[3].g = (ubyte)g;
    verts[3].b = (ubyte)b;
    verts[3].a = 255;
    verts[4].r = (ubyte)r;
    verts[4].g = (ubyte)g;
    verts[4].b = (ubyte)b;
    verts[4].a = 255;
    verts[5].r = (ubyte)r;
    verts[5].g = (ubyte)g;
    verts[5].b = (ubyte)b;
    verts[5].a = 255;

    batch->add_triangle(&verts[0], &verts[1], &verts[2]);
    batch->add_triangle(&verts[3], &verts[4], &verts[5]);
}
Пример #5
0
void move_object_to_position(int objnum, vms_vector *newpos)
{
	object	*objp = &Objects[objnum];

	segmasks	result = get_seg_masks(newpos, objp->segnum, objp->size);

	if (result.facemask == 0) {
		//mprintf((0, "Object #%i moved from (%7.3f %7.3f %7.3f) to (%7.3f %7.3f %7.3f)\n", objnum, f2fl(objp->pos.x), f2fl(objp->pos.y), f2fl(objp->pos.z), f2fl(newpos->x), f2fl(newpos->y), f2fl(newpos->z)));
		objp->pos = *newpos;
	} else {
		if (verify_object_seg(&Objects[objnum], newpos)) {
			int		fate, count;
			int		viewer_segnum;
			object	temp_viewer_obj;
			fvi_query fq;
			fvi_info	hit_info;
			vms_vector	last_outside_pos;
			vms_vector	last_inside_pos;

			temp_viewer_obj = *Viewer;
			viewer_segnum = find_object_seg(&temp_viewer_obj);
			temp_viewer_obj.segnum = viewer_segnum;

			//	If the viewer is outside the mine, get him in the mine!
			if (viewer_segnum == -1) {
				//	While outside mine, move towards object
				count = 0;
				while (viewer_segnum == -1) {
					vms_vector	temp_vec;

					//mprintf((0, "[towards %7.3f %7.3f %7.3f]\n", f2fl(temp_viewer_obj.pos.x), f2fl(temp_viewer_obj.pos.y), f2fl(temp_viewer_obj.pos.z)));
					last_outside_pos = temp_viewer_obj.pos;

					vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, newpos);
					temp_viewer_obj.pos = temp_vec;
					viewer_segnum = find_object_seg(&temp_viewer_obj);
					temp_viewer_obj.segnum = viewer_segnum;

					if (count > 5) {
						editor_status("Unable to move object, can't get viewer in mine.  Aborting");
						return;
					}
				}

				count = 0;
				//	While inside mine, move away from object.
				while (viewer_segnum != -1) {

					vms_vector	temp_vec;

					//mprintf((0, "[away %7.3f %7.3f %7.3f]\n", f2fl(temp_viewer_obj.pos.x), f2fl(temp_viewer_obj.pos.y), f2fl(temp_viewer_obj.pos.z)));
					last_inside_pos = temp_viewer_obj.pos;

					vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, &last_outside_pos);
					temp_viewer_obj.pos = temp_vec;
					update_object_seg(&temp_viewer_obj);
					viewer_segnum = find_object_seg(&temp_viewer_obj);
					temp_viewer_obj.segnum = viewer_segnum;

					if (count > 5) {
						editor_status("Unable to move object, can't get viewer back out of mine.  Aborting");
						return;
					}
				}
			}

			fq.p0						= &temp_viewer_obj.pos;
			fq.startseg				= temp_viewer_obj.segnum;
			fq.p1						= newpos;
			fq.rad					= temp_viewer_obj.size;
			fq.thisobjnum			= -1;
			fq.ignore_obj_list	= NULL;
			fq.flags					= 0;

			fate = find_vector_intersection(&fq,&hit_info);
			if (fate == HIT_WALL) {
				int	new_segnum;

				//mprintf((0, "Hit wall seg:side = %i:%i, point = (%7.3f %7.3f %7.3f)\n", hit_info.hit_seg, hit_info.hit_side, f2fl(hit_info.hit_pnt.x), f2fl(hit_info.hit_pnt.y), f2fl(hit_info.hit_pnt.z)));
				objp->pos = hit_info.hit_pnt;
				new_segnum = find_object_seg(objp);
				Assert(new_segnum != -1);
				obj_relink(objp-Objects, new_segnum);
				//mprintf((0, "Object moved from segment %i to %i\n", old_segnum, objp->segnum));
			} else {
				editor_status("Attempted to move object out of mine.  Object not moved.");
				//mprintf((0,"Attempted to move object out of mine.  Object not moved."));
			}
		}
	}

	Update_flags |= UF_WORLD_CHANGED;
}
void briefing_editor_dlg::OnMakeIcon() 
{
	char *name;
	int z, len, team, ship, waypoint, count = -1;
	int cargo = 0, cargo_count = 0, freighter_count = 0;
	object *ptr;
	vec3d min, max, pos;
	brief_icon *iconp;

	if (Briefing->stages[m_cur_stage].num_icons >= MAX_STAGE_ICONS)
		return;

	m_cur_icon = Briefing->stages[m_cur_stage].num_icons++;
	iconp = &Briefing->stages[m_cur_stage].icons[m_cur_icon];
	ship = waypoint = -1;
	team = 0;
	jump_node *jnp = NULL;

	vm_vec_make(&min, 9e19f, 9e19f, 9e19f);
	vm_vec_make(&max, -9e19f, -9e19f, -9e19f);
	ptr = GET_FIRST(&obj_used_list);
	while (ptr != END_OF_LIST(&obj_used_list)) {
		if (ptr->flags & OF_MARKED) {
			if (ptr->pos.xyz.x < min.xyz.x)
				min.xyz.x = ptr->pos.xyz.x;
			if (ptr->pos.xyz.x > max.xyz.x)
				max.xyz.x = ptr->pos.xyz.x;
			if (ptr->pos.xyz.y < min.xyz.y)
				min.xyz.y = ptr->pos.xyz.y;
			if (ptr->pos.xyz.y > max.xyz.y)
				max.xyz.y = ptr->pos.xyz.y;
			if (ptr->pos.xyz.z < min.xyz.z)
				min.xyz.z = ptr->pos.xyz.z;
			if (ptr->pos.xyz.z > max.xyz.z)
				max.xyz.z = ptr->pos.xyz.z;
			
			switch (ptr->type) {
				case OBJ_SHIP:
				case OBJ_START:
					ship = ptr->instance;
					break;

				case OBJ_WAYPOINT:
					waypoint = ptr->instance;
					break;
				
				case OBJ_JUMP_NODE:
					jnp = ptr->jnp;
					break;

				default:
					Int3();
			}

			if (ship >= 0) {
				team = Ships[ship].team;

				z = ship_query_general_type(ship);
				if (Ship_info[Ships[ship].ship_info_index].flags & SIF_CARGO)
					cargo_count++;

				if (Ship_info[Ships[ship].ship_info_index].flags & SIF_FREIGHTER)
				{
					// direct docked with any marked cargo?
					for (dock_instance *dock_ptr = ptr->dock_list; dock_ptr != NULL; dock_ptr = dock_ptr->next)
					{
						if (dock_ptr->docked_objp->flags & OF_MARKED)
						{
							if (Ship_info[Ships[dock_ptr->docked_objp->instance].ship_info_index].flags & SIF_CARGO)
								freighter_count++;
						}
					}
				}
			}

			count++;
		}

		ptr = GET_NEXT(ptr);
	}

	if (cargo_count && cargo_count == freighter_count)
		cargo = 1;

	vm_vec_avg(&pos, &min, &max);
	if (ship >= 0)
		name = Ships[ship].ship_name;
	else if (waypoint >= 0)
		name = Waypoint_lists[waypoint / 65536].name;
	else if (jnp != NULL)
		name = jnp->get_name_ptr();
	else
		return;

	len = strlen(name);
	if (len >= MAX_LABEL_LEN - 1)
		len = MAX_LABEL_LEN - 1;

	strncpy(iconp->label, name, len);
	iconp->label[len] = 0;
//	iconp->text[0] = 0;
	iconp->type = 0;
	iconp->team = team;
	iconp->pos = pos;
	iconp->flags = 0;
	iconp->id = Cur_brief_id++;
	if (ship >= 0) {
		iconp->ship_class = Ships[ship].ship_info_index;
		switch (Ship_info[Ships[ship].ship_info_index].flags & SIF_ALL_SHIP_TYPES) {
			case SIF_KNOSSOS_DEVICE:
				iconp->type = ICON_KNOSSOS_DEVICE;
				break;

			case SIF_CORVETTE:
				iconp->type = ICON_CORVETTE;
				break;

			case SIF_GAS_MINER:
				iconp->type = ICON_GAS_MINER;
				break;

			case SIF_SUPERCAP:
				iconp->type = ICON_SUPERCAP;
				break;

			case SIF_SENTRYGUN:
				iconp->type = ICON_SENTRYGUN;
				break;

			case SIF_AWACS:
				iconp->type = ICON_AWACS;
				break;

			case SIF_CARGO:
				if (cargo)
					iconp->type = (count == 1) ? ICON_FREIGHTER_WITH_CARGO : ICON_FREIGHTER_WING_WITH_CARGO;
				else
					iconp->type = count ? ICON_CARGO_WING : ICON_CARGO;

				break;

			case SIF_SUPPORT:
				iconp->type = ICON_SUPPORT_SHIP;
				break;

			case SIF_FIGHTER:
				iconp->type = count ? ICON_FIGHTER_WING : ICON_FIGHTER;
				break;

			case SIF_BOMBER:
				iconp->type = count ? ICON_BOMBER_WING : ICON_BOMBER;
				break;

			case SIF_FREIGHTER:
				if (cargo)
					iconp->type = (count == 1) ? ICON_FREIGHTER_WITH_CARGO : ICON_FREIGHTER_WING_WITH_CARGO;
				else
					iconp->type = count ? ICON_FREIGHTER_WING_NO_CARGO : ICON_FREIGHTER_NO_CARGO;

				break;

			case SIF_CRUISER:
				iconp->type = count ? ICON_CRUISER_WING : ICON_CRUISER;
				break;

			case SIF_TRANSPORT:
				iconp->type = count ? ICON_TRANSPORT_WING : ICON_TRANSPORT;
				break;

			case SIF_CAPITAL:			
			case SIF_DRYDOCK:
				iconp->type = ICON_CAPITAL;
				break;			

			case SIF_NAVBUOY:
				iconp->type = ICON_WAYPOINT;
				break;

			default:
				iconp->type = ICON_ASTEROID_FIELD;
				break;
		}
	}
	// jumpnodes
	else if(jnp != NULL){
		// find the first navbuoy
		iconp->ship_class = -1;
		for (int i = 0; i < Num_ship_classes; i++)
		{
			if (Ship_info[i].flags & SIF_NAVBUOY)
			{
				iconp->ship_class = i;
				break;
			}
		}
		iconp->type = ICON_JUMP_NODE;
	} 
	// everything else
	else {
		// find the first navbuoy
		iconp->ship_class = -1;
		for (int i = 0; i < Num_ship_classes; i++)
		{
			if (Ship_info[i].flags & SIF_NAVBUOY)
			{
				iconp->ship_class = i;
				break;
			}
		}
		iconp->type = ICON_WAYPOINT;
	}

	if (!m_change_local){
		propagate_icon(m_cur_icon);
	}

	icon_obj[m_cur_icon] = obj_create(OBJ_POINT, -1, m_cur_icon, NULL, &pos, 0.0f, OF_RENDERS);
	Assert(icon_obj[m_cur_icon] >= 0);
	obj_merge_created_list();
	unmark_all();
	set_cur_object_index(icon_obj[m_cur_icon]);
	GetDlgItem(IDC_MAKE_ICON) -> EnableWindow(FALSE);
	GetDlgItem(IDC_PROPAGATE_ICONS) -> EnableWindow(TRUE);
	update_data(1);
}
Пример #7
0
float geometry_batcher::draw_laser(vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
{
	width1 *= 0.5f;
	width2 *= 0.5f;

	vec3d uvec, fvec, rvec, center, reye;

	vm_vec_sub( &fvec, p0, p1 );
	vm_vec_normalize_safe( &fvec );

	vm_vec_avg( &center, p0, p1 ); // needed for the return value only
	vm_vec_sub(&reye, &Eye_position, &center);
	vm_vec_normalize(&reye);

	// compute the up vector
	vm_vec_cross(&uvec, &fvec, &reye);
	vm_vec_normalize_safe(&uvec);
	// ... the forward vector
	vm_vec_cross(&fvec, &uvec, &reye);
	vm_vec_normalize_safe(&fvec);
	// now recompute right vector, in case it wasn't entirely perpendiclar
	vm_vec_cross(&rvec, &uvec, &fvec);

	// Now have uvec, which is up vector and rvec which is the normal
	// of the face.

	vec3d start, end;

	vm_vec_scale_add(&start, p0, &fvec, -width1);
	vm_vec_scale_add(&end, p1, &fvec, width2);

	vec3d vecs[4];

	vertex *pts = &vert[n_to_render * 3];

	vm_vec_scale_add( &vecs[0], &end, &uvec, width2 );
	vm_vec_scale_add( &vecs[1], &start, &uvec, width1 );
	vm_vec_scale_add( &vecs[2], &start, &uvec, -width1 );
	vm_vec_scale_add( &vecs[3], &end, &uvec, -width2 );

	g3_transfer_vertex( &pts[0], &vecs[0] );
	g3_transfer_vertex( &pts[1], &vecs[1] );
	g3_transfer_vertex( &pts[2], &vecs[2] );

	g3_transfer_vertex( &pts[3], &vecs[0] );
	g3_transfer_vertex( &pts[4], &vecs[2] );
	g3_transfer_vertex( &pts[5], &vecs[3] );

	pts[0].texture_position.u = 1.0f;
	pts[0].texture_position.v = 0.0f;
	pts[1].texture_position.u = 0.0f;
	pts[1].texture_position.v = 0.0f;
	pts[2].texture_position.u = 0.0f;
	pts[2].texture_position.v = 1.0f;

	pts[3].texture_position.u = 1.0f;
	pts[3].texture_position.v = 0.0f;
	pts[4].texture_position.u = 0.0f;
	pts[4].texture_position.v = 1.0f;
	pts[5].texture_position.u = 1.0f;
	pts[5].texture_position.v = 1.0f;

	pts[0].r = (ubyte)r;
	pts[0].g = (ubyte)g;
	pts[0].b = (ubyte)b;
	pts[0].a = 255;
	pts[1].r = (ubyte)r;
	pts[1].g = (ubyte)g;
	pts[1].b = (ubyte)b;
	pts[1].a = 255;
	pts[2].r = (ubyte)r;
	pts[2].g = (ubyte)g;
	pts[2].b = (ubyte)b;
	pts[2].a = 255;
	pts[3].r = (ubyte)r;
	pts[3].g = (ubyte)g;
	pts[3].b = (ubyte)b;
	pts[3].a = 255;
	pts[4].r = (ubyte)r;
	pts[4].g = (ubyte)g;
	pts[4].b = (ubyte)b;
	pts[4].a = 255;
	pts[5].r = (ubyte)r;
	pts[5].g = (ubyte)g;
	pts[5].b = (ubyte)b;
	pts[5].a = 255;


	n_to_render += 2;
	use_radius = false;

	return center.xyz.z;
}
Пример #8
0
void draw_polygon_model(vms_vector *pos,vms_matrix *orient,vms_angvec *anim_angles,int model_num,int flags,g3s_lrgb light,fix *glow_values,bitmap_index alt_textures[])
{
	polymodel *po;
	int i;

	if (model_num < 0)
		return;

	Assert(model_num < N_polygon_models);

	po=&Polygon_models[model_num];

	//check if should use simple model
	if (po->simpler_model )					//must have a simpler model
		if (flags==0)							//can't switch if this is debris
			//!!if (!alt_textures) {				//alternate textures might not match
			//alt textures might not match, but in the one case we're using this
			//for on 11/14/94, they do match.  So we leave it in.
			{
				int cnt=1;
				fix depth;
	
				depth = g3_calc_point_depth(pos);		//gets 3d depth

				while (po->simpler_model && depth > cnt++ * Simple_model_threshhold_scale * po->rad)
					po = &Polygon_models[po->simpler_model-1];
			}

	if (alt_textures)
		for (i=0;i<po->n_textures;i++)	{
			texture_list_index[i] = alt_textures[i];
			texture_list[i] = &GameBitmaps[alt_textures[i].index];
		}
	else
		for (i=0;i<po->n_textures;i++)	{
			texture_list_index[i] = ObjBitmaps[ObjBitmapPtrs[po->first_texture+i]];
			texture_list[i] = &GameBitmaps[ObjBitmaps[ObjBitmapPtrs[po->first_texture+i]].index];
		}

	// Make sure the textures for this object are paged in...
	piggy_page_flushed = 0;
	for (i=0;i<po->n_textures;i++)	
		PIGGY_PAGE_IN( texture_list_index[i] );
	// Hmmm... cache got flushed in the middle of paging all these in,
	// so we need to reread them all in.
	if (piggy_page_flushed)	{
		piggy_page_flushed = 0;
		for (i=0;i<po->n_textures;i++)	
			PIGGY_PAGE_IN( texture_list_index[i] );
	}
	// Make sure that they can all fit in memory.
	Assert( piggy_page_flushed == 0 );

	g3_start_instance_matrix(pos,orient);

	g3_set_interp_points(robot_points);

	if (flags == 0)		//draw entire object

		g3_draw_polygon_model(po->model_data,texture_list,anim_angles,light,glow_values);

	else {
		int i;
	
		for (i=0;flags;flags>>=1,i++)
			if (flags & 1) {
				vms_vector ofs;

				Assert(i < po->n_models);

				//if submodel, rotate around its center point, not pivot point
	
				vm_vec_avg(&ofs,&po->submodel_mins[i],&po->submodel_maxs[i]);
				vm_vec_negate(&ofs);
				g3_start_instance_matrix(&ofs,NULL);
	
				g3_draw_polygon_model(&po->model_data[po->submodel_ptrs[i]],texture_list,anim_angles,light,glow_values);
	
				g3_done_instance();
			}	
	}

	g3_done_instance();

}
float g3_draw_laser_htl(vec3d *p0,float width1,vec3d *p1,float width2, int r, int g, int b, uint tmap_flags)
{
	width1 *= 0.5f;
	width2 *= 0.5f;
	vec3d uvec, fvec, rvec, center, reye, rfvec;

	vm_vec_sub( &fvec, p0, p1 );
	vm_vec_normalize_safe( &fvec );
	vm_vec_copy_scale(&rfvec, &fvec, -1.0f);

	vm_vec_avg( &center, p0, p1 ); //needed for the return value only
	vm_vec_sub(&reye, &Eye_position, &center);
	vm_vec_normalize(&reye);

	// code intended to prevent possible null vector normalize issue - start
	if (vm_test_parallel(&reye,&fvec)){
		fvec.xyz.x = -reye.xyz.z;
		fvec.xyz.y = 0.0f;
		fvec.xyz.z = -reye.xyz.x;
	}

	if (vm_test_parallel(&reye,&rfvec)){
		fvec.xyz.x = reye.xyz.z;
		fvec.xyz.y = 0.0f;
		fvec.xyz.z = reye.xyz.x;
	}
	// code intended to prevent possible null vector normalize issue - end

	vm_vec_crossprod(&uvec,&fvec,&reye);
	vm_vec_normalize(&uvec);
	vm_vec_crossprod(&fvec,&uvec,&reye);
	vm_vec_normalize(&fvec);
	 
	//now recompute right vector, in case it wasn't entirely perpendiclar
	vm_vec_crossprod(&rvec,&uvec,&fvec);

	// Now have uvec, which is up vector and rvec which is the normal
	// of the face.

	int i;
	vec3d start, end;
	vm_vec_scale_add(&start, p0, &fvec, -width1);
	vm_vec_scale_add(&end, p1, &fvec, width2);
	vec3d vecs[4];
	vertex pts[4];
	vertex *ptlist[8] = 
	{ &pts[3], &pts[2], &pts[1], &pts[0], 
	  &pts[0], &pts[1], &pts[2], &pts[3]};

	vm_vec_scale_add( &vecs[0], &start, &uvec, width1 );
	vm_vec_scale_add( &vecs[1], &end, &uvec, width2 );
	vm_vec_scale_add( &vecs[2], &end, &uvec, -width2 );
	vm_vec_scale_add( &vecs[3], &start, &uvec, -width1 );

	for (i=0; i<4; i++ )	{
		g3_transfer_vertex( &pts[i], &vecs[i] );
	}
	ptlist[0]->texture_position.u = 0.0f;
	ptlist[0]->texture_position.v = 0.0f;
	ptlist[1]->texture_position.u = 1.0f;
	ptlist[1]->texture_position.v = 0.0f;
	ptlist[2]->texture_position.u = 1.0f;
	ptlist[2]->texture_position.v = 1.0f;
	ptlist[3]->texture_position.u = 0.0f;
	ptlist[3]->texture_position.v = 1.0f;
	ptlist[0]->r = (ubyte)r;
	ptlist[0]->g = (ubyte)g;
	ptlist[0]->b = (ubyte)b;
	ptlist[0]->a = 255;
	ptlist[1]->r = (ubyte)r;
	ptlist[1]->g = (ubyte)g;
	ptlist[1]->b = (ubyte)b;
	ptlist[1]->a = 255;
	ptlist[2]->r = (ubyte)r;
	ptlist[2]->g = (ubyte)g;
	ptlist[2]->b = (ubyte)b;
	ptlist[2]->a = 255;
	ptlist[3]->r = (ubyte)r;
	ptlist[3]->g = (ubyte)g;
	ptlist[3]->b = (ubyte)b;
	ptlist[3]->a = 255;

	gr_tmapper(4, ptlist,tmap_flags | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);
	
	return center.xyz.z;
}
Пример #10
0
void trail_render( trail * trailp )
{
	int sections[NUM_TRAIL_SECTIONS];
	int num_sections = 0;
	int i;
	vec3d topv, botv, *fvec, last_pos, tmp_fvec;
	vertex  top, bot;
	int nv = 0;
	float w;
	ubyte l;
	vec3d centerv;

	if (trailp->tail == trailp->head)
		return;

	// if this trail is on the player ship, and he's in any padlock view except rear view, don't draw	
	if ( (Player_ship != NULL) && trail_is_on_ship(trailp, Player_ship) &&
		(Viewer_mode & (VM_PADLOCK_UP | VM_PADLOCK_LEFT | VM_PADLOCK_RIGHT)) )
	{
		return;
	}

	trail_info *ti	= &trailp->info;

	int n = trailp->tail;

	do	{
		n--;

		if (n < 0)
			n = NUM_TRAIL_SECTIONS-1;

		if (trailp->val[n] > 1.0f)
			break;

		sections[num_sections++] = n;
	} while ( n != trailp->head );

	if (num_sections <= 0)
		return;

	Assertion(ti->texture.bitmap_id != -1, "Weapon trail %s could not be loaded", ti->texture.filename); // We can leave this as an assert, but tell them how to fix it. --Chief

	memset( &top, 0, sizeof(vertex) );
	memset( &bot, 0, sizeof(vertex) );

	// it's a tristrip, so allocate for 2+1
	allocate_trail_verts((num_sections * 2) + 1);

	float w_size = (ti->w_end - ti->w_start);
	float a_size = (ti->a_end - ti->a_start);
	int num_faded_sections = ti->n_fade_out_sections;

	for (i = 0; i < num_sections; i++) {
		n = sections[i];
		float init_fade_out = 1.0f;

		if ((num_faded_sections > 0) && (i < num_faded_sections)) {
			init_fade_out = ((float) i) / (float) num_faded_sections;
		}

		w = trailp->val[n] * w_size + ti->w_start;
		if (init_fade_out != 1.0f) {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f * init_fade_out * init_fade_out);
		} else {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f);
		}

		if ( i == 0 )	{
			if ( num_sections > 1 )	{
				vm_vec_sub(&tmp_fvec, &trailp->pos[n], &trailp->pos[sections[i+1]] );
				vm_vec_normalize_safe(&tmp_fvec);
				fvec = &tmp_fvec;
			} else {
				fvec = &tmp_fvec;
				fvec->xyz.x = 0.0f;
				fvec->xyz.y = 0.0f;
				fvec->xyz.z = 1.0f;
			}
		} else {
			vm_vec_sub(&tmp_fvec, &last_pos, &trailp->pos[n] );
			vm_vec_normalize_safe(&tmp_fvec);
			fvec = &tmp_fvec;
		}

		trail_calc_facing_pts( &topv, &botv, fvec, &trailp->pos[n], w );

		if ( !Cmdline_nohtl ) {
			g3_transfer_vertex( &top, &topv );
			g3_transfer_vertex( &bot, &botv );
		} else {
			g3_rotate_vertex( &top, &topv );
			g3_rotate_vertex( &bot, &botv );
		}

		top.a = bot.a = l;	

		if (i > 0) {
			float U = i2fl(i);

			if (i == num_sections-1) {
				// Last one...
				vm_vec_avg( &centerv, &topv, &botv );

				if ( !Cmdline_nohtl )
					g3_transfer_vertex( &Trail_v_list[nv+2], &centerv );
				else
					g3_rotate_vertex( &Trail_v_list[nv+2], &centerv );

				Trail_v_list[nv].a = l;	

				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 1.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;

				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 0.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;

				Trail_v_list[nv].texture_position.u = U + 1.0f;
				Trail_v_list[nv].texture_position.v = 0.5f;
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = 0;
				nv++;
			} else {
				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 1.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;

				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 0.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;
			}
		}

		last_pos = trailp->pos[n];
		Trail_v_list[nv] = top;
		Trail_v_list[nv+1] = bot;
	}

	if ( !nv )
		return;

	if (nv < 3)
		Error( LOCATION, "too few verts in trail render\n" );

	// there should always be three verts in the last section and 2 everyware else, therefore there should always be an odd number of verts
	if ( (nv % 2) != 1 )
		Warning( LOCATION, "even number of verts in trail render\n" );

	profile_begin("Trail Draw");
	gr_set_bitmap( ti->texture.bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
	gr_render(nv, Trail_v_list, TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT | TMAP_FLAG_TRISTRIP);
	profile_end("Trail Draw");
}
Пример #11
0
void trail_add_batch(trail * trailp)
{
	int sections[NUM_TRAIL_SECTIONS];
	int num_sections = 0;
	int i;
	vec3d topv, botv, *fvec, last_pos, tmp_fvec;
	vertex  top, bot, top_prev, bot_prev;
	float w;
	ubyte l;
	vec3d centerv;

	if (trailp->tail == trailp->head)
		return;

	// if this trail is on the player ship, and he's in any padlock view except rear view, don't draw	
	if ((Player_ship != NULL) && trail_is_on_ship(trailp, Player_ship) &&
		(Viewer_mode & (VM_PADLOCK_UP | VM_PADLOCK_LEFT | VM_PADLOCK_RIGHT)))
	{
		return;
	}

	trail_info *ti = &trailp->info;

	int n = trailp->tail;

	do	{
		n--;

		if (n < 0)
			n = NUM_TRAIL_SECTIONS - 1;

		if (trailp->val[n] > 1.0f)
			break;

		sections[num_sections++] = n;
	} while (n != trailp->head);

	if (num_sections <= 0)
		return;

	Assertion(ti->texture.bitmap_id != -1, "Weapon trail %s could not be loaded", ti->texture.filename); // We can leave this as an assert, but tell them how to fix it. --Chief

	memset(&top, 0, sizeof(vertex));
	memset(&bot, 0, sizeof(vertex));
	memset(&top_prev, 0, sizeof(vertex));
	memset(&bot_prev, 0, sizeof(vertex));

	float w_size = (ti->w_end - ti->w_start);
	float a_size = (ti->a_end - ti->a_start);
	int num_faded_sections = ti->n_fade_out_sections;

	for (i = 0; i < num_sections; i++) {
		n = sections[i];
		float init_fade_out = 1.0f;

		if ((num_faded_sections > 0) && (i < num_faded_sections)) {
			init_fade_out = ((float)i) / (float)num_faded_sections;
		}

		w = trailp->val[n] * w_size + ti->w_start;
		if (init_fade_out != 1.0f) {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f * init_fade_out * init_fade_out);
		}
		else {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f);
		}

		if (i == 0)	{
			if (num_sections > 1)	{
				vm_vec_sub(&tmp_fvec, &trailp->pos[n], &trailp->pos[sections[i + 1]]);
				vm_vec_normalize_safe(&tmp_fvec);
				fvec = &tmp_fvec;
			}
			else {
				fvec = &tmp_fvec;
				fvec->xyz.x = 0.0f;
				fvec->xyz.y = 0.0f;
				fvec->xyz.z = 1.0f;
			}
		}
		else {
			vm_vec_sub(&tmp_fvec, &last_pos, &trailp->pos[n]);
			vm_vec_normalize_safe(&tmp_fvec);
			fvec = &tmp_fvec;
		}

		trail_calc_facing_pts(&topv, &botv, fvec, &trailp->pos[n], w);

		if (!Cmdline_nohtl) {
			g3_transfer_vertex(&top, &topv);
			g3_transfer_vertex(&bot, &botv);
		}
		else {
			g3_rotate_vertex(&top, &topv);
			g3_rotate_vertex(&bot, &botv);
		}

		top.r = top.g = top.b = l;
		bot.r = bot.g = bot.b = l;
		top.a = bot.a = l;

		float U = i2fl(i);
		
		top.texture_position.u = U;
		top.texture_position.v = 1.0f;

		bot.texture_position.u = U;
		bot.texture_position.v = 0.0f;

		if (i > 0) {
			if (i == num_sections - 1) {
				// Last one...
				vm_vec_avg(&centerv, &topv, &botv);

				vertex center_vert = vertex();

				if (!Cmdline_nohtl)
					g3_transfer_vertex(&center_vert, &centerv);
				else
					g3_rotate_vertex(&center_vert, &centerv);

				center_vert.texture_position.u = U + 1.0f;
				center_vert.texture_position.v = 0.5f;
				center_vert.a = center_vert.r = center_vert.g = center_vert.b = l;

				vertex tri[3];

				tri[1] = top_prev;
				tri[2] = bot_prev;
				tri[0] = center_vert;

				batch_add_tri(
					ti->texture.bitmap_id,
					TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT,
					tri,
					1.0f
				);
			} else {
				vertex quad[4];

				quad[0] = top_prev;
				quad[1] = bot_prev;
				quad[2] = bot;
				quad[3] = top;

				batch_add_quad(
					ti->texture.bitmap_id, 
					TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT,
					quad,
					1.0f
				);
			}
		}

		last_pos = trailp->pos[n];
		top_prev = top;
		bot_prev = bot;
	}
}
Пример #12
0
// function to actually deal with weapon-ship hit stuff.  separated from check_collision routine below
// because of multiplayer reasons.
void ship_weapon_do_hit_stuff(object *ship_obj, object *weapon_obj, vec3d *world_hitpos, vec3d *hitpos, int quadrant_num, int submodel_num, vec3d /*not a pointer intentionaly*/ hit_dir)
{
	weapon	*wp = &Weapons[weapon_obj->instance];
	weapon_info	*wip = &Weapon_info[wp->weapon_info_index];
	ship *shipp = &Ships[ship_obj->instance];	
	float damage;
	vec3d force;		

	// Apply hit & damage & stuff to weapon
	weapon_hit(weapon_obj, ship_obj,  world_hitpos);

	damage = wip->damage;

	// deterine whack whack
	float		blast = wip->mass;
	vm_vec_copy_scale(&force, &weapon_obj->phys_info.vel, blast );	

	// send player pain packet
	if ( (MULTIPLAYER_MASTER) && !(shipp->flags & SF_DYING) ){
		int np_index = multi_find_player_by_object(ship_obj);

		// if this is a player ship
		if((np_index >= 0) && (np_index != MY_NET_PLAYER_NUM) && (wip->subtype == WP_LASER)){
			send_player_pain_packet(&Net_players[np_index], wp->weapon_info_index, wip->damage * weapon_get_damage_scale(wip, weapon_obj, ship_obj), &force, hitpos);
		}
	}	

	ship_apply_local_damage(ship_obj, weapon_obj, world_hitpos, damage, quadrant_num, CREATE_SPARKS, submodel_num);

	// let the hud shield gauge know when Player or Player target is hit
	hud_shield_quadrant_hit(ship_obj, quadrant_num);

	// Let wingman status gauge know a wingman ship was hit
	if ( (Ships[ship_obj->instance].wing_status_wing_index >= 0) && ((Ships[ship_obj->instance].wing_status_wing_pos >= 0)) ) {
		hud_wingman_status_start_flash(shipp->wing_status_wing_index, shipp->wing_status_wing_pos);
	}

	// Apply a wack.  This used to be inside of ship_hit... duh! Ship_hit
	// is to apply damage, not physics, so I moved it here.
	// don't apply whack for multiplayer_client from laser - will occur with pain packet
	if (!((wip->subtype == WP_LASER) && MULTIPLAYER_CLIENT) ) {		
		// apply a whack		
		ship_apply_whack( &force, hitpos, ship_obj );
	}

	if( (quadrant_num == -1) && Cmdline_decals ){
		weapon_info	*wip = &Weapon_info[Weapons[weapon_obj->instance].weapon_info_index];
		decal_point dec;
		dec.orient = weapon_obj->orient;
		vec3d hit_fvec;
		vm_vec_negate(&hit_dir);
		vm_vec_avg(&hit_fvec, &hit_dir, &weapon_obj->orient.vec.fvec);
		vm_vec_normalize(&hit_fvec);
		dec.orient.vec.fvec = hit_fvec;
		vm_fix_matrix(&dec.orient);
		dec.pnt.xyz = hitpos->xyz;
		dec.radius = wip->decal_rad;

		if ( (dec.radius > 0) && (wip->decal_texture.bitmap_id > -1) )
			decal_create(ship_obj, &dec, submodel_num, wip->decal_texture.bitmap_id, wip->decal_backface_texture.bitmap_id, wip->decal_glow_texture_id, wip->decal_burn_texture_id, wip->decal_burn_time);
	}
	

}