コード例 #1
0
ファイル: map_util_prepare.c プロジェクト: rzel/dim3
void map_prepare_mesh_poly_shadow(map_type *map,map_mesh_type *mesh,map_mesh_poly_type *poly)
{
	int			d;
	
	poly->draw.shadow_ok=TRUE;
	
	if (!poly->box.wall_like) {
		if (map->optimize.shadow_poly_min_area==0) return;
		poly->draw.shadow_ok=((poly->box.max.x-poly->box.min.x)>=map->optimize.shadow_poly_min_area) || ((poly->box.max.z-poly->box.min.z)>=map->optimize.shadow_poly_min_area);
	}
	else {

			// floor only drawing?

		if (map->optimize.shadow_floor_only) {
			poly->draw.shadow_ok=FALSE;
			return;
		}
		
		if (map->optimize.shadow_poly_min_area==0) return;

		d=distance_2D_get(poly->box.min.x,poly->box.min.z,poly->box.max.x,poly->box.max.z);
		poly->draw.shadow_ok=(d>=map->optimize.shadow_poly_min_area) || ((poly->box.max.y-poly->box.min.y)>=map->optimize.shadow_poly_min_area);
	}
}
コード例 #2
0
ファイル: map_nodes.c プロジェクト: rzel/dim3
void node_path_rebuild(void)
{
    int				i,x,z,k,n;
	unsigned char	node_hit[max_node];
	node_type		*node,*to_node;
	
        // precalc the distance between each
		// directly linked node
        
	node=map.nodes;
		
    for (n=0;n!=map.nnode;n++) {
    
        x=node->pnt.x;
        z=node->pnt.z;
		
			// get distance to each directly linked node
			
        for (i=0;i!=max_node_link;i++) {
            k=node->link[i];
            if ((k==-1) || (k==n)) {
                node_scan[n].link_dist[i]=0;
            }
            else {
				to_node=&map.nodes[k];
            	node_scan[n].link_dist[i]=distance_2D_get(x,z,to_node->pnt.x,to_node->pnt.z);
            }
        }
        
            // clear out path hints

        for (k=0;k!=map.nnode;k++) {
            node->path_hint[k]=-1;
        }
        
        node++;
    }
    
        // find the best path between all nodes
	
    for (n=0;n!=map.nnode;n++) {
		node_path_trace_all(n,0,0,0,node_hit,0);
    }
}
コード例 #3
0
ファイル: camera.c プロジェクト: prophile/dim3
void camera_get_angle_from(d3pnt *pt,d3ang *ang)
{
	int				dist;
	d3pnt			pnt;
	d3ang			temp_ang;

		// get camera position

	camera_get_position(&pnt,&temp_ang);

		// find angle

	dist=distance_2D_get(0,0,(pnt.x-pt->x),(pnt.z-pt->z));
	ang->x=-angle_find(0,0,(pnt.y-pt->y),dist);

	ang->y=angle_find(pt->x,pt->z,pnt.x,pnt.z);

	ang->z=0.0f;
}
コード例 #4
0
ファイル: map_util_prepare.c プロジェクト: rzel/dim3
void map_prepare_mesh_poly(map_type *map,map_mesh_type *mesh,map_mesh_poly_type *poly)
{
	int				n,ptsz,y,lx,rx,lz,rz,dist;
	float			ang;
	bool			flat;
	d3pnt			min,max,mid;
	d3pnt			*pt;
	d3vct			map_up;

		// find enclosing square
		// and middle and if polygon is flat
		
	pt=&mesh->vertexes[poly->v[0]];

	min.x=max.x=mid.x=pt->x;
	min.y=max.y=mid.y=y=pt->y;
	min.z=max.z=mid.z=pt->z;

	flat=TRUE;
    
    ptsz=poly->ptsz;
    
	for (n=1;n<ptsz;n++) {
		pt=&mesh->vertexes[poly->v[n]];

			// get min and max

		if (pt->x<min.x) min.x=pt->x;
		if (pt->x>max.x) max.x=pt->x;
		if (pt->y<min.y) min.y=pt->y;
		if (pt->y>max.y) max.y=pt->y;
		if (pt->z<min.z) min.z=pt->z;
		if (pt->z>max.z) max.z=pt->z;

			// add for middle

		mid.x+=pt->x;
		mid.y+=pt->y;
		mid.z+=pt->z;

			// check for flat y

		if (pt->y!=y) flat=FALSE;
	}
    
	memmove(&poly->box.min,&min,sizeof(d3pnt));
	memmove(&poly->box.max,&max,sizeof(d3pnt));
	
	poly->box.mid.x=mid.x/ptsz;
	poly->box.mid.y=mid.y/ptsz;
	poly->box.mid.z=mid.z/ptsz;
	
	poly->box.flat=flat;

		// get dot product of normal and up
		// vector to determine the slope of surface
		// and if it's wall like

	if (flat) {
		poly->slope.y=0.0f;
		poly->slope.ang_y=0.0f;
		poly->slope.move_x=0.0f;
		poly->slope.move_z=0.0f;

		poly->box.wall_like=FALSE;
	}
	else {
		map_up.x=0.0f;
		map_up.y=-1.0f;
		map_up.z=0.0f;

		ang=fabsf(vector_dot_product(&map_up,&poly->tangent_space.normal));

			// use dot product to tell if wall like
			// and the y slope

		poly->box.wall_like=(ang<=0.4f);
		poly->slope.y=1.0f-ang;

			// find the slope angle

		map_prepare_mesh_poly_slope_ang(mesh,poly);
		angle_get_movement_float(poly->slope.ang_y,(map->physics.slope_max_speed*poly->slope.y),&poly->slope.move_x,&poly->slope.move_z);
	}

		// create wall "line" for wall like polygons

	if (poly->box.wall_like) {
			
			// get the lx,lz to rx,rz
			
		lx=poly->box.min.x;
		rx=poly->box.max.x;
		lz=poly->box.min.z;
		rz=poly->box.max.z;
		
		for (n=0;n!=poly->ptsz;n++) {
			pt=&mesh->vertexes[poly->v[n]];
			
			if ((rx-lx)>(rz-lz)) {
				if (pt->x==lx) lz=pt->z;
				if (pt->x==rx) rz=pt->z;
			}
			else {
				if (pt->z==lz) lx=pt->x;
				if (pt->z==rz) rx=pt->x;
			}
		}

		poly->line.lx=lx;
		poly->line.rx=rx;
		poly->line.lz=lz;
		poly->line.rz=rz;
		
			// find ty,by for each point
			// we need to catch polygons that have higher or lower
			// points slightly offset from lx,lz or rx,rz, so we use
			// a distance calculation here (within 20% of end point)
			
		dist=distance_2D_get(lx,lz,rx,rz);
		dist=(dist*20)/100;
			
		poly->line.l_ty=poly->line.r_ty=poly->line.l_by=poly->line.r_by=-1;
		
		for (n=0;n!=poly->ptsz;n++) {
			pt=&mesh->vertexes[poly->v[n]];
			
			if (distance_2D_get(pt->x,pt->z,lx,lz)<dist) {
				if ((pt->y<poly->line.l_ty) || (poly->line.l_ty==-1)) poly->line.l_ty=pt->y;
				if ((pt->y>poly->line.l_by) || (poly->line.l_by==-1)) poly->line.l_by=pt->y;
			}
			
			if (distance_2D_get(pt->x,pt->z,rx,rz)<dist) {
				if ((pt->y<poly->line.r_ty) || (poly->line.r_ty==-1)) poly->line.r_ty=pt->y;
				if ((pt->y>poly->line.r_by) || (poly->line.r_by==-1)) poly->line.r_by=pt->y;
			}
		}
		
		if (poly->line.l_ty==-1) poly->line.l_ty=poly->box.min.y;
		if (poly->line.r_ty==-1) poly->line.r_ty=poly->box.min.y;
		if (poly->line.l_by==-1) poly->line.l_by=poly->box.max.y;
		if (poly->line.r_by==-1) poly->line.r_by=poly->box.max.y;
	}
	
		// get the plane equation for ray-plane intersections
		
	map_prepare_mesh_poly_plane(mesh,poly);

		// determine if shadows can project on this polygon

	map_prepare_mesh_poly_shadow(map,mesh,poly);
}
コード例 #5
0
ファイル: model_util_normals.c プロジェクト: rzel/dim3
bool model_recalc_normals_determine_vector_in_out(model_type *model,int mesh_idx,int vertex_idx)
{
    int					x,y,z,k,pos_dist,neg_dist;
    float				f_dist;
    bool				is_out;
    d3pnt				*pnt,min,max,center,pos_pt,neg_pt;
    d3vct				face_vct;
    model_mesh_type		*mesh;
    model_vertex_type	*vertex;

    // get box for vertex.  This will be the combination
    // of vertexes with the same material

    map_recalc_normals_get_vertex_box(model,mesh_idx,vertex_idx,&min,&max);

    // get the box center

    mesh=&model->meshes[mesh_idx];
    vertex=&mesh->vertexes[vertex_idx];
    pnt=&vertex->pnt;

    center.x=(min.x+max.x)>>1;
    center.y=(min.y+max.y)>>1;
    center.z=(min.z+max.z)>>1;

    // the dot product is the fall back position
    // if these specialized checks fail

    vector_create(&face_vct,pnt->x,pnt->y,pnt->z,center.x,center.y,center.z);
    is_out=(vector_dot_product(&vertex->tangent_space.normal,&face_vct)>0.0f);

    // get a point from the current normal vector
    // and inverse of the current normal vector, using 10%
    // of the distance to center

    f_dist=(float)distance_get(pnt->x,pnt->y,pnt->z,center.x,center.y,center.z);
    f_dist*=0.1f;

    pos_pt.x=pnt->x+(int)(vertex->tangent_space.normal.x*f_dist);
    pos_pt.y=pnt->y+(int)(vertex->tangent_space.normal.y*f_dist);
    pos_pt.z=pnt->z+(int)(vertex->tangent_space.normal.z*f_dist);

    neg_pt.x=pnt->x-(int)(vertex->tangent_space.normal.x*f_dist);
    neg_pt.y=pnt->y-(int)(vertex->tangent_space.normal.y*f_dist);
    neg_pt.z=pnt->z-(int)(vertex->tangent_space.normal.z*f_dist);

    // first we determine if we can think of the
    // poly's box (which is determined by all connected
    // polys) as a closed object in one direction

    // if one direction is at least 25% greater than the others
    // then consider it a tube like structure

    // if any distance calcs fail, fall back to dot product

    x=max.x-min.x;
    y=max.y-min.y;
    z=max.z-min.z;

    k=x-((x*25)/100);
    if ((x>y) && (x>z)) {
        pos_dist=distance_2D_get(pos_pt.y,pos_pt.z,center.y,center.z);
        neg_dist=distance_2D_get(neg_pt.y,neg_pt.z,center.y,center.z);
        if (pos_dist==neg_dist) return(is_out);

        return(pos_dist>neg_dist);
    }

    k=y-((y*25)/100);
    if ((y>x) && (y>z)) {
        pos_dist=distance_2D_get(pos_pt.x,pos_pt.z,center.x,center.z);
        neg_dist=distance_2D_get(neg_pt.x,neg_pt.z,center.x,center.z);
        if (pos_dist==neg_dist) return(is_out);

        return(pos_dist>neg_dist);
    }

    k=z-((z*25)/100);
    if ((z>x) && (z>y)) {
        pos_dist=distance_2D_get(pos_pt.x,pos_pt.y,center.x,center.y);
        neg_dist=distance_2D_get(neg_pt.x,neg_pt.y,center.x,center.y);
        if (pos_dist==neg_dist) return(is_out);

        return(pos_dist>neg_dist);
    }

    // finally fall back to dot product

    return(is_out);
}
コード例 #6
0
ファイル: weapon_melee.c プロジェクト: prophile/dim3
void melee_add(obj_type *obj,weapon_type *weap,d3pnt *pt,d3ang *ang,melee_type *melee,int ignore_uid)
{
	int				n,x,y,z,xadd,zadd,damage,dist;
	bool			hit;
	char			weap_name[name_str_len];
	d3pnt			pnt;
	obj_type		*hurt_obj;
	proj_type		*proj;

		// fail under liquid?

	if (weap!=NULL) {
		if ((weap->fail_in_liquid) && (obj->liquid_mode==lm_under)) return;
	}
	
		// original position for network melees
		
	pnt.x=pt->x;
	pnt.y=pt->y;
	pnt.z=pt->z;
    
		// move melee ahead for distance
		
	angle_get_movement(ang->y,melee->distance,&xadd,&zadd);

	x=pt->x+xadd;
	y=pt->y;
	z=pt->z+zadd;
	
		// check objects
		
	for (n=0;n!=server.count.obj;n++) {
	
		hurt_obj=&server.objs[n];

        if ((hurt_obj->hidden) || (!hurt_obj->contact.projectile_on) || (hurt_obj->uid==ignore_uid)) continue;
		
			// melee hit?
			
		if (!collide_sphere_to_object(x,y,z,melee->radius,hurt_obj)) continue;
		
			// which hit box?
		
		hit=TRUE;
		
		if (hurt_obj->hit_box.on) {
			hit=collide_set_object_hit_box_for_sphere_hit(x,y,z,melee->radius,hurt_obj);
		}

			// get damage

		damage=melee->damage;

		if (melee->fall_off) {
			dist=distance_2D_get(x,z,hurt_obj->pnt.x,hurt_obj->pnt.z);
			dist-=obj->size.radius;

			if (dist>0) damage=damage-((damage*dist)/melee->radius);
			if (damage<1) damage=1;
		}
		
			// hurt
            
		if (hit) {
			object_damage(hurt_obj,obj,weap,NULL,pt,damage);
			if (weap==NULL) {
				scripts_post_event_console(&obj->attach,sd_event_melee,sd_event_melee_hit,0);
			}
			else {
				scripts_post_event_console(&weap->attach,sd_event_melee,sd_event_melee_hit,0);
			}
			scripts_post_event_console(&hurt_obj->attach,sd_event_melee,sd_event_melee_hit,0);
		}
	}
  
		// check projectiles
		
	proj=server.projs;
	
	for (n=0;n!=server.count.proj;n++) {
		if (collide_sphere_to_projectile(x,y,z,melee->radius,proj)) proj->flag_melee_hit=TRUE;		// flag the melee hit
		proj++;
	}
	
		// do any pushes
		
	if (melee->force!=0) {
		collide_push_objects(x,y,z,melee->radius,melee->force);
	}
	
		// if this object is the player object, then spawn melee in remotes
		
	if (net_setup.client.joined) {
		if ((obj->uid==server.player_obj_uid) || (obj->bot)) {
			weap_name[0]=0x0;
			if (weap!=NULL) strcpy(weap_name,weap->name);
			net_client_send_melee_add(obj->remote.uid,weap_name,melee->radius,melee->distance,melee->damage,melee->force,&pnt,ang);
		}
	}
}
コード例 #7
0
ファイル: weapon_projectile.c プロジェクト: prophile/dim3
bool weapon_get_projectile_position_angle_weapon_barrel(int tick,obj_type *obj,weapon_type *weap,d3pnt *fire_pnt,d3ang *fire_ang,char *err_str)
{
	int						pose_idx,bone_idx,dist;
	d3pnt					barrel_pnt;
	model_type				*mdl;
	model_draw				*draw;
	model_draw_setup		*setup;

		// get weapon model

	mdl=model_find_uid(weap->draw.uid);
	if (mdl==NULL) {
		if (err_str!=NULL) strcpy(err_str,"Weapon has no model");
		return(FALSE);
	}

		// get current pose

	pose_idx=model_find_pose(mdl,weap->proj.fire_pose_name);
	if (pose_idx==-1) {
		if (err_str!=NULL) strcpy(err_str,"Weapon has missing or no fire pose");
		return(FALSE);
	}
	
		// get 'fire' bone offset and calc

	bone_idx=model_find_bone(mdl,weap->proj.fire_bone_tag);
	if (bone_idx==-1) {
		if (err_str!=NULL) strcpy(err_str,"Weapon has missing or no fire bone");
		return(FALSE);
	}

	model_draw_setup_weapon(tick,obj,weap,TRUE,weap->dual.in_dual);

	if (weap->dual.in_dual) {
		draw=&weap->draw_dual;
	}
	else {
		draw=&weap->draw;
	}

	setup=&draw->setup;

	setup->move.x=setup->move.y=setup->move.z=0;
	setup->sway.x=setup->sway.y=setup->sway.z=0.0f;

	model_calc_draw_bone_position(mdl,setup,pose_idx,bone_idx,&fire_pnt->x,&fire_pnt->y,&fire_pnt->z);

	if (draw->flip_x) fire_pnt->x=-fire_pnt->x;

	fire_pnt->x+=draw->pnt.x;
	fire_pnt->y+=draw->pnt.y;
	fire_pnt->z+=draw->pnt.z;

	if (draw->no_rot.on) gl_project_fix_rotation(&fire_pnt->x,&fire_pnt->y,&fire_pnt->z);

		// get 'barrel' bone offset (draw bones already calced above)

	bone_idx=model_find_bone(mdl,weap->proj.barrel_bone_tag);
	if (bone_idx==-1) {
		if (err_str!=NULL) strcpy(err_str,"Weapon has missing or no barrel bone");
		return(FALSE);
	}

	model_get_draw_bone_position(setup,bone_idx,&barrel_pnt.x,&barrel_pnt.y,&barrel_pnt.z);

	if (draw->flip_x) barrel_pnt.x=-barrel_pnt.x;

	barrel_pnt.x+=draw->pnt.x;
	barrel_pnt.y+=draw->pnt.y;
	barrel_pnt.z+=draw->pnt.z;

	if (draw->no_rot.on) gl_project_fix_rotation(&barrel_pnt.x,&barrel_pnt.y,&barrel_pnt.z);

		// angles between them

	dist=distance_2D_get(0,0,(fire_pnt->x-barrel_pnt.x),(fire_pnt->z-barrel_pnt.z));
	fire_ang->x=-(180.0f-angle_find(0,0,(fire_pnt->y-barrel_pnt.y),dist));
	fire_ang->y=angle_find(barrel_pnt.x,barrel_pnt.z,fire_pnt->x,fire_pnt->z);
	fire_ang->z=0.0f;

	return(TRUE);
}