Beispiel #1
0
double R3Distance(const R3Point& point, const R3Line& line)
{
  // Return distance from point to line (Riddle p. 904)
  R3Vector v = line.Vector();
  v.Cross(point - line.Point());
  return v.Length();
}
Beispiel #2
0
double R3Distance(const R3Line& line1, const R3Line& line2)
{
  // Return distance from line to line (Riddle p. 905)
  R3Vector v = line1.Vector();
  v.Cross(line2.Vector());
  return v.Dot(line1.Point() - line2.Point());
}
Beispiel #3
0
R3Vector 
operator%(const R3Vector& vector1, const R3Vector& vector2)
{
  // Return cross product of two vectors
  R3Vector v = vector1;
  v.Cross(vector2);
  return v;
}
Beispiel #4
0
R3Point SpawnLocation() {
    R3Point playerPos = globals.player->GetPosition();
    R3Vector playerDir = globals.player->GetDirection();
    R3Vector playerLeft = R3Vector(R3posy_vector);
    playerLeft.Cross(playerDir);
    return playerPos + Util::SymmetricRandom() * 15.0 * playerLeft + 
                        Util::SymmetricRandom() * 15.0 * R3posy_vector + 
                        (Util::UnitRandom() + 0.3) * 100.0 * playerDir;
}
Beispiel #5
0
const RNBoolean R3Point::
Collinear(const R3Point& point1, const R3Point& point2) const
{
    // Check if two of points are same
    if ((*this == point1) || (*this == point2) || (point1 == point2)) return TRUE;

    /// Check if three points are collinear
    R3Vector v = point1 - *this;
    v.Cross(point1 - point2);
    if (RNIsZero(v.Length())) return TRUE;
    return FALSE;
}
Beispiel #6
0
int IntersectMesh(R3Mesh *m, R3Ray r, R3Point *position, R3Vector *normal, double *t) {
	*t = DBL_MAX;
	for(int i=0; i < m->NFaces(); i++) {
		R3MeshFace *f = m->Face(i);
		if(f->vertices.size() != 3) continue;
		
		R3Vector trianglenormal = (f->vertices[1]->position - f->vertices[0]->position);
		trianglenormal.Cross(f->vertices[2]->position - f->vertices[0]->position);
		trianglenormal.Normalize();

		R3Plane triangleplane(f->vertices[0]->position, trianglenormal);

		R3Point intersectionpoint;
		double t_intersection;
		if(IntersectPlane(&triangleplane, r, &intersectionpoint, &trianglenormal, &t_intersection) !=0 ) {
			// check inside triangle
			int withintriangle = 1;
			for(int j=0; j<3; j++) {
				R3Vector v1 = f->vertices[j%3]->position - r.Start();
				R3Vector v2 = f->vertices[(j+1)%3]->position - r.Start();
				R3Vector n1 = v2;
				n1.Cross(v1);
				n1.Normalize();
				R3Plane p(r.Start(), n1);
				if(R3SignedDistance(p, intersectionpoint) < 0) {
					withintriangle = 0;
					break;
				}
			}
			
			if(withintriangle == 1 && t_intersection > 0 && t_intersection < *t) {
				*t = t_intersection;
				*position = intersectionpoint;
				*normal = trianglenormal;
			}
		}

	}

	if(*t < DBL_MAX) {
		return 1;
	}
	else {
		return 0;
	}
}
Beispiel #7
0
void GenerateParticles(R3Scene *scene, double current_time, double delta_time)
{
    for (int i = 0; i < scene->NParticleSources(); i++) {
        
        R3ParticleSource *source = scene->ParticleSource(i);
        
        // spheres
        if (source->shape->type == R3_SPHERE_SHAPE) {
            
            // remainder term for fraction of particle
            double numberweshouldmake = delta_time * source->rate + source->remainder;
            int nparts = (int) floor(numberweshouldmake);
            source->remainder = numberweshouldmake - nparts;
            
            for (int p = 0; p < nparts; p++) {
                R3Particle *newpart = new R3Particle();
                
                // calculate position and velocity
                double u = RandomNumber();
                double theta = 2*PI*u;
                double v = RandomNumber();
                double phi = acos(2*v-1);
                double r = source->shape->sphere->Radius();
                R3Point center = source->shape->sphere->Center();
                
                double x = r*cos(theta)*sin(phi);
                double y = r*sin(theta)*sin(phi);
                double z = r*cos(phi);
                
                R3Vector n = R3Vector(x,y,z);
                n.Normalize();
                
                // find tangent vector, use lecture notes to get velocity
                R3Plane plane = R3Plane(R3Point(0,0,0),n);
                R3Vector a;
                do {
                    a = R3Vector(RandomNumber(),RandomNumber(),RandomNumber());
                    a.Project(plane);
                } while (a.Length() == 0.0);
                a.Normalize();
                double t1 = 2*PI*RandomNumber();
                double t2 = sin(source->angle_cutoff)*RandomNumber();
                a.Rotate(n,t1);
                R3Vector vec = R3Vector(a);
                R3Vector cross = R3Vector(vec);
                cross.Cross(n);
                vec.Rotate(cross,acos(t2));
                
                newpart->position = center + n*r;
                newpart->velocity = vec*source->velocity;
                
                //update
                newpart->mass = source->mass;
                newpart->fixed = source->fixed;
                newpart->drag = source->drag;
                newpart->elasticity = source->elasticity;
                newpart->lifetime = source->lifetime;
                newpart->lifetimeactive = source->lifetimeactive;
                newpart->material = source->material;
                
                scene->particles.push_back(newpart);
            }
        }
        

        // CIRCLE
        if (source->shape->type == R3_CIRCLE_SHAPE) {
            double numberweshouldmake = delta_time * source->rate + source->remainder;
            int nparts = (int) floor(numberweshouldmake);
            source->remainder = numberweshouldmake - nparts;
            
            for (int p = 0; p < nparts; p++) {
                R3Particle *newpart = new R3Particle();
                
                // calculate position and velocity
                
                double r = source->shape->circle->Radius();
                R3Point center = source->shape->circle->Center();
                R3Plane plane = source->shape->circle->Plane();
                R3Vector n = plane.Normal();
                n.Normalize();
                
                // get a random point on a circle
                double xcirc, ycirc;
                do {
                    xcirc = 2*r*(RandomNumber() - 0.5);
                    ycirc = 2*r*(RandomNumber() - 0.5);
                } while (xcirc*xcirc + ycirc*ycirc > r*r);
                
                // get basis vectors of circle
                R3Vector tang;
                do {
                    tang = R3Vector(RandomNumber(),RandomNumber(),RandomNumber());
                    tang.Project(plane);
                } while (tang.Length() == 0.0);
                R3Vector othertang = R3Vector(tang);
                othertang.Cross(n);
                othertang.Normalize();
                tang.Normalize();
                
                R3Point pos = center + tang*xcirc + othertang*ycirc;
                
                
                R3Vector a = R3Vector(tang);
                double t1 = 2*PI*RandomNumber();
                double t2 = sin(source->angle_cutoff)*RandomNumber();
                a.Rotate(n,t1);
                R3Vector vec = R3Vector(a);
                R3Vector cross = R3Vector(vec);
                cross.Cross(n);
                vec.Rotate(cross,acos(t2));
                
                newpart->position = pos;
                newpart->velocity = vec*source->velocity;
                
                
                newpart->mass = source->mass;
                newpart->fixed = source->fixed;
                newpart->drag = source->drag;
                newpart->elasticity = source->elasticity;
                newpart->lifetime = source->lifetime;
                newpart->lifetimeactive = source->lifetimeactive;
                newpart->material = source->material;
                
                scene->particles.push_back(newpart);
            }
        }
        
    }
	
	
	 for (int i = 0; i < (int)scene->enemies.size(); i++) {
        
        R3Enemy *enemy = scene->enemies[i];
        
        // spheres
        if (enemy->shape->type == R3_SPHERE_SHAPE) {
            
            // remainder term for fraction of particle
            double numberweshouldmake = delta_time * enemy->rate + enemy->remainder;
            int nparts = (int) floor(numberweshouldmake);
            enemy->remainder = numberweshouldmake - nparts;
            
            for (int p = 0; p < nparts; p++) {
                R3Particle *newpart = new R3Particle();
                
                // calculate position and velocity
                double u = RandomNumber();
                double theta = 2*PI*u;
                double v = RandomNumber();
                double phi = acos(2*v-1);
                double r = enemy->shape->sphere->Radius();
                R3Point center = enemy->shape->sphere->Center();
                
                double x = r*cos(theta)*sin(phi);
                double y = r*sin(theta)*sin(phi);
                double z = r*cos(phi);
                
                R3Vector n = R3Vector(x,y,z);
                n.Normalize();
                
                // find tangent vector, use lecture notes to get velocity
                R3Plane plane = R3Plane(R3Point(0,0,0),n);
                R3Vector a;
                do {
                    a = R3Vector(RandomNumber(),RandomNumber(),RandomNumber());
                    a.Project(plane);
                } while (a.Length() == 0.0);
                a.Normalize();
                double t1 = 2*PI*RandomNumber();
                double t2 = sin(enemy->angle_cutoff)*RandomNumber();
                a.Rotate(n,t1);
                R3Vector vec = R3Vector(a);
                R3Vector cross = R3Vector(vec);
                cross.Cross(n);
                vec.Rotate(cross,acos(t2));
                
                newpart->position = center + n*r;
                newpart->velocity = vec*enemy->velocity;
                
                //update
                newpart->mass = enemy->mass;
                newpart->fixed = enemy->fixed;
                newpart->drag = enemy->drag;
                newpart->elasticity = enemy->elasticity;
                newpart->lifetime = enemy->lifetime;
                newpart->lifetimeactive = enemy->lifetimeactive;
                newpart->material = enemy->material;
                
                scene->particles.push_back(newpart);
            }
        }
        
        
        // CIRCLE
        if (enemy->shape->type == R3_CIRCLE_SHAPE) {
            
            double numberweshouldmake = delta_time * enemy->rate + enemy->remainder;
            int nparts = (int) floor(numberweshouldmake);
            enemy->remainder = numberweshouldmake - nparts;
            
            for (int p = 0; p < nparts; p++) {
                R3Particle *newpart = new R3Particle();
                
                // calculate position and velocity
                
                double r = enemy->shape->circle->Radius();
                R3Point center = enemy->shape->circle->Center();
                R3Plane plane = enemy->shape->circle->Plane();
                R3Vector n = plane.Normal();
                n.Normalize();
                
                // get a random point on a circle
                double xcirc, ycirc;
                do {
                    xcirc = 2*r*(RandomNumber() - 0.5);
                    ycirc = 2*r*(RandomNumber() - 0.5);
                } while (xcirc*xcirc + ycirc*ycirc > r*r);
                
                // get basis vectors of circle
                R3Vector tang;
                do {
                    tang = R3Vector(RandomNumber(),RandomNumber(),RandomNumber());
                    tang.Project(plane);
                } while (tang.Length() == 0.0);
                R3Vector othertang = R3Vector(tang);
                othertang.Cross(n);
                othertang.Normalize();
                tang.Normalize();
                
                R3Point pos = center + tang*xcirc + othertang*ycirc;
                
                
                R3Vector a = R3Vector(tang);
                double t1 = 2*PI*RandomNumber();
                double t2 = sin(enemy->angle_cutoff)*RandomNumber();
                a.Rotate(n,t1);
                R3Vector vec = R3Vector(a);
                R3Vector cross = R3Vector(vec);
                cross.Cross(n);
                vec.Rotate(cross,acos(t2));
                
                newpart->position = pos;
                newpart->velocity = vec * 1.0;
                
                
                newpart->mass = enemy->mass;
                newpart->fixed = enemy->fixed;
                newpart->drag = enemy->drag;
                newpart->elasticity = enemy->elasticity;
                newpart->lifetime = enemy->lifetime;
                newpart->lifetimeactive = enemy->lifetimeactive;
                newpart->material = enemy->material;
                
                scene->particles.push_back(newpart);
            }
        }
        
    }
	
    
}
////////////////////////////////////////////////////////////
// Generating Particles
////////////////////////////////////////////////////////////
   void GenerateParticles(R3Scene *scene, double current_time, double delta_time)
   {
   // Generate new particles for every source
      R3ParticleSource* source;
      for (int i = 0; i < scene->NParticleSources(); i++)
      {
         source = scene->ParticleSource(i);
         int num_particles = source->elapsed_time * source->rate;
      	
         if ((num_particles) >= 1)
         {
            source->elapsed_time = 0;
         	
            for (int m = 0; m < num_particles; m++)
            {
               if (source->shape->type == R3_SEGMENT_SHAPE)
               {
                  R3Segment* seg = source->shape->segment;
                  R3Point pos = seg->Start() + RandomNumber() * (seg->End() - seg->Start());
                  R3Vector dir = seg->Vector();
                  dir.Cross(R3Vector(RandomNumber() - .5, RandomNumber() - .5, RandomNumber() - .5));
                  dir.Normalize();
               	
                  R3Particle* particle = new R3Particle();
                  particle->position = pos;
                  particle->velocity = source->velocity * dir;
                  particle->mass = source->mass;
                  particle->fixed = source->fixed;
                  particle->drag = source->drag;
                  particle->elasticity = source->elasticity;
                  particle->lifetime = source->lifetime;
                  particle->material = source->material; 
               
                  scene->particles.push_back(particle);
               }
            
               if (source->shape->type == R3_BOX_SHAPE)
               {
                  R3Particle* particle = generate_random_box_particle(source);
                  scene->particles.push_back(particle);
               }
               
               else if (source->shape->type == R3_MESH_SHAPE)
               {
                  R3Mesh* mesh = source->shape->mesh;
                  double area_sum = 0.0;
                  double face_prob[mesh->faces.size()];
               
                  for (unsigned int i = 0; i < mesh->faces.size(); i++)
                  {
                     face_prob[i] = mesh->faces[i]->Area();
                     area_sum += face_prob[i];
                  }
                  for (unsigned int i = 0; i < mesh->faces.size(); i++)
                     face_prob[i] /= area_sum;	
               	
                  int source_face = discrete(face_prob, mesh->faces.size());
                  int num_verts = mesh->faces[source_face]->vertices.size();
                
                	R3Point pos = R3Point(0,0,0);
                     R3Vector dir = R3Vector(0,0,0);
                  if (num_verts == 3)
                  {
                     double a = 0;
                     double b = 0;
                     double c;
                     while (a + b <= 1)
                     {
                        a = RandomNumber();
                        b = RandomNumber();  
                     }
                  
                     a = 1 - a;
                     b = 1 - b;
                     c = 1 - a - b;
                  
                     pos = a * mesh->faces[source_face]->vertices[0]->position
                        + b * mesh->faces[source_face]->vertices[1]->position
                        + c * mesh->faces[source_face]->vertices[2]->position;
                     mesh->faces[source_face]->vertices[0]->UpdateNormal();
                     mesh->faces[source_face]->vertices[1]->UpdateNormal();
                     mesh->faces[source_face]->vertices[2]->UpdateNormal();
                  
                     dir = a * mesh->faces[source_face]->vertices[0]->normal
                        + b * mesh->faces[source_face]->vertices[0]->normal
                        + c * mesh->faces[source_face]->vertices[0]->normal;
                  }
                  else
                  {
                     int num_verts = mesh->faces[source_face]->vertices.size();
                     double vert_sum = 0.0;
                     double vert_prob[num_verts];
                  
                     for (int i = 0; i < num_verts; i++)
                     {
                        vert_prob[i] = RandomNumber();
                        vert_sum += vert_prob[i];
                     }
                  
                     R3Point pos = R3Point(0,0,0);
                     R3Vector dir = R3Vector(0,0,0);
                     for (int i = 0; i < num_verts; i++)
                     {
                        vert_prob[i] /= vert_sum;
                        pos += vert_prob[i] * mesh->faces[source_face]->vertices[i]->position;
                        mesh->faces[source_face]->vertices[i]->UpdateNormal();
                        dir += vert_prob[i] * mesh->faces[source_face]->vertices[i]->normal;
                     }
                  }
               
                  dir.Normalize();
               
                  R3Particle* particle = new R3Particle();
                  particle->position = pos;
                  particle->velocity = source->velocity * dir;
                  particle->mass = source->mass;
                  particle->fixed = source->fixed;
                  particle->drag = source->drag;
                  particle->elasticity = source->elasticity;
                  particle->lifetime = source->lifetime;
                  particle->material = source->material; 
               
                  scene->particles.push_back(particle);
               	
               }
               else if (source->shape->type == R3_SPHERE_SHAPE)
               {
                  R3Sphere* sphere = source->shape->sphere;
                  double radius = sphere->Radius();
                  R3Point center = sphere->Center();
               
                  double z = (RandomNumber() * 2 - 1);
                  double t = RandomNumber() * 2 * PI;
               
                  double r = sqrt(1.0 - z*z);
                  double x = r * cos(t) * radius;
                  double y = r * sin(t) * radius;
               
                  R3Point pos = R3Point(center.X() + x, center.Y() + y, center.Z() + z*radius);
                  R3Vector dir = (pos - center);
                  dir.Normalize();
               
                  R3Particle* particle = new R3Particle();
                  particle->position = pos;
                  particle->velocity = source->velocity * dir;
                  particle->mass = source->mass;
                  particle->fixed = source->fixed;
                  particle->drag = source->drag;
                  particle->elasticity = source->elasticity;
                  particle->lifetime = source->lifetime;
                  particle->material = source->material; 
               
                  scene->particles.push_back(particle);
               }
            }
         }
         else
            source->elapsed_time += delta_time;
      }
   }
// compute area between three points
double Area(R3Point p1, R3Point p2, R3Point p3)
{
  R3Vector v = p2 - p1;
  v.Cross(p3 - p1);
  return v.Length() / 2;
}
// compute intersection between a triangle face and a ray
R3Intersection ComputeIntersection(R3MeshFace *tri, R3Ray &ray, double min_t)
{
  assert (tri->vertices.size() == 3);

  R3Intersection i;

  R3Point t1 = tri->vertices[0]->position;
  R3Point t2 = tri->vertices[1]->position;
  R3Point t3 = tri->vertices[2]->position;

  // intersect ray with triangle's plane
  R3Plane plane = tri->plane;
  double t = -(ray.Start().Vector().Dot(plane.Normal()) + plane.D()) 
    / (ray.Vector().Dot(plane.Normal()));

  // early return if not closer than minimum intersection for the mesh
  if (t > min_t || t < 0)
  {
    i.hit = false;
    return i;
  }


  // check if intersection is within triangle using barycentric coordinate method
  R3Point p = ray.Point(t);

  R3Vector v;

  v = t2 - t1;
  v.Cross(t3 - t1);
  double area = v.Length() / 2;

  v = t2 - t1;
  v.Cross(p - t1);
  if (v.Dot(plane.Normal()) < 0)
  {
    i.hit = false;
    return i;
  }
  double a = v.Length() / (2 * area);

  v = p - t1;
  v.Cross(t3 - t1);
  if (v.Dot(plane.Normal()) < 0)
  {
    i.hit = false;
    return i;
  }
  double b = v.Length() / (2 * area);

  if (a <= 1 && a >= 0 && b <= 1 && b >= 0 && a + b <= 1)
  {
    i.hit = true;
    if (ray.Vector().Dot(plane.Normal()) < 0)
    {
      i.normal = plane.Normal();
    }
    else
    {
      i.normal = -plane.Normal();
    }
    i.position = p;
    i.t = t;
    return i;
  } 
  else
  {
    i.hit = false;
    return i;
  }
}