⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objects.cpp

📁 2002年
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "objects.h"
#include "worldmodel.h"
#include "perceptron.h"
#include "skill.h"
#include "log.h"

ObjectUpdate::ObjectUpdate(){
	pos_time = -1;
}

void ObjectUpdate::set_polar(AngleDeg ang,Time time){
	//do not exchange the order of the next two statements
	seenposinfo.Setdata(Vector(seenposinfo.Data(seentime).x, ang), time);
	seentime = Max(seentime, time);
	seen = true;
}
  
void ObjectUpdate::set_polar(AngleDeg ang,float d,Time time){
	seenposinfo.Setdata(Vector(d, ang), time);
	seen = true;
	if(seentime < time){
		seentime = time;
		sdtime = time;
		seen_times.Add(time);
	}else if(seentime > time){
		int i,j;
		for(i=seen_times.Num_datas()-2; i>=0; i--){
			if(seen_times.Data(i) == time) return;
			if(seen_times.Data(i) < time){
				break;
			}
		}
		i++;
		seen_times.Add(time);
		for(j=seen_times.Num_datas()-1; j>i; j--){
			seen_times.Data(j) = seen_times.Data(j-1);
		} 
		seen_times.Data(j) = time;
	}else{
		if(seen_times.IsEmpty()){
			seen_times.Add(time);
		} 
	}
}


void ObjectUpdate::set_conf_param(float max,float decay,float min){
	max_conf = max;
	conf_decay = decay;
	min_valid_conf = min;
}

void ObjectUpdate::set_objtype(ObjType objtype){
	this->objtype = objtype;
}

/*******************************   Object   **************************/
Object::Object(){
	pos_conf = 0;
	global_angle = 0;
}

void Object::set_pos(float X,float Y,bool rotate){
	if (!rotate)
		pos = Vector(X,Y);
	else
		pos = Vector(-X,-Y);
}

void Object::set_global_angle(AngleDeg ang,bool rotate){
	if(!rotate)
		global_angle = ang;
	else
		global_angle = NormalizeAngle(180 + ang);
}

bool Object::pos_valid(){
	return bool(pos_conf >= min_valid_conf);
}

/**************************Mobile Object Update Process************************/
MobileUpdate::MobileUpdate(){
	coordinate_time = -1;
	heard_pos = false;
	heard_vel = false;
	pos_delta_valid = false;
}

void MobileUpdate::estimate_pos_delta(Time t){	
	if(!pos_delta_valid) return;

	while(pos_delta_time < t){
		pos_deltas.Setdata(pos_deltas.Data(pos_delta_time) + max_speed, pos_delta_time+1);
		pos_delta_time ++;
	}
}


void MobileUpdate::Parse_HearPos(TimedData<NoiseVector>& hearpos){
	if(!heard_pos){
		heardpos_info = hearpos;
		heard_pos = true;
	}else if(hearpos.data.delta >= hearpos.data.delta){
		//the second hear info is more valuable
		heardpos_info = hearpos;
	}
}

void MobileUpdate::Parse_HearVel(TimedData<NoiseVector>& hearvel){
	if(!heard_vel){
		heardvel_info = hearvel;
		heard_vel = true;
	}else if(hearvel.data.delta >= hearvel.data.delta){
		//the second hear info is more valuable
		heardvel_info = hearvel;
	}
}

void MobileUpdate::set_speed_param(float max,float decay){
	max_speed = max;
	speed_decay = decay;
}

void MobileUpdate::set_chinfo(float distChng,float dirChng,Time time){
	seenchinfo.Setdata(Vector(distChng, dirChng), time);
}

/***************************   Mobile Object       *********************/
MobileObject::MobileObject(){
	Object::Object();
	speed_conf = 0;
	speed_conf = 0;
	global_vel = 0;
	update_seen_time = -1;
	seentime = -1;
	sdtime = -1;
}

Vector MobileObject::Pos(Time time){
	return gpos.IsDataKnown(time) ? gpos.Data(time) : pos;
}

int MobileObject::PosDelay(){
	return situation.CurrentTime - original_postime;
}

int MobileObject::VelDelay(){
	return situation.CurrentTime - original_veltime;
}

Vector MobileObject::Vel(Time time){
	return gvel.IsDataKnown(time) ? gvel.Data(time) : global_vel;
}

float MobileObject::ActiveRadius(Time time){
	return pos_deltas.ChkData(time);
}

void MobileObject::update_end(){
	if(newpos){
		forgot = false;
	}
#ifndef _Up_FState
	if(sensory.NewSight && !seen && inview(sensory.LastSightTime) && distance < ServerParam::team_far_length){
		DoLog(LOG_UPDATE, "forget obj (%.2f %.2f)", pos.x, pos.y);
		forget();
	}
#endif
	pos = Pos(situation.CurrentTime);
	rel_pos = pos - Self.pos;
	global_angle = rel_pos.Angle();
	distance = rel_pos.mod();

	if (domain.IsDataKnown(situation.CurrentTime)) 
	{
		RingSector * rs = &(domain.Data(situation.CurrentTime));
		if (objtype == OBJ_Player && rs->IsValid() &&			//valid player and valid domain
			!rs->IsWithin(global_angle, distance)				//pos is out of domain
			&& rel_pos.mod() < ServerParam::team_far_length * 0.9f){	//too far player needn't care
			/*
			if(ball.kickable()){
				DoLog("ctrller adjust");
			} 
			//player pos correction based on domain, move from outside into the edge of domain
			DoLog("move player %d into domain mean%.1f delta%.1f, former dir%.1f",
				((Player*) this)->InsideNO, 
				rs->angles.Data(0).mean,
				rs->angles.Data(0).delta,
				global_angle);
			*/
			//distance correction
			if (distance > rs->radius.sup()){
				distance = rs->radius.sup();
			}else if (distance < rs->radius.inf()){ 
				distance = rs->radius.inf();
			}
			if(!rs->IsWithin(global_angle)){
				//angle correction, it's assumed to lies in the first sector of domain.
				float da = NormalizeAngle(global_angle - rs->angles.Data(0).mean);
				if (da > rs->angles.Data(0).delta){
					global_angle = NormalizeAngle(rs->angles.Data(0).sup());
				}else if(da < - rs->angles.Data(0).delta){
					global_angle = NormalizeAngle(rs->angles.Data(0).inf());
				}
			}
			rel_pos = Polar2Vector(distance, global_angle);
			pos = Self.pos + rel_pos;
			//DoLog("from (%.1f, %.1f) to (%.1f, %.1f)", Pos(situation.CurrentTime).x, Pos(situation.CurrentTime).y, pos.x, pos.y);
		}
	}
	
	global_vel = Vel(situation.CurrentTime);
	speed = global_vel.mod();
	vel_angle = global_vel.Angle();
//yjy
	pos_delta = pos_deltas.Data(situation.CurrentTime);

	seen = false;
	isupdateheard = false;
	seen_times.Reset();
	heard_pos = false;
	heard_vel = false;
}

//
void MobileObject::Prior_update(){
	newpos = false;
	updated_seen = false;
	newvel = false;
}

void MobileObject::update(Time time){
	update_seen(time);
	update_heard(time);

	//if(IsValidObject()){
	estimate(time);
	pos = Pos(sensory.LastSightTime);
	rel_pos = pos - Self.Pos(sensory.LastSightTime);
	distance = rel_pos.mod();
	//}
}

void MobileObject::update_seen(Time time){
#ifdef	_Up_FState
	if(sensory.HasFullState() && acc_vel.IsDataKnown(time)){
		gvel.Setdata(acc_vel.Data(time), time);
		gpos.Setdata(acc_pos.Data(time), time);
		pos_time = time;
		coordinate_time = time;
		vel_time = time;
		speed_conf = max_conf;
		pos_conf = max_conf;
		update_seen_time = time;
		original_postime = time;
		original_veltime = time;

		updated_seen = true;
		newpos = true;
		newvel = true;

		pos_delta_valid = true;
		pos_deltas.Setdata(0,time);
		pos_delta_time = time;
		rel_pos = gpos.Data(time) - Self.Pos(time);
		domain.Data(time).Set(rel_pos.mod(), 0, rel_pos.Angle(), 0); 
		domain.TimedData(time).time = time;
	} 
#else
//没有新的视觉消息, 直接返回
	if(seen){
//将收到的视觉信息,按时间依次更新 (一般1条或2条视觉信息)
		Vector pos, rel_vel, rpos;
		int i = 0, t = 0;
		for(; i<seen_times.Num_datas(); i++){
			t = seen_times.Data(i);
			/*       Position         */
			rpos = Polar2Vector(seen_distance(t), seen_rel_angle(t)); 
			pos = rpos.Rotate(Self.Headfacing(t)) + Self.Pos(t);
			estimate(t -1);
			gpos.Setdata(pos, t);
			
			/*****************/
			float seegap = Sqr(seen_distance(t)*ServerParam::dist_qstep*0.5f) + Sqr(seen_distance(t)*ServerParam::dir_qstep*0.5f );
			pos_deltas.Setdata((float)sqrt(seegap), t);
			
			/*       Velocity         */
			if (seenchinfo.IsDataKnown(t)){
				newvel = true;
				
				rpos.Normalize();
				rel_vel.x = seen_distCh(t) * rpos.x - (seen_dirCh(t) * PI / 180.0f * seen_distance(t) * rpos.y);
				rel_vel.y = seen_distCh(t) * rpos.y + (seen_dirCh(t) * PI / 180.0f * seen_distance(t) * rpos.x);
				rel_vel = rel_vel.Rotate(Self.Headfacing(t));

				gvel.Setdata(Self.Vel(t) + rel_vel, t);
				vel_time = t;
				speed_conf = max_conf;
				
				original_veltime = t;
			}
		}
		updated_seen = true;
		newpos = true;

		update_seen_time = t;
		pos_time = t;
		coordinate_time = t;
		pos_conf = max_conf;
		original_postime = t;
		pos_delta_time = t;
		pos_delta_valid = true;
		forgot = false;
	}
#endif
}

void MobileObject::estimate(Time time){
	//if(!IsValidObject()) return;

	Time t;
	if(vel_time < pos_time - 5){//for unknown player, maybe no old vel;
		vel_time = pos_time;
		gvel.Setdata(0, vel_time);
		speed_conf = 0;
	}
	for(t = vel_time; t < pos_time; t ++){
		estimate_vel(t + 1);
	}
	if(sensory.LastSightTime > coordinate_time && coordinate_time > 0 && gpos.IsDataKnown(coordinate_time)){
		float posconfbk = pos_conf;
		for(t = coordinate_time; t < pos_time; t++){			
			estimate_pos(t + 1);
		}
		pos_conf = posconfbk;
	}
	for(t = pos_time; t < time; t ++){
		estimate_vel(t + 1);
		estimate_pos(t + 1);
	}
}

void MobileObject::estimate_vel(Time time){
	Vector evel = gvel.ChkData(time -1);

	if (objtype == OBJ_Ball)
		evel += Skill::action.KickEffect(time -1);
	if (evel.mod() > max_speed){
		evel = evel / evel.mod() * max_speed;
	}
	evel *= speed_decay;
	gvel.Setdata(evel, time);
	speed_conf *= conf_decay;
	vel_time = time;
	if (objtype == OBJ_Ball){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -