Exemplo n.º 1
0
    private int InitWindParticle(ref WindParticle p, Vector3 startPosition, Vector3 startDirection)
    {
        p.id       = _particleId;
        p.position = startPosition;
        p.dir      = startDirection;
        p.velocity = windVelocity;
        p.mass     = windParticleMass;
        p.alive    = true;
        p.color    = Color.black;
        p.hasEnteredTargetBounds = false;

        _particleId++;

        return(p.id);
    }
Exemplo n.º 2
0
	public void investigateMap() { // Werte für aktuelle Landschaft in abhängigkeit zu Werten ermitteln und speichern
		Gradient colorArea = new Gradient ();
		particle = new WindParticle(0, position, 99999, direction, 0.1f, 999, startTemperature, startSaturation, colorArea); // create WindParticle
		
		temperatures[0] = startTemperature;
		saturations[0] = startSaturation;
		heights[0] = (position.y-particle.groundHeight)/particle.scale;
		
		int n = 0;
		while (n+1 < steps) {
			particle.move();
			if(Vector3.Distance(new Vector3(particle.position.x,0,particle.position.z),new Vector3(position.x,0,position.z)) >= stepMap[n]) { // if actual position is nearest to calculated distance for actual step...
				temperatures[n+1] = particle.temperature;
				saturations[n+1] = particle.getFRel();
				heights[n+1] = (particle.position.y-particle.groundHeight)/particle.scale;
				n++;
			}
		}
	}
Exemplo n.º 3
0
	private void addParticle(int id, Vector3 position) {
		particles[id] = new WindParticle(id, position, maxDistanceFromSource, direction, speed, maxMountainHeight, temperature, saturation, colorArea);
	}
Exemplo n.º 4
0
    void UpdateWindParticles()
    {
        for (int i = 0; i < _activeParticleCount; i++)
        {
            WindParticle particle = _particles[i];
            if (!particle.alive)
            {
                continue;
            }

            List <Vector3> path = renderParticlePaths ? _particlePaths[particle.id] : null;

            //
            //  Particles are allowd to move into the target bounds, but when they exit it
            //  they are done with simulation. If a particle velocity drops to zero it is
            //  also all done. Pruning will periodically clear out dead particles.
            //

            if (!particle.hasEnteredTargetBounds)
            {
                if ((particle.position - _particlePruningBoundsOrigin).sqrMagnitude <= _particlePruningBoundsRadius2)
                {
                    particle.hasEnteredTargetBounds = true;
                }
            }
            else
            {
                if ((particle.position - _particlePruningBoundsOrigin).sqrMagnitude > _particlePruningBoundsRadius2)
                {
                    // we're done here
                    particle.alive = false;
                    _particles[i]  = particle;
                    continue;
                }
            }

            //
            //  compute the travel of the particle this step. Run raycasts.
            //  If there's a collision, update particle direction and velocity
            //

            Vector3 nextPosition     = particle.position + (particle.dir * particle.velocity * Time.deltaTime);
            float   distanceTraveled = Vector3.Distance(nextPosition, particle.position);
            int     hitCount         = Physics.RaycastNonAlloc(new Ray(particle.position, particle.dir), _raycastHits, distanceTraveled, windTargetLayer, QueryTriggerInteraction.Ignore);

            for (int hit = 0; hit < hitCount; hit++)
            {
                //
                // we have a collision - apply impulse and deflect and reduce power of the particle
                // compute the reflection (this is the new particle direction) and the incidence
                // incidence goeas from -1 to 1 where -1 means we hit square on, and 1 means we
                // perfectly grazed the surface imparting no energy
                //

                RaycastHit hitInfo = _raycastHits[hit];

                // first add intersection point to the path so we can render it
                if (renderParticlePaths)
                {
                    path.Add(hitInfo.point);
                }

                Vector3 reflection = Vector3.Reflect(particle.dir, hitInfo.normal);
                float   incidence  = Vector3.Dot(particle.dir, reflection);

                // remap the incidence such that a value of 1 means full energy transfer and 0 means none
                float   energyTransfer = 1 - ((incidence + 1f) / 2f);
                Vector3 force          = particle.dir * particle.velocity * particle.mass * energyTransfer;

                hitInfo.rigidbody.AddForceAtPosition(force, hitInfo.point, ForceMode.Impulse);

                // reduce particle velocity
                particle.velocity *= 1 - energyTransfer;
                particle.dir       = reflection;
                particle.alive     = particle.velocity > minVelocity;

                // update the particle position along the path up to collision and then the
                // remaining distance along the reflection
                nextPosition = hitInfo.point + (reflection * Mathf.Max(distanceTraveled - hitInfo.distance, 0.01f));
            }

            //
            // update the particle and store
            //

            particle.position = nextPosition;
            if (renderParticlePaths)
            {
                path.Add(nextPosition);
            }
            _particles[i] = particle;

            //
            // now draw this particle's path
            //

            if (renderParticlePaths)
            {
                Vector3 a = path[0];
                for (int j = 1, N = path.Count; j < N; j++)
                {
                    Vector3 b = path[j];
                    RuntimeDebugDraw.Draw.DrawLine(a, b, particle.color);
                    a = b;
                }
            }
        }
    }