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 = mesh->Center();
      		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;
   }
Example #2
0
int 
main(int argc, char **argv)
{
  // Look for help
  for (int i = 0; i < argc; i++) {
    if (!strcmp(argv[i], "-help")) {
      ShowUsage();
    }
  }

  // Read input and output mesh filenames
  if (argc < 3)  ShowUsage();
  argv++, argc--; // First argument is program name
  char *tree_file_name=*argv;argv++;argc--;
  int iterations=0;
  if (argc>1)
    iterations=atoi(*argv++),argc--;
  char *output_mesh_name = *argv; argv++, argc--; 

  // Allocate mesh
  R3Mesh *mesh = new R3Mesh();
  if (!mesh) {
    fprintf(stderr, "Unable to allocate mesh\n");
    exit(-1);
  }

  // Read input mesh
  // if (!mesh->Read(input_mesh_name)) {
    // fprintf(stderr, "Unable to read mesh from %s\n", input_mesh_name);
    // exit(-1);
  // }

  mesh->Tree(tree_file_name,iterations);
  // Write output mesh
  if (!mesh->Write(output_mesh_name)) {
    fprintf(stderr, "Unable to write mesh to %s\n", output_mesh_name);
    exit(-1);
  }

  // Delete mesh
  delete mesh;
  printf("All done.\n");
  // Return success
  return EXIT_SUCCESS;
}
Example #3
0
R3Mesh::
R3Mesh(const R3Mesh& mesh)
  : bbox(R3null_box)
{
  // Create vertices
  for (int i = 0; i < mesh.NVertices(); i++) {
    R3MeshVertex *v = mesh.Vertex(i);
    CreateVertex(v->position, v->normal, v->texcoords);
  }

  // Create faces
  for (int i = 0; i < mesh.NFaces(); i++) {
    R3MeshFace *f = mesh.Face(i);
    vector<R3MeshVertex *> face_vertices;
    for (unsigned int j = 0; j < f->vertices.size(); j++) {
      R3MeshVertex *ov = f->vertices[j];
      R3MeshVertex *nv = Vertex(ov->id);
      face_vertices.push_back(nv);
    }
    CreateFace(face_vertices);
  }
}
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;
}
Example #5
0
R3Mesh* Terrain::Patch(R3Point center, R2Point size, R2Point dps) { // dps: dots per side
  R3Mesh *patch = new R3Mesh();
  for (unsigned int r = 0; r < dps.Y(); r++) {
    for (unsigned int c = 0; c < dps.X(); c++) {
      double dx = (double)c / dps.X() * size.X() - size.X() / 2;
      double dy = (r + c) % 2 * Util::UnitRandom(); // default

      if (params.heightMap) {
        int x = ((double)c / dps.X()) * params.heightMap->Width();
        int y = ((double)r / dps.Y()) * params.heightMap->Height();
        dy = 25 * params.heightMap->Pixel(x,y).Luminance();
      }

      double dz = (double)r / dps.Y() * size.Y() - size.Y() / 2;
      R3Point position(center.X() + dx, center.Y() + dy, center.Z() + dz);

      double tx = position.X() / 80;
      double ty = position.Z() / 80;

      //R2Point texcoord = R2Point(tx - ((int) tx), ty - ((int) ty));
      //if (texcoord.X() < 0)
          //texcoord.SetX(1 + texcoord.X());
      //if (texcoord.Y() < 0)
          //texcoord.SetY(1 + texcoord.Y());

      patch->CreateVertex(position, R3Vector(0,1,0), R2Point(tx, ty)); // id's go up along x axis, then along y
    }
  }
  
  for (unsigned int r = 0; r < dps.Y() - 1; r++) {
    for (unsigned int c = 0; c < dps.X() - 1; c++) {
      unsigned int cols = (unsigned int)dps.X();
      unsigned int k = c + r * cols;
      vector<R3MeshVertex*> vertices;
      vertices.push_back(patch->Vertex(k+cols));
      vertices.push_back(patch->Vertex(k+1));
      vertices.push_back(patch->Vertex(k));
      patch->CreateFace(vertices);

      vector<R3MeshVertex*> vertices2;
      vertices2.push_back(patch->Vertex(k+cols));
      vertices2.push_back(patch->Vertex(k+1+cols));
      vertices2.push_back(patch->Vertex(k+1));
      patch->CreateFace(vertices2);
    }
  }

  patch->Update();

  return patch;
}
Example #6
0
int 
main(int argc, char **argv)
{
  // Look for help
  for (int i = 0; i < argc; i++) {
    if (!strcmp(argv[i], "-help")) {
      ShowUsage();
    }
  }

  // Read input and output mesh filenames
  if (argc < 3)  ShowUsage();
  argv++, argc--; // First argument is program name
  char *input_mesh_name = *argv; argv++, argc--; 
  char *output_mesh_name = *argv; argv++, argc--; 

  // Allocate mesh
  R3Mesh *mesh = new R3Mesh();
  if (!mesh) {
    fprintf(stderr, "Unable to allocate mesh\n");
    exit(-1);
  }

  // Read input mesh
  if (!mesh->Read(input_mesh_name)) {
    fprintf(stderr, "Unable to read mesh from %s\n", input_mesh_name);
    exit(-1);
  }

  // Parse arguments and perform operations 
  while (argc > 0) {
    if (!strcmp(*argv, "-twist")) {
      CheckOption(*argv, argc, 2);
      double angle = atof(argv[1]);
      argv += 2, argc -= 2;
      mesh->Twist(angle);
    }
    else if (!strcmp(*argv, "-taubin")) {
      CheckOption(*argv, argc, 4);
      double lambda = atof(argv[1]);
      double mu = atof(argv[2]);
      double iters = atoi(argv[3]);
      argv += 4, argc -= 4;
      mesh->Taubin(lambda, mu, iters);
    }
    else if (!strcmp(*argv, "-loop")) {
      CheckOption(*argv, argc, 1);
      argv += 1, argc -= 1;
      mesh->Loop();
    }
    else {
      // Unrecognized program argument
      fprintf(stderr, "meshpro: invalid option: %s\n", *argv);
      ShowUsage();
    }
  }

  // Write output mesh
  if (!mesh->Write(output_mesh_name)) {
    fprintf(stderr, "Unable to write mesh to %s\n", output_mesh_name);
    exit(-1);
  }

  // Delete mesh
  delete mesh;

  // Return success
  return EXIT_SUCCESS;
}