void Start() { particles = new particle_type[particleNum]; objParticles = new GameObject[particleNum]; for (int i = 0; i < particleNum; i++) { particles [i] = new particle_type(Random.Range(0, width), Random.Range(0, height), Random.Range(0.0f, 1.0f)); objParticles [i] = Instantiate(objParticle, particles [i].pos(), objParticle.transform.rotation) as GameObject; objParticles [i].transform.parent = container.transform; } A = new[, ] { { 1.0f, 0 }, { 0, 1.0f } }; B = new[, ] { { dt, 0 }, { 0, dt } }; x = new[, ] { { 0.0f }, { 0.0f } }; z = new[, ] { { 0.0f }, { 0.0f } }; u = new[, ] { { 1.0f }, { 1.0f } }; s_sigma = new[, ] { { 0.1f, 0 }, { 0, 0.1f } }; o_sigma = new[, ] { { 0.1f, 0 }, { 0, 0.1f } }; sigma = o_sigma [0, 0]; Kai = new float[2, M]; Kai_bar = new float[3, M]; w = new float[M]; for (int j = 0; j < 2; j++) { for (int i = 0; i < M; i++) { Kai [j, i] = 0; } } for (int j = 0; j < 3; j++) { for (int i = 0; i < M; i++) { Kai_bar [j, i] = 0; } } for (int i = 0; i < M; i++) { w [i] = 1.0f / M; } }
void resample() { // 累積重みの計算. float[] weights = new float[particleNum]; weights [0] = particles [0].weight; for (int i = 1; i < particleNum; i++) { weights [i] = weights [i - 1] + particles [i].weight; } // 重みを基準にパーティクルをリサンプリングして重みを1.0に. particle_type[] tmp_particles = new particle_type[particleNum]; particles.CopyTo(tmp_particles, 0); for (int i = 0; i < particleNum; i++) { float weight = Random.value * weights [particleNum - 1]; int n = 0; while (weights[++n] < weight) { ; } particles [i] = tmp_particles [n]; // objParticles [i].transform.localScale = particles [i].weight*Vector3.one * 2; particles [i].weight = 1.0f; } }
void initialize() { // オブジェクトの準備. particles = new particle_type[particleNum]; objParticles = new GameObject[particleNum]; for (int i = 0; i < particleNum; i++) { particles [i] = new particle_type (Random.Range (0, width), Random.Range (0, height), Random.Range (0.0f, 1.0f)); objParticles [i] = Instantiate (objParticle, particles [i].pos (), objParticle.transform.rotation) as GameObject; objParticles [i].transform.parent = container.transform; } res = Instantiate (res, new Vector3 (-5, -5, 0), res.transform.rotation) as GameObject; // wcbからデータを受け取る. width = wcb.width; height = wcb.height; GetComponent<Renderer>().material.mainTexture = wct; c = wct.GetPixels32 (); // カメラの画像読み込み. particle_type max_particle = new particle_type (0, 0, 0); // 最も尤度の高いピクセルを探索. for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { float weight = likelihood (i, j); if (weight > max_particle.weight) max_particle = new particle_type (i, j, weight); } } // すべてのパーティクルの値を最尤値で設定する. for (int i = 0; i < particleNum; i++) particles [i] = max_particle; }
private bool delete_signal; // if true - delete immediately /// <summary> /// initiates all basic particle features, additional functions will be created to allow “turning on” /// parameters such as color change or scale change because each one needs additional parameters and will clutter the basic constructor /// </summary> /// <param name="ptype">particle shape type</param> /// <param name="ttype">trajectory type - movement</param> /// <param name="origin">particle position for rendering and calculations</param> /// <param name="life">particle duration before deletion</param> /// <param name="max_distance">maximum travel distance before deldetion</param> /// <param name="ang_momentum">rotational speed</param> /// <param name="starting_speed">starting movement speed</param> /// <param name="acceleration">particle acceleration value in pixels per second squared</param> /// <param name="direction_angle">direction of movement</param> public Particle(particle_type ptype, trajectory_type ttype, Vector2 origin, int life, int max_distance, float ang_momentum, float starting_speed, float acceleration, float direction_angle) { particle_origin = origin; bounds = Rectangle.Empty; //calculate this like x,y, width,height particle_life = life; this.max_distance = max_distance; particle_creation_time = Engine.get_current_game_millisecond(); last_update_time = particle_creation_time; particle_angular_momentum = ang_momentum; particle_angle = 0f; this._particle_type = ptype; this.trajectory = ttype; this.acceleration = acceleration; // acceleration value in px/s^2 this.starting_speed = starting_speed; // initial speed of the particle in px/s has to be float but is truncated to int when object is rendered this.speed = starting_speed; this.direction_angle = direction_angle; current_scale = 1.0f; scale_minmax = Vector2.One; // scale limits for interpolation scale_fluc_period = 0; // scale fluctuation period in ms scale_interpolation_flag = false; // dynamic scale? transparency = 1.0f; transparency_minmax = Vector2.One; // min-max transparency transparency_fluc_period = 0; // scale fluctuation period in ms transparency_interpolation_flag = false; // change transparency for this particle? light_source_particle = false; // has a light sphere base_color_light_sphere = Color.White; secondary_color_light_sphere = Color.White; // what color does particle light sphere interpolate to? light_sphere_color_fluc_period = 0; // color fluctuation period in ms light_color_interpolation_flag = false; // dynamic light color? enables gradient of 2 colors light_sphere_size_minmax = new Int2(0, 0); // light radius in px min and max light_sphere_size_interpolation_flag = false; light_sphere_size_fluc_period = 0; // scale fluctuation period in ms tint_flag = false; // tinted or use original graphics current_color = Color.White; base_tint = Color.White; // base tint: in case our particle needs tint effect or if it's white and this is color source. secondary_tint = null; // a second tint color to which the base color can interpolate tint_interpolation_flag = false; color_fluc_period = 0; delete_signal = false; }
void initialize() { // オブジェクトの準備. particles = new particle_type[particleNum]; objParticles = new GameObject[particleNum]; for (int i = 0; i < particleNum; i++) { particles [i] = new particle_type(Random.Range(0, width), Random.Range(0, height), Random.Range(0.0f, 1.0f)); objParticles [i] = Instantiate(objParticle, particles [i].pos(), objParticle.transform.rotation) as GameObject; objParticles [i].transform.parent = container.transform; } res = Instantiate(res, new Vector3(-5, -5, 0), res.transform.rotation) as GameObject; // wcbからデータを受け取る. width = wcb.width; height = wcb.height; GetComponent <Renderer>().material.mainTexture = wct; c = wct.GetPixels32(); // カメラの画像読み込み. particle_type max_particle = new particle_type(0, 0, 0); // 最も尤度の高いピクセルを探索. for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { float weight = likelihood(i, j); if (weight > max_particle.weight) { max_particle = new particle_type(i, j, weight); } } } // すべてのパーティクルの値を最尤値で設定する. for (int i = 0; i < particleNum; i++) { particles [i] = max_particle; } }
/// <summary> /// Emitter generator - send emitter for an enabled object to handle /// </summary> /// <param name="host">an object that is hosting the emitter</param> /// <param name="pos">emitter position in pixels</param> /// <param name="ptype">particle type being generated</param> /// <param name="random">are particles randomized?</param> /// <param name="emitter_life_duration">how long should this emitter exist</param> /// <param name="rate">number of ms between bursts</param> /// <param name="auto">is generation automatic?</param> /// <param name="ttype">particle trajectory type</param> /// <param name="particle_lifetime">how long should the particles exist - in ms?</param> /// <param name="number_of_particles_in_burst">number of particles generated at the same time</param> /// <param name="random_color">are colors randomized?</param> /// <param name="interpolate_color_flag">are colors interpolated?</param> /// <param name="area_radius">area of generation</param> public void create_emitter( IParticleCreating host, // emitter will be created inside this object Vector2[] pos, // create in these positions (allows creation of multiple emitters in one function call) particle_type ptype, // defines what shape the particle takes as well as multiple internal properties bool random, // int emitter_life_duration, // when is this emitter scheduled for deletion int rate, // number of milliseconds between particle bursts bool auto, // requires no manual input to create particles trajectory_type ttype, // trajectory type - defines particle movement after creation int particle_lifetime, // particle lifetime int number_of_particles_in_burst, // number of particles created in the same cycle bool random_color, // randomizes particle tint bool interpolate_color_flag, // change from current color to black int area_radius // all particles in one burst will be created in this radius (use 1 for point creation) ) { for (int i = 0; i < pos.Length; i++) { Emitter temp = new Emitter(pos[i], ptype, random, emitter_life_duration, particle_lifetime, rate, auto, ttype, number_of_particles_in_burst, random_color, interpolate_color_flag, area_radius); // call Emitter constructor using parameters supplied by Engine host.Add(temp); // function required by the interface } }
/// <summary> /// Emitter constructor /// </summary> /// <param name="pos">cell position vector</param> /// <param name="ptype">particle type</param> /// <param name="random">randomzied particles</param> /// <param name="emitter_life_duration">emitter life</param> /// <param name="particle_lifetime">particle lifetime</param> /// <param name="rate">number of milliseconds until next burst</param> /// <param name="auto">automatic generation - no signal needed</param> /// <param name="ttype">particle trajectory type</param> /// <param name="number_of_particles_in_burst">number of particles generated in one burst</param> /// <param name="random_color">randomized color</param> /// <param name="interpolate_color">change from one color to another over time</param> /// <param name="area_radius">emitter burst area</param> public Emitter(Vector2 pos, particle_type ptype, bool random, int emitter_life_duration, int particle_lifetime, int rate, bool auto, trajectory_type ttype, int number_of_particles_in_burst, bool random_color, bool interpolate_color, int area_radius) { position = pos; this._particle_type = ptype; random_type = random; emitter_duration = emitter_life_duration; last_burst = 0; this.rate = rate; automatic_generation = auto; this.trajectory = ttype; this.number_of_particles_in_burst = number_of_particles_in_burst; random_color_flag = random_color; // assigns a random color instead of a built in color value emitter_radius = area_radius; creation_time = Engine.get_current_game_millisecond(); // get ms value from Engine and assign as a beginning point particles_created = new List <Particle>(); acceleration = 0; scale = 1f; rotation_amount = 0f; particle_base_color = Color.White; particle_secondary_color = null; emit = false; this.particle_lifetime = particle_lifetime; interpolate_color_flag = interpolate_color; }
void show_res(particle_type particle) // 結果を出力. { res.transform.position = particle.pos(); }
/// <summary> /// update particle type generated by this emitter /// </summary> /// <param name="p_type">particle type enum value</param> public void change_particle_type(particle_type p_type) { _particle_type = p_type; }
void resample() { // 累積重みの計算. float[] weights = new float[particleNum]; weights [0] = particles [0].weight; for (int i = 1; i < particleNum; i++) weights [i] = weights [i - 1] + particles [i].weight; // 重みを基準にパーティクルをリサンプリングして重みを1.0に. particle_type[] tmp_particles = new particle_type[particleNum]; particles.CopyTo (tmp_particles, 0); for (int i = 0; i < particleNum; i++) { float weight = Random.value * weights [particleNum - 1]; int n = 0; while (weights[++n] < weight); particles [i] = tmp_particles [n]; // objParticles [i].transform.localScale = particles [i].weight*Vector3.one * 2; particles [i].weight = 1.0f; } }
// 結果を出力. void show_res(particle_type particle) { res.transform.position = particle.pos (); }
bool weight(particle_type[] particles, Color32[] c) { // 尤度に従いパーティクルの重みを決定する. float sum_weight = 0; for (int i = 0; i < particles.Length; i++) { particles [i].weight = likelihood (particles [i].x, particles [i].y, c); sum_weight += particles [i].weight; } // 重みの正規化. for (int i = 0; i < particles.Length; i++) particles [i].weight = (particles [i].weight / sum_weight) * particles.Length; return true; }
void Start() { particles = new particle_type[particleNum]; objParticles = new GameObject[particleNum]; for (int i = 0; i < particleNum; i++) { particles [i] = new particle_type (Random.Range (0, width), Random.Range (0, height), Random.Range (0.0f, 1.0f)); objParticles [i] = Instantiate (objParticle, particles [i].pos (), objParticle.transform.rotation) as GameObject; objParticles [i].transform.parent = container.transform; } A = new[,]{ {1.0f, 0}, {0, 1.0f}}; B = new[,]{ {dt, 0}, {0, dt}}; x = new[,]{{0.0f}, {0.0f}}; z = new[,]{{0.0f}, {0.0f}}; u = new[,]{{1.0f}, {1.0f}}; s_sigma = new[,]{ {0.1f, 0}, {0, 0.1f}}; o_sigma = new[,]{ {0.1f, 0}, {0, 0.1f}}; sigma = o_sigma [0, 0]; Kai = new float[2, M]; Kai_bar = new float[3, M]; w = new float[M]; for (int j = 0; j < 2; j++) for (int i = 0; i < M; i++) Kai [j, i] = 0; for (int j = 0; j < 3; j++) for (int i = 0; i < M; i++) Kai_bar [j, i] = 0; for (int i = 0; i < M; i++) w [i] = 1.0f / M; }
bool resample(particle_type[] particles) { // 累積重みの計算. float[] weights = new float[particles.Length]; weights [0] = particles [0].weight; for (int i = 1; i < weights.Length; i++) weights [i] = weights [i - 1] + particles [i].weight; // 重みを基準にパーティクルをリサンプリングして重みを1.0に. particle_type[] tmp_particles = particles; for (int i = 0; i < particles.Length; i++) { // float weight = nrnd.NextDouble() * weights[weights.Length - 1]; // float weight = Mathf.Abs(nrnd.NextDouble()) * weights[weights.Length - 1]; float weight = Random.Range (-0.1f, 0.1f) * weights [weights.Length - 1]; int n = 0; while (weights[++n] < weight) ; particles [i] = tmp_particles [n]; particles [i].weight = 1.0f; } return true; }
bool predict(particle_type[] particles) { float variance = 13.0f; // 位置の予測. // 「次状態もほぼ同じ位置(ほとんど動かない)」と仮定、分散(13.0)は実験的に決定. for (int i = 0; i < particles.Length; i++) { float vx = Random.Range (0.0f, 1.0f) * variance; float vy = Random.Range (0.0f, 1.0f) * variance; particles [i].x += (int)vx; particles [i].y += (int)vy; } return true; }
particle_type measure(particle_type[] particles) { float x = 0; float y = 0; float weight = 0; // 重み和. for (int i = 0; i < particles.Length; i++) { x += particles [i].x * particles [i].weight; y += particles [i].y * particles [i].weight; weight += particles [i].weight; } // 正規化. return new particle_type ((int)(x / weight), (int)(y / weight), 1); }