Ejemplo n.º 1
0
RNBoolean R3Contains(const R3Plane& plane, const R3Sphere& sphere)
{
    // Return whether plane contains sphere 
    if (!sphere.IsPoint()) return FALSE;
    if (!R3Contains(plane, sphere.Center())) return FALSE;
    return TRUE;
}
Ejemplo n.º 2
0
RNBoolean R3Contains(const R3Span& span, const R3Sphere& sphere)
{
    // Return whether span contains sphere 
    if (!sphere.IsPoint()) return FALSE;
    if (!R3Contains(span, sphere.Center())) return FALSE;
    return TRUE;
}
Ejemplo n.º 3
0
RNBoolean R3Contains(const R3Ray& ray, const R3Sphere& sphere)
{
    // Return whether ray contains sphere 
    if (!sphere.IsPoint()) return FALSE;
    if (!R3Contains(ray, sphere.Center())) return FALSE;
    return TRUE;
}
   static R3Vector calculate_sink_force(R3Scene* scene, R3Particle* particle)
   {
      R3ParticleSink* sink;
      R3Vector force = R3Vector(0,0,0);  
   	
      for (int i = 0; i < scene->NParticleSinks(); i++)
      {
         sink = scene->ParticleSink(i);
      	
         if (sink->shape->type == R3_SPHERE_SHAPE)
         {
            R3Sphere* sphere = sink->shape->sphere;
            R3Point center = sphere->Center();
            
            R3Vector f = -(particle->position - center);
            double d = f.Length() - sphere->Radius();
            f.Normalize();
         	
            double mag = sink->intensity / (sink->constant_attenuation + 
               						sink->linear_attenuation*d + 
               						sink->quadratic_attenuation*d*d);
            force += f*mag;
         }
         else if (sink->shape->type == R3_MESH_SHAPE)
      	{
      		R3Mesh* mesh = sink->shape->mesh;
      		R3Point center = R3Point(0,0,0);
      		for (unsigned int j = 0; j < mesh->vertices.size(); j++)
      		{
      			center += mesh->vertices[i]->position / mesh->vertices.size();
      		}
      		R3Vector f = -(particle->position - center);
            double d = f.Length();
            f.Normalize();
         	
            double mag = sink->intensity / (sink->constant_attenuation + 
               						sink->linear_attenuation*d + 
               						sink->quadratic_attenuation*d*d);
            force += f*mag;
      	}
      	else if (sink->shape->type == R3_BOX_SHAPE)
      	{
      		R3Box* box = sink->shape->box;
      		R3Point center = R3Point((box->XMax() - box->XMin())/2 + box->XMin(),
      										 (box->YMax() - box->YMin())/2 + box->YMin(),
      										 (box->ZMax() - box->ZMin())/2 + box->ZMin());
      		R3Vector f = -(particle->position - center);
            double d = f.Length();
            f.Normalize();
         	
            double mag = sink->intensity / (sink->constant_attenuation + 
               						sink->linear_attenuation*d + 
               						sink->quadratic_attenuation*d*d);
            force += f*mag;

      	}
      }
      return force;
   }
Ejemplo n.º 5
0
RNBoolean R3Contains(const R3Sphere& sphere, const R3Point& point)
{
    // Return whether sphere contains point
    RNScalar radius_squared = sphere.Radius() * sphere.Radius();
    R3Vector v = sphere.Center() - point;
    RNScalar distance_squared = v.X() * v.X() + v.Y() * v.Y() + v.Z() * v.Z();
    return RNIsLessOrEqual(distance_squared, radius_squared);
}
Ejemplo n.º 6
0
RNBoolean R3Contains(const R3Sphere& sphere, const R3Box& box)
{
    // Return whether sphere contains box 
    R3Vector v = box.Centroid() - sphere.Center();
    R3Point corner = box.Corner(v.Octant());
    return R3Contains(sphere, corner);
}
Ejemplo n.º 7
0
RNBoolean R3Contains(const R3Box& box, const R3Sphere& sphere)
{
    // Return whether box contains sphere 
    if (box.IsEmpty()) return FALSE;
    if (sphere.IsEmpty()) return TRUE;
    if (RNIsLess(sphere.Center().X() - sphere.Radius(), box.XMin())) return FALSE;
    if (RNIsLess(sphere.Center().Y() - sphere.Radius(), box.YMin())) return FALSE;
    if (RNIsLess(sphere.Center().Z() - sphere.Radius(), box.ZMin())) return FALSE;
    if (RNIsGreater(sphere.Center().X() + sphere.Radius(), box.XMax())) return FALSE;
    if (RNIsGreater(sphere.Center().Y() + sphere.Radius(), box.YMax())) return FALSE;
    if (RNIsGreater(sphere.Center().Z() + sphere.Radius(), box.ZMax())) return FALSE;
    return TRUE;
}
Ejemplo n.º 8
0
 static bool in_sink(R3Scene* scene, R3Particle* particle, double delta_time)
 {
    R3ParticleSink* sink;
 	
    for (int i = 0; i < scene->NParticleSinks(); i++)
    {
       sink = scene->ParticleSink(i);
    	
       if (sink->shape->type == R3_SPHERE_SHAPE)
       {
          R3Sphere* sphere = sink->shape->sphere;
          R3Point center = sphere->Center();
          double radius = sphere->Radius();  
       	
          if ((particle->position - center).Length() < radius)
             return true;
       }
       else if (sink->shape->type == R3_MESH_SHAPE)
    	{
    		R3Ray ray = R3Ray(particle->position, particle->velocity);
    		
    		R3Node node;
    		node.shape = sink->shape;
    		
    		R3Intersection inter = IntersectMesh(&node, &ray);
    		
    		if (inter.hit == true
    		&&  inter.t <= ((particle->velocity).Length() * (delta_time) * 2))
    			return true;
    	}
    	else if (sink->shape->type == R3_BOX_SHAPE)
    	{
    	 	R3Box* box = sink->shape->box;
    		if (particle->position.Z() < box->ZMax() && particle->position.Z() > box->ZMin()
          &&  particle->position.Y() < box->YMax() && particle->position.Y() > box->YMin()
          &&  particle->position.X() < box->XMax() && particle->position.X() > box->XMin())
             return true;
    	}
    }
    return false;
 }
Ejemplo n.º 9
0
////////////////////////////////////////////////////////////
// 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;
      }
   }
Ejemplo n.º 10
0
void R3Box::
Union (const R3Sphere& sphere) 
{
    // Expand this to include sphere
    Union(sphere.BBox());
}
Ejemplo n.º 11
0
int R3Scene::
Read(const char *filename, R3Node *node)
{
    // Open file
    FILE *fp;
    if (!(fp = fopen(filename, "r"))) {
        fprintf(stderr, "Unable to open file %s", filename);
        return 0;
    }
    
    // Create array of materials
    vector<R3Material *> materials;
    
    // Create default material
    R3Material *default_material = new R3Material();
    default_material->ka = R3Rgb(0.2, 0.2, 0.2, 1);
    default_material->kd = R3Rgb(0.5, 0.5, 0.5, 1);
    default_material->ks = R3Rgb(0.5, 0.5, 0.5, 1);
    default_material->kt = R3Rgb(0.0, 0.0, 0.0, 1);
    default_material->emission = R3Rgb(0, 0, 0, 1);
    default_material->shininess = 10;
    default_material->indexofrefraction = 1;
    default_material->texture = NULL;
    default_material->id = 0;
    
    // Create stack of group information
    const int max_depth = 1024;
    R3Node *group_nodes[max_depth] = { NULL };
    R3Material *group_materials[max_depth] = { NULL };
    group_nodes[0] = (node) ? node : root;
    group_materials[0] = default_material;
    int depth = 0;
    
    // Read body
    char cmd[128];
    int command_number = 1;
    while (fscanf(fp, "%s", cmd) == 1) {
        if (cmd[0] == '#') {
            // Comment -- read everything until end of line
            do { cmd[0] = fgetc(fp); } while ((cmd[0] >= 0) && (cmd[0] != '\n'));
        }
        else if (!strcmp(cmd, "tri")) {
            // Read data
            int m;
            R3Point p1, p2, p3;
            if (fscanf(fp, "%d%lf%lf%lf%lf%lf%lf%lf%lf%lf", &m, 
                       &p1[0], &p1[1], &p1[2], &p2[0], &p2[1], &p2[2], &p3[0], &p3[1], &p3[2]) != 10) {
                fprintf(stderr, "Unable to read triangle at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at tri command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Create mesh
            R3Mesh *mesh = new R3Mesh();
            vector<R3MeshVertex *> vertices;
            vertices.push_back(mesh->CreateVertex(p1, R3zero_vector, R2zero_point));
            vertices.push_back(mesh->CreateVertex(p2, R3zero_vector, R2zero_point));
            vertices.push_back(mesh->CreateVertex(p3, R3zero_vector, R2zero_point));
            mesh->CreateFace(vertices);
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_MESH_SHAPE;
            shape->box = NULL;
            shape->sphere = NULL;
            shape->cylinder = NULL;
            shape->cone = NULL;
            shape->mesh = mesh;
            shape->segment = NULL;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = R3null_box;
            node->bbox.Union(p1);
            node->bbox.Union(p2);
            node->bbox.Union(p3);
            node->enemy = NULL;
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        }
        else if (!strcmp(cmd, "box")) {
            // Read data
            int m;
            R3Point p1, p2;
            if (fscanf(fp, "%d%lf%lf%lf%lf%lf%lf", &m, &p1[0], &p1[1], &p1[2], &p2[0], &p2[1], &p2[2]) != 7) {
                fprintf(stderr, "Unable to read box at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at box command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Create box
            R3Box *box = new R3Box(p1, p2);
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_BOX_SHAPE;
            shape->box = box;
            shape->sphere = NULL;
            shape->cylinder = NULL;
            shape->cone = NULL;
            shape->mesh = NULL;
            shape->segment = NULL;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = *box;
            node->enemy = NULL;
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        }
        else if (!strcmp(cmd, "sphere")) {
            // Read data
            int m;
            R3Point c;
            double r;
            if (fscanf(fp, "%d%lf%lf%lf%lf", &m, &c[0], &c[1], &c[2], &r) != 5) {
                fprintf(stderr, "Unable to read sphere at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at sphere command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Create sphere
            R3Sphere *sphere = new R3Sphere(c, r);
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_SPHERE_SHAPE;
            shape->box = NULL;
            shape->sphere = sphere;
            shape->cylinder = NULL;
            shape->cone = NULL;
            shape->mesh = NULL;
            shape->segment = NULL;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = sphere->BBox();
            node->enemy = NULL;
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        }
        else if (!strcmp(cmd, "cylinder")) {
            // Read data
            int m;
            R3Point c;
            double r, h;
            if (fscanf(fp, "%d%lf%lf%lf%lf%lf", &m, &c[0], &c[1], &c[2], &r, &h) != 6) {
                fprintf(stderr, "Unable to read cylinder at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at cyl command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Create cylinder
            R3Cylinder *cylinder = new R3Cylinder(c, r, h);
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_CYLINDER_SHAPE;
            shape->box = NULL;
            shape->sphere = NULL;
            shape->cylinder = cylinder;
            shape->cone = NULL;
            shape->mesh = NULL;
            shape->segment = NULL;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = cylinder->BBox();
            node->enemy = NULL;
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        }
        else if (!strcmp(cmd, "mesh")) {
            // Read data
            int m;
            char meshname[256];
            if (fscanf(fp, "%d%s", &m, meshname) != 2) {
                fprintf(stderr, "Unable to parse mesh command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at cone command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Get mesh filename
            char buffer[2048];
            strcpy(buffer, filename);
            char *bufferp = strrchr(buffer, '/');
            if (bufferp) *(bufferp+1) = '\0';
            else buffer[0] = '\0';
            strcat(buffer, meshname);
            
            // Create mesh
            R3Mesh *mesh = new R3Mesh();
            if (!mesh) {
                fprintf(stderr, "Unable to allocate mesh\n");
                return 0;
            }
            
            // Read mesh file
            if (!mesh->Read(buffer)) {
                fprintf(stderr, "Unable to read mesh: %s\n", buffer);
                return 0;
            }
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_MESH_SHAPE;
            shape->box = NULL;
            shape->sphere = NULL;
            shape->cylinder = NULL;
            shape->cone = NULL;
            shape->mesh = mesh;
            shape->segment = NULL;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = mesh->bbox;
            node->enemy = NULL;
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        }
        //in order to set the arwing node as a global in GlutTest.cpp
        else if (!strcmp(cmd, "arwing")) {
            // Read data
            int m;
            char meshname[256];
            if (fscanf(fp, "%d%s", &m, meshname) != 2) {
                fprintf(stderr, "Unable to parse mesh command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at cone command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Get mesh filename
            char buffer[2048];
            strcpy(buffer, filename);
            char *bufferp = strrchr(buffer, '/');
            if (bufferp) *(bufferp+1) = '\0';
            else buffer[0] = '\0';
            strcat(buffer, meshname);
            
            // Create mesh
            R3Mesh *mesh = new R3Mesh();
            if (!mesh) {
                fprintf(stderr, "Unable to allocate mesh\n");
                return 0;
            }
            
            // Read mesh file
            if (!mesh->Read(buffer)) {
                fprintf(stderr, "Unable to read mesh: %s\n", buffer);
                return 0;
            }
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_MESH_SHAPE;
            shape->box = NULL;
            shape->sphere = NULL;
            shape->cylinder = NULL;
            shape->cone = NULL;
            shape->mesh = mesh;
            shape->segment = NULL;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = mesh->bbox;
            node->enemy = NULL;
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
            arwingNode = node;
        }
        /* unneeded
        //turret - basically a box that shoots
        else if (!strcmp(cmd, "turret")) {
            // Read data
            int m;
            R3Point p1, p2;
            if (fscanf(fp, "%d%lf%lf%lf%lf%lf%lf", &m, &p1[0], &p1[1], &p1[2], &p2[0], &p2[1], &p2[2]) != 7) {
                fprintf(stderr, "Unable to read box at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at box command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Create box
            R3Box *box = new R3Box(p1, p2);
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_BOX_SHAPE;
            shape->box = box;
            shape->sphere = NULL;
            shape->cylinder = NULL;
            shape->cone = NULL;
            shape->mesh = NULL;
            shape->segment = NULL;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->cumulativeTransformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = *box;
            node->enemy = new SFEnemy();
            
            //list properties of the turret
            node->enemy->position = box->Centroid();
            node->enemy->projectileSource = box->Centroid();
            node->enemy->node = node;
            
        //    node->enemy->projectileSource.InverseTransform(node->transformation);
        //    node->enemy->projectileSource.SetZ(node->enemy->projectileSource.Z() - .5 * (box->ZMax() - box->ZMin()));
            
            enemies.push_back(node->enemy);
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        } */
        //enemy - a mesh that moves and shoots
        else if (!strcmp(cmd, "enemy")) {
            // Read data
            int fixed;
            int m;
            float vx, vy, vz;
            int h;
            char meshname[256];
				float particle_velocity;
				int firing_rate;
            if (fscanf(fp, "%d%d%s%f%f%f%d%f%d", &fixed, &m, meshname, &vx, &vy, &vz, &h,&particle_velocity, &firing_rate) != 9) {
                fprintf(stderr, "Unable to parse enemy command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at cone command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Get mesh filename
            char buffer[2048];
            strcpy(buffer, filename);
            char *bufferp = strrchr(buffer, '/');
            if (bufferp) *(bufferp+1) = '\0';
            else buffer[0] = '\0';
            strcat(buffer, meshname);
            
            
            R3Vector *initialVelocity = new R3Vector(vx, vy, vz);
            
            // Create mesh
            R3Mesh *mesh = new R3Mesh();
            if (!mesh) {
                fprintf(stderr, "Unable to allocate mesh\n");
                return 0;
            }
            
            // Read mesh file
            if (!mesh->Read(buffer)) {
                fprintf(stderr, "Unable to read mesh: %s\n", buffer);
                return 0;
            }
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_MESH_SHAPE;
            shape->box = NULL;
            shape->sphere = NULL;
            shape->cylinder = NULL;
            shape->cone = NULL;
            shape->mesh = mesh;
            shape->segment = NULL;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->cumulativeTransformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = mesh->bbox;
            node->enemy = new SFEnemy(fixed, mesh, *initialVelocity, h, particle_velocity, firing_rate);
            
            node->enemy->position = shape->mesh->Center();
            node->enemy->projectileSource = shape->mesh->Center();
            node->enemy->node = node;
            
            enemies.push_back(node->enemy);
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        }
        else if (!strcmp(cmd, "cone")) {
            // Read data
            int m;
            R3Point c;
            double r, h;
            if (fscanf(fp, "%d%lf%lf%lf%lf%lf", &m, &c[0], &c[1], &c[2], &r, &h) != 6) {
                fprintf(stderr, "Unable to read cone at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at cone command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Create cone
            R3Cone *cone = new R3Cone(c, r, h);
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_CONE_SHAPE;
            shape->box = NULL;
            shape->sphere = NULL;
            shape->cylinder = NULL;
            shape->cone = cone;
            shape->mesh = NULL;
            shape->segment = NULL;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = cone->BBox();
            node->enemy = NULL;
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        }
        else if (!strcmp(cmd, "line")) {
            // Read data
            int m;
            R3Point p1, p2;
            if (fscanf(fp, "%d%lf%lf%lf%lf%lf%lf", &m, &p1[0], &p1[1], &p1[2], &p2[0], &p2[1], &p2[2]) != 7) {
                fprintf(stderr, "Unable to read line at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at line command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Create segment
            R3Segment *segment = new R3Segment(p1, p2);
            
            // Create shape
            R3Shape *shape = new R3Shape();
            shape->type = R3_SEGMENT_SHAPE;
            shape->box = NULL;
            shape->sphere = NULL;
            shape->cylinder = NULL;
            shape->cone = NULL;
            shape->mesh = NULL;
            shape->segment = segment;
            
            // Create shape node
            R3Node *node = new R3Node();
            node->transformation = R3identity_matrix;
            node->material = material;
            node->shape = shape;
            node->bbox = segment->BBox();
            node->enemy = NULL;
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        }
        else if (!strcmp(cmd, "begin")) {
            // Read data
            int m;
            double matrix[16];
            if (fscanf(fp, "%d%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", &m, 
                       &matrix[0], &matrix[1], &matrix[2], &matrix[3], 
                       &matrix[4], &matrix[5], &matrix[6], &matrix[7], 
                       &matrix[8], &matrix[9], &matrix[10], &matrix[11], 
                       &matrix[12], &matrix[13], &matrix[14], &matrix[15]) != 17) {
                fprintf(stderr, "Unable to read begin at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get material
            R3Material *material = group_materials[depth];
            if (m >= 0) {
                if (m < (int) materials.size()) {
                    material = materials[m];
                }
                else {
                    fprintf(stderr, "Invalid material id at cone command %d in file %s\n", command_number, filename);
                    return 0;
                }
            }
            
            // Create new group node
            R3Node *node = new R3Node();
            node->transformation = R3Matrix(matrix);
            node->material = NULL;
            node->shape = NULL;
            node->bbox = R3null_box;
            node->enemy = NULL;
            
            // Push node onto stack
            depth++;
            group_nodes[depth] = node;
            group_materials[depth] = material;
        }
        else if (!strcmp(cmd, "end")) {
            // Pop node from stack
            R3Node *node = group_nodes[depth];
            depth--;
            
            // Transform bounding box
            node->bbox.Transform(node->transformation);
            
            // Insert node
            group_nodes[depth]->bbox.Union(node->bbox);
            group_nodes[depth]->children.push_back(node);
            node->parent = group_nodes[depth];
        }
        else if (!strcmp(cmd, "material")) {
            // Read data
            R3Rgb ka, kd, ks, kt, e;
            double n, ir;
            char texture_name[256];
            if (fscanf(fp, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%s", 
                       &ka[0], &ka[1], &ka[2], &kd[0], &kd[1], &kd[2], &ks[0], &ks[1], &ks[2], &kt[0], &kt[1], &kt[2], 
                       &e[0], &e[1], &e[2], &n, &ir, texture_name) != 18) {
                fprintf(stderr, "Unable to read material at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Create material
            R3Material *material = new R3Material();
            material->ka = ka;
            material->kd = kd;
            material->ks = ks;
            material->kt = kt;
            material->emission = e;
            material->shininess = n;
            material->indexofrefraction = ir;
            material->texture = NULL;
            
            // Read texture
            if (strcmp(texture_name, "0")) {
                // Get texture filename
                char buffer[2048];
                strcpy(buffer, filename);
                char *bufferp = strrchr(buffer, '/');
                if (bufferp) *(bufferp+1) = '\0';
                else buffer[0] = '\0';
                strcat(buffer, texture_name);
                
                // Read texture image
                material->texture = new R2Image();
                if (!material->texture->Read(buffer)) {
                    fprintf(stderr, "Unable to read texture from %s at command %d in file %s\n", buffer, command_number, filename);
                    return 0;
                }
            }
            
            // Insert material
            materials.push_back(material);
        }
        else if (!strcmp(cmd, "dir_light")) {
            // Read data
            R3Rgb c;
            R3Vector d;
            if (fscanf(fp, "%lf%lf%lf%lf%lf%lf", 
                       &c[0], &c[1], &c[2], &d[0], &d[1], &d[2]) != 6) {
                fprintf(stderr, "Unable to read directional light at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Normalize direction
            d.Normalize();
            
            // Create light
            R3Light *light = new R3Light();
            light->type = R3_DIRECTIONAL_LIGHT;
            light->color = c;
            light->position = R3Point(0, 0, 0);
            light->direction = d;
            light->radius = 0;
            light->constant_attenuation = 0;
            light->linear_attenuation = 0;
            light->quadratic_attenuation = 0;
            light->angle_attenuation = 0;
            light->angle_cutoff = M_PI;
            
            // Insert light
            lights.push_back(light);
        }
        else if (!strcmp(cmd, "point_light")) {
            // Read data
            R3Rgb c;
            R3Point p;
            double ca, la, qa;
            if (fscanf(fp, "%lf%lf%lf%lf%lf%lf%lf%lf%lf", &c[0], &c[1], &c[2], &p[0], &p[1], &p[2], &ca, &la, &qa) != 9) {
                fprintf(stderr, "Unable to read point light at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Create light
            R3Light *light = new R3Light();
            light->type = R3_POINT_LIGHT;
            light->color = c;
            light->position = p;
            light->direction = R3Vector(0, 0, 0);
            light->radius = 0;
            light->constant_attenuation = ca;
            light->linear_attenuation = la;
            light->quadratic_attenuation = qa;
            light->angle_attenuation = 0;
            light->angle_cutoff = M_PI;
            
            // Insert light
            lights.push_back(light);
        }
        else if (!strcmp(cmd, "spot_light")) {
            // Read data
            R3Rgb c;
            R3Point p;
            R3Vector d;
            double ca, la, qa, sc, sd;
            if (fscanf(fp, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", 
                       &c[0], &c[1], &c[2], &p[0], &p[1], &p[2], &d[0], &d[1], &d[2], &ca, &la, &qa, &sc, &sd) != 14) {
                fprintf(stderr, "Unable to read point light at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Normalize direction
            d.Normalize();
            
            // Create light
            R3Light *light = new R3Light();
            light->type = R3_SPOT_LIGHT;
            light->color = c;
            light->position = p;
            light->direction = d;
            light->radius = 0;
            light->constant_attenuation = ca;
            light->linear_attenuation = la;
            light->quadratic_attenuation = qa;
            light->angle_attenuation = sd;
            light->angle_cutoff = sc;
            
            // Insert light
            lights.push_back(light);
        }
        else if (!strcmp(cmd, "area_light")) {
            // Read data
            R3Rgb c;
            R3Point p;
            R3Vector d;
            double radius, ca, la, qa;
            if (fscanf(fp, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", 
                       &c[0], &c[1], &c[2], &p[0], &p[1], &p[2], &d[0], &d[1], &d[2], &radius, &ca, &la, &qa) != 13) {
                fprintf(stderr, "Unable to read area light at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Normalize direction
            d.Normalize();
            
            // Create light
            R3Light *light = new R3Light();
            light->type = R3_AREA_LIGHT;
            light->color = c;
            light->position = p;
            light->direction = d;
            light->radius = radius;
            light->constant_attenuation = ca;
            light->linear_attenuation = la;
            light->quadratic_attenuation = qa;
            light->angle_attenuation = 0;
            light->angle_cutoff = M_PI;
            
            // Insert light
            lights.push_back(light);
        }
        else if (!strcmp(cmd, "camera")) {
            // Read data
            double px, py, pz, dx, dy, dz, ux, uy, uz, xfov, neardist, fardist;
            if (fscanf(fp, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", &px, &py, &pz, &dx, &dy, &dz, &ux, &uy, &uz, &xfov, &neardist, &fardist) != 12) {
                fprintf(stderr, "Unable to read camera at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Assign camera
            camera.eye = R3Point(px, py, pz);
            camera.towards = R3Vector(dx, dy, dz);
            camera.towards.Normalize();
            camera.up = R3Vector(ux, uy, uz);
            camera.up.Normalize();
            camera.right = camera.towards % camera.up;
            camera.right.Normalize();
            camera.up = camera.right % camera.towards;
            camera.up.Normalize();
            camera.xfov = xfov;
            camera.yfov = xfov;
            camera.neardist = neardist;
            camera.fardist = fardist;
        }
        else if (!strcmp(cmd, "include")) {
            // Read data
            char scenename[256];
            if (fscanf(fp, "%s", scenename) != 1) {
                fprintf(stderr, "Unable to read include command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Get scene filename
            char buffer[2048];
            strcpy(buffer, filename);
            char *bufferp = strrchr(buffer, '/');
            if (bufferp) *(bufferp+1) = '\0';
            else buffer[0] = '\0';
            strcat(buffer, scenename);
            
            // Read scene from included file
            if (!Read(buffer, group_nodes[depth])) {
                fprintf(stderr, "Unable to read included scene: %s\n", buffer);
                return 0;
            }
        }
        else if (!strcmp(cmd, "background")) {
            // Read data
            double r, g, b;
            if (fscanf(fp, "%lf%lf%lf", &r, &g, &b) != 3) {
                fprintf(stderr, "Unable to read background at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Assign background color
            background = R3Rgb(r, g, b, 1);
        }
        else if (!strcmp(cmd, "ambient")) {
            // Read data
            double r, g, b;
            if (fscanf(fp, "%lf%lf%lf", &r, &g, &b) != 3) {
                fprintf(stderr, "Unable to read ambient at command %d in file %s\n", command_number, filename);
                return 0;
            }
            
            // Assign ambient color
            ambient = R3Rgb(r, g, b, 1);
        }
        else {
            fprintf(stderr, "Unrecognized command %d in file %s: %s\n", command_number, filename, cmd);
            return 0;
        }
        
        // Increment command number
        command_number++;
    }
    
    // Update bounding box
    bbox = root->bbox;
    
    // Provide default camera
    if (camera.xfov == 0) {
        double scene_radius = bbox.DiagonalRadius();
        R3Point scene_center = bbox.Centroid();
        camera.towards = R3Vector(0, 0, -1);
        camera.up = R3Vector(0, 1, 0);
        camera.right = R3Vector(1, 0, 0);
        camera.eye = scene_center - 3 * scene_radius * camera.towards;
        camera.xfov = 0.25;
        camera.yfov = 0.25;
        camera.neardist = 0.01 * scene_radius;
        camera.fardist = 100 * scene_radius;
    }
    
    // Provide default lights
    if (lights.size() == 0) {
        // Create first directional light
        R3Light *light = new R3Light();
        R3Vector direction(-3,-4,-5);
        direction.Normalize();
        light->type = R3_DIRECTIONAL_LIGHT;
        light->color = R3Rgb(1,1,1,1);
        light->position = R3Point(0, 0, 0);
        light->direction = direction;
        light->radius = 0;
        light->constant_attenuation = 0;
        light->linear_attenuation = 0;
        light->quadratic_attenuation = 0;
        light->angle_attenuation = 0;
        light->angle_cutoff = M_PI;
        lights.push_back(light);
        
        // Create second directional light
        light = new R3Light();
        direction = R3Vector(3,2,3);
        direction.Normalize();
        light->type = R3_DIRECTIONAL_LIGHT;
        light->color = R3Rgb(0.5, 0.5, 0.5, 1);
        light->position = R3Point(0, 0, 0);
        light->direction = direction;
        light->radius = 0;
        light->constant_attenuation = 0;
        light->linear_attenuation = 0;
        light->quadratic_attenuation = 0;
        light->angle_attenuation = 0;
        light->angle_cutoff = M_PI;
        lights.push_back(light);
    }
    
    // Close file
    fclose(fp);
    
    // Return success
    return 1;
}
Ejemplo n.º 12
0
RNBoolean R3Contains(const R3Sphere& sphere1, const R3Sphere& sphere2) 
{
    // Return whether sphere1 contains sphere2
    RNLength d = R3Distance(sphere1.Center(), sphere2.Center());
    return RNIsLess(d + sphere2.Radius(), sphere1.Radius());
}
Ejemplo n.º 13
0
RNBoolean R3Contains(const R3Sphere& sphere, const R3Halfspace& halfspace)
{
    // Return whether sphere contains halfspace
    if (sphere.IsFinite()) return FALSE;
    return TRUE;
}
Ejemplo n.º 14
0
RNBoolean R3Contains(const R3Sphere& sphere, const R3Plane& plane)
{
    // Return whether sphere contains plane
    if (sphere.IsFinite()) return FALSE;
    return TRUE;
}
Ejemplo n.º 15
0
RNBoolean R3Contains(const R3Sphere& sphere, const R3Ray& ray)
{
    // Return whether sphere contains ray
    if (sphere.IsFinite()) return FALSE;
    return TRUE;
}
Ejemplo n.º 16
0
RNBoolean R3Contains(const R3Halfspace& halfspace, const R3Sphere& sphere)
{
    // Return whether halfspace contains sphere 
    RNLength d = R3SignedDistance(halfspace.Plane(), sphere.Center());
    return RNIsGreaterOrEqual(d, sphere.Radius());
}