home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vectoper.zip / RTObjOps.cpp < prev    next >
C/C++ Source or Header  |  1996-09-19  |  17KB  |  621 lines

  1.  
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. #include <string.h>
  7.  
  8. #include "RTTypes.h"
  9. #include "RTMatMac.h"
  10. #include "RTVecOps.h"
  11.  
  12. #include "RTObjOps.h"
  13. #include "RTIMOps.h"
  14. #include "RayTrace.h"
  15.  
  16.  
  17.  
  18. char * Sh_malloc(unsigned size);
  19. char * Sh_calloc(unsigned  elem_count,  unsigned size);
  20.  
  21.  
  22. void build_sphere(FILE *fp);
  23. void build_rect(FILE *fp);
  24. void build_poly_mesh(FILE *fp);
  25.  
  26. void bound_sphere( Sphere_Obj *s_ptr, Vector min_vec, Vector max_vec);
  27.  
  28. void set_obj_defaults();
  29.  
  30. void clear_object(Poly_Mesh_Obj *obj_ptr);
  31.  
  32. int obj_label_to_type(char *object_label);
  33.  
  34. Vector  ColorVecs_Out[10] = { (float)0.0, (float)0.0, (float)1.0,   (float)0.0, (float)1.0, (float)0.0,
  35.                               (float)1.0, (float)0.0, (float)1.0,   (float)0.0, (float)1.0, (float)1.0};
  36.  
  37. Vector  ColorVecs_In[10] =  { (float)1.0, (float)0.0, (float)0.0,   (float)0.0, (float)0.0, (float)1.0,
  38.                               (float)0.0, (float)1.0, (float)1.0,   (float)1.0, (float)1.0, (float)1.0};
  39.  
  40. int cvec_num = 4;
  41.  
  42.  
  43. Obj_View  obj_defaults;
  44.  
  45.  
  46.  
  47.  
  48.  
  49. /*
  50.  *******************************************************************************
  51.  *
  52.  *  Name:  build_object
  53.  *
  54.  *  Purpose: this routine reads in data from a specified file and builds
  55.  *           an object structure for the data.
  56.  *
  57.  *
  58.  *
  59.  *  Input Parameters
  60.  *
  61.  *     fp - file pointer
  62.  *     new_obj - flag to indicate whether or not to reset object counter
  63.  *
  64.  *
  65.  *  Output Parameters
  66.  *
  67.  *     none
  68.  *
  69.  *******************************************************************************
  70.  */
  71. void
  72.    build_object(FILE *fp, Boolean new_obj)
  73.       {
  74.        char object_label[50];
  75.        int object_type;
  76.  
  77.  
  78. /*
  79.  *     set object count & read object type
  80.  */
  81.        shared->obj_num = (new_obj)? 1 : shared->obj_num + 1;
  82.  
  83.        fscanf (fp, "%s\n", &object_label);
  84.        object_type = obj_label_to_type(object_label);
  85.  
  86. /*
  87.  *     set default optical properties for object
  88.  */
  89.        shared->obj_props[shared->obj_num-1].Od_out = 
  90.                                     ColorVecs_Out[(shared->obj_num-1)%cvec_num];
  91.        shared->obj_props[shared->obj_num-1].Od_in = 
  92.                                     ColorVecs_In[(shared->obj_num-1)%cvec_num];
  93.  
  94.        vset(&shared->obj_props[shared->obj_num-1].Os, (float)1.0, (float)1.0, (float)1.0);
  95.  
  96.        shared->obj_props[shared->obj_num-1].Ka = (float)0.2;
  97.        shared->obj_props[shared->obj_num-1].Kd = (float)0.7;
  98.        shared->obj_props[shared->obj_num-1].Ks = (float)0.6;
  99.        shared->obj_props[shared->obj_num-1].Kt = (float)0.0;
  100.        shared->obj_props[shared->obj_num-1].n =  (float)1.5;
  101.  
  102.        if (object_type == RECTANGLE)
  103.            shared->obj_props[shared->obj_num-1].txt_flg = TRUE;
  104.        else
  105.            shared->obj_props[shared->obj_num-1].txt_flg = FALSE;
  106.  
  107.  
  108.        switch(object_type)  {
  109.            case SPHERE:
  110.                build_sphere(fp);
  111.                break;
  112.            case RECTANGLE:
  113.                build_rect(fp);
  114.                break;
  115.            case POLY_MESH:
  116.                build_poly_mesh(fp);
  117.                break;
  118.           }
  119.       }
  120.  
  121.  
  122. /*
  123.  *******************************************************************************
  124.  *
  125.  *  Name:  obj_label_to_type
  126.  *
  127.  *  Purpose:  this routine examines the label identifying the type of object
  128.  *            and returns the type associated with that object.
  129.  *
  130.  *
  131.  *
  132.  *  Input Parameters
  133.  *
  134.  *     object_label - label identifying object type
  135.  *
  136.  *
  137.  *  Output Parameters
  138.  *
  139.  *     none
  140.  *
  141.  *******************************************************************************
  142.  */
  143. int
  144.    obj_label_to_type(char *object_label)
  145.       {
  146.        if (strcmp("SPHERE", object_label) == 0)
  147.           return(SPHERE);
  148.  
  149.        else if (strcmp("RECTANGLE", object_label) == 0)
  150.           return(RECTANGLE);
  151.  
  152.        else if (strcmp("POLY_MESH", object_label) == 0)
  153.           return(POLY_MESH);
  154.  
  155.        else {
  156.            printf("***** Error:  Illegal Object Type -- %s -- EXITING *****\n",
  157.                object_label);
  158.            exit(1);
  159.           }
  160.        exit(1);
  161.        return(1);
  162.       }
  163.  
  164.  
  165.  
  166. /*
  167.  *******************************************************************************
  168.  *
  169.  *  Name:  build_sphere
  170.  *
  171.  *  Purpose: 
  172.  *
  173.  *
  174.  *
  175.  *  Input Parameters
  176.  *
  177.  *     fp - file pointer 
  178.  *
  179.  *
  180.  *  Output Parameters
  181.  *
  182.  *     none
  183.  *
  184.  *******************************************************************************
  185.  */
  186. void
  187.    build_sphere(FILE *fp)
  188.       {
  189.        Sphere_Obj *curr_obj;
  190.  
  191.  
  192. /*
  193.  *     initialize object and read in header information from file
  194.  */
  195.        shared->obj_list[shared->obj_num-1].label = SPHERE;
  196.        shared->obj_list[shared->obj_num-1].ptr = (char *) Sh_malloc( (unsigned) 
  197.                                                        sizeof(Sphere_Obj) );
  198.  
  199.        curr_obj = (Sphere_Obj *) shared->obj_list[shared->obj_num-1].ptr;
  200.  
  201.  
  202.  
  203.        fscanf (fp, "%f %f %f", &curr_obj->center_pt.x, &curr_obj->center_pt.y,
  204.                                &curr_obj->center_pt.z);
  205.  
  206.        fscanf (fp, "%f %f %f", &curr_obj->radius_pt.x, &curr_obj->radius_pt.y,
  207.                                &curr_obj->radius_pt.z);
  208.        
  209.        set_obj_defaults();
  210.       }
  211.  
  212.  
  213. /*
  214.  *******************************************************************************
  215.  *
  216.  *  Name:  build_rect
  217.  *
  218.  *  Purpose: .
  219.  *
  220.  *
  221.  *
  222.  *  Input Parameters
  223.  *
  224.  *     fp - file pointer 
  225.  *
  226.  *
  227.  *  Output Parameters
  228.  *
  229.  *     none
  230.  *
  231.  *******************************************************************************
  232.  */
  233. void
  234.    build_rect(FILE *fp)
  235.       {
  236.        Rect_Obj *curr_obj;
  237.        Vector max_vec, min_vec;
  238.  
  239.        int i;
  240.  
  241.  
  242.        vset(&max_vec, (float)-9999.0, (float)-9999.0, (float)-9999.0);
  243.        vset(&min_vec,  (float)9999.0,  (float)9999.0,  (float)9999.0);
  244. /*
  245.  *     initialize object and read in header information from file
  246.  */
  247.        shared->obj_list[shared->obj_num-1].label = RECTANGLE;
  248.        shared->obj_list[shared->obj_num-1].ptr = (char *) Sh_malloc( (unsigned) 
  249.                                                        sizeof(Rect_Obj) );
  250.  
  251.        curr_obj = (Rect_Obj *) shared->obj_list[shared->obj_num-1].ptr;
  252.  
  253.  
  254.  
  255.        for (i=0; i<4; i++)  {
  256.            fscanf (fp, "%f %f %f", &curr_obj->corners[i].x,
  257.                                    &curr_obj->corners[i].y,
  258.                                    &curr_obj->corners[i].z  );
  259.  
  260.            max_vec = vmax(&max_vec, &curr_obj->corners[i]);
  261.            min_vec = vmin(&min_vec, &curr_obj->corners[i]);
  262.           }
  263.  
  264.        if (max_vec.x == min_vec.x)
  265.            curr_obj->normal = X_AXIS;
  266.  
  267.        else if (max_vec.y == min_vec.y)
  268.            curr_obj->normal = Y_AXIS;
  269.  
  270.        else if (max_vec.z == min_vec.z)
  271.            curr_obj->normal = Z_AXIS;
  272.  
  273.        curr_obj->max_pt = max_vec;
  274.        curr_obj->min_pt = min_vec;
  275.  
  276.        set_obj_defaults();
  277.       }
  278.  
  279.  
  280. /*
  281.  *******************************************************************************
  282.  *
  283.  *  Name:  build_poly_mesh
  284.  *
  285.  *  Purpose: 
  286.  *
  287.  *
  288.  *
  289.  *  Input Parameters
  290.  *
  291.  *     fp - file pointer 
  292.  *
  293.  *
  294.  *  Output Parameters
  295.  *
  296.  *     none
  297.  *
  298.  *******************************************************************************
  299.  */
  300. void
  301.    build_poly_mesh(FILE *fp)
  302.       {
  303.        int surf_list[100];
  304.  
  305.        Surface *sptr;
  306.        Triangle *tptr;
  307.        Poly_Mesh_Obj *curr_obj;
  308.  
  309.        int no_obj, no_vert, no_faces, no_surf;
  310.        int conn_start, conn_stop, leng_conn;
  311.        int i,j;
  312.  
  313.  
  314. /*
  315.  *     initialize object and read in header information from file
  316.  */
  317.        shared->obj_list[shared->obj_num-1].label = POLY_MESH;
  318.        shared->obj_list[shared->obj_num-1].ptr = (char *) Sh_malloc( (unsigned) 
  319.                                                        sizeof(Poly_Mesh_Obj) );
  320.  
  321.        curr_obj = (Poly_Mesh_Obj *) shared->obj_list[shared->obj_num-1].ptr;
  322.  
  323.  
  324.        clear_object(curr_obj);
  325.  
  326.        fscanf (fp, "%d", &no_obj);
  327.        fscanf (fp, "%d %d %d %d\n", &no_vert, &no_faces, &leng_conn, &no_surf);
  328.        fscanf (fp, "%d %d\n", &conn_start, &conn_stop);
  329.  
  330. /*
  331.  +++++++++++++++++++++++++++++++++++++++++++++++++
  332.  *  read data points into object
  333.  +++++++++++++++++++++++++++++++++++++++++++++++++
  334.  */
  335.        curr_obj->data = (Vector *) Sh_calloc( (unsigned)no_vert,
  336.                                            (unsigned)sizeof(Vector) );
  337.        curr_obj->num_vert = no_vert;
  338.  
  339.        for (i=0; i<no_vert; i++)
  340.            fscanf (fp, "%f %f %f", &curr_obj->data[i].x, &curr_obj->data[i].y,
  341.                                    &curr_obj->data[i].z);
  342.        
  343. /*
  344.  +++++++++++++++++++++++++++++++++++++++++++++++++
  345.  *  setup the surfaces in an object
  346.  +++++++++++++++++++++++++++++++++++++++++++++++++
  347.  */
  348.        curr_obj->num_surf = no_surf;
  349.  
  350. /*
  351.  *     malloc space in structure for normals
  352.  */
  353.        curr_obj->surf_tnorm_flags = (Boolean *) Sh_calloc( (unsigned)no_surf,
  354.                                                   (unsigned)sizeof(Boolean) );
  355.        curr_obj->surf_pnorm_flags = (Boolean *) Sh_calloc( (unsigned)no_surf,
  356.                                                   (unsigned)sizeof(Boolean) );
  357.        for (i=0; i<no_surf; i++)  {
  358.            curr_obj->surf_norms[i] = (Vector *) Sh_calloc((unsigned)no_vert,
  359.                                                       (unsigned)sizeof(Vector));
  360.            fscanf (fp, "%d", &surf_list[i]);
  361.           }
  362.  
  363. /*
  364.  *     malloc space in structure for surfaces
  365.  */
  366.        curr_obj->surfs = (Surface *) Sh_calloc( (unsigned) curr_obj->num_surf,
  367.                                              (unsigned)sizeof(Surface) );
  368.  
  369. /*
  370.  +++++++++++++++++++++++++++++++++++++++++++++++++
  371.  *  setup the triangles in a surface
  372.  +++++++++++++++++++++++++++++++++++++++++++++++++
  373.  */
  374.        sptr = curr_obj->surfs;
  375.  
  376.        for (i=0; i<no_surf; i++)  {
  377.  
  378. /*
  379.  *         malloc space in structure for current triangle
  380.  */
  381.            sptr[i].triangs = (Triangle *)
  382.                  Sh_calloc((unsigned) surf_list[i], (unsigned)sizeof(Triangle));
  383.  
  384.  
  385.            sptr[i].num_triang = surf_list[i];
  386.            tptr = sptr[i].triangs;
  387.  
  388. /*
  389.  *         read in vertices for each triangle in surface
  390.  */
  391.            for (j=0; j<surf_list[i]; j++)  {
  392.                fscanf (fp, "%d %d %d *%d", &tptr[j].v[0], &tptr[j].v[1],
  393.                                            &tptr[j].v[2]);
  394.  
  395.                tptr[j].v[0]--;
  396.                tptr[j].v[1]--;
  397.                tptr[j].v[2] = (-tptr[j].v[2]) - 1;
  398.                tptr[j].v[3] = tptr[j].v[0];
  399.               }
  400.           }
  401.  
  402.        set_obj_defaults();
  403.       }
  404.  
  405.  
  406.  
  407. /*
  408.  *******************************************************************************
  409.  *
  410.  *  Name:  set_obj_defaults
  411.  *
  412.  *  Purpose: this routine sets default viewing parameters for bounding box
  413.  *           around object data extrema
  414.  *
  415.  *
  416.  *
  417.  *  Input Parameters
  418.  *
  419.  *     none
  420.  *
  421.  *
  422.  *  Output Parameters
  423.  *
  424.  *     none
  425.  *
  426.  *******************************************************************************
  427.  */
  428. void
  429.    set_obj_defaults()
  430.       {
  431.        Obj *obj_ptr;
  432.        Poly_Mesh_Obj *poly_ptr;
  433.        Sphere_Obj *s_ptr;
  434.        Rect_Obj *r_ptr;
  435.  
  436.        Vector min_vec, max_vec;
  437.        Vector min_s, max_s;
  438.        Vector min_r, max_r;
  439.        Vector min_p, max_p;
  440.        Vector range_vec;
  441.  
  442.        float vrad, tanv2, delta;
  443.        float r;
  444.  
  445.        int i, j;
  446.        
  447.  
  448.        vset(&min_vec, (float)9999.0, (float)9999.0, (float)9999.0);
  449.        vset(&max_vec, (float)-9999.0, (float)-9999.0, (float)-9999.0);
  450.  
  451.  
  452.        for (i=0; i<shared->obj_num; i++)  {
  453.            obj_ptr = &shared->obj_list[i];
  454.  
  455.            switch (obj_ptr->label)  {
  456.  
  457.                case POLY_MESH:
  458.                    poly_ptr = (Poly_Mesh_Obj *) obj_ptr->ptr;
  459.  
  460.                    for (j=0; j<poly_ptr->num_vert; j++)  {
  461.                        min_p = vmin(&min_p, &poly_ptr->data[j]);
  462.                        max_p = vmax(&max_p, &poly_ptr->data[j]);
  463.                       }
  464.  
  465.                    bound_sphere(&poly_ptr->b_sph, min_p, max_p);
  466.  
  467.                    max_vec = vmax(&max_vec, &max_p);
  468.                    min_vec = vmin(&min_vec, &min_p);
  469.                    break;
  470.  
  471.                case SPHERE:
  472.                    s_ptr = (Sphere_Obj *) obj_ptr->ptr;
  473.  
  474.                    r = sqrt( SQR(s_ptr->center_pt.x - s_ptr->radius_pt.x) + 
  475.                              SQR(s_ptr->center_pt.y - s_ptr->radius_pt.y) + 
  476.                              SQR(s_ptr->center_pt.z - s_ptr->radius_pt.z)   );
  477.  
  478.                    vset(&min_s, s_ptr->center_pt.x - r,
  479.                                 s_ptr->center_pt.y - r,
  480.                                 s_ptr->center_pt.z - r );
  481.  
  482.                    vset(&max_s, s_ptr->center_pt.x + r,
  483.                                 s_ptr->center_pt.y + r,
  484.                                 s_ptr->center_pt.z + r );
  485.  
  486.                    max_vec = vmax(&max_vec, &max_s);
  487.                    min_vec = vmin(&min_vec, &min_s);
  488.                    break;
  489.  
  490.                case RECTANGLE:
  491.                    r_ptr = (Rect_Obj *) obj_ptr->ptr;
  492.  
  493.                    max_r.x = MAX(r_ptr->corners[0].x, r_ptr->corners[2].x);
  494.                    max_r.y = MAX(r_ptr->corners[0].y, r_ptr->corners[2].y);
  495.                    max_r.z = MAX(r_ptr->corners[0].z, r_ptr->corners[2].z);
  496.  
  497.                    min_r.x = MIN(r_ptr->corners[0].x, r_ptr->corners[2].x);
  498.                    min_r.y = MIN(r_ptr->corners[0].y, r_ptr->corners[2].y);
  499.                    min_r.z = MIN(r_ptr->corners[0].z, r_ptr->corners[2].z);
  500.  
  501.                    bound_sphere(&r_ptr->b_sph, min_r, max_r);
  502.  
  503.                    max_vec = vmax(&max_vec, &max_r);
  504.                    min_vec = vmin(&min_vec, &min_r);
  505.                    break;
  506.               }
  507.           }
  508.  
  509.        obj_defaults.zmax = max_vec;
  510.        obj_defaults.zmin = min_vec;
  511.  
  512.        obj_defaults.v = (float)60.0;
  513.  
  514.        vset( &obj_defaults.U,  (float) 0.0,  (float) 1.0,  (float) 0.0);
  515.  
  516.        obj_defaults.A.x = min_vec.x + (max_vec.x - min_vec.x) / ((float)2.0);
  517.        obj_defaults.A.y = min_vec.y + (max_vec.y - min_vec.y) / ((float)2.0);
  518.        obj_defaults.A.z = min_vec.z + (max_vec.z - min_vec.z) / ((float)2.0);
  519.  
  520.  
  521.        range_vec = Vector_Difference(&max_vec, &min_vec);
  522.  
  523.        vrad =  (obj_defaults.v/180) * M_PI;
  524.        tanv2 =  2 * tan(vrad/2);
  525. /*
  526.  *     delta = MAX(range_vec.z/tanv2, range_vec.x/tanv2);
  527.  *
  528.  *
  529.  *     shared->obj_list->F.x = shared->obj_list->A.x;
  530.  *
  531.  *     shared->obj_list->F.y = shared->obj_list->A.y - (range_vec.y/2 + delta);
  532.  *     shared->obj_list->F.z = shared->obj_list->A.z;
  533.  */
  534.  
  535.        delta = MAX(range_vec.y/tanv2, range_vec.x/tanv2);
  536.   
  537.   
  538.        obj_defaults.F.x = obj_defaults.A.x;
  539.   
  540.        obj_defaults.F.y = obj_defaults.A.y;
  541.        obj_defaults.F.z = obj_defaults.A.z + (range_vec.z/2 + delta);
  542.  
  543.   
  544.        for (i=0; i<LIGHTS_MAX; i++)
  545.                shared->lights[i].L_pt = obj_defaults.F;
  546.       }
  547.  
  548.  
  549.  
  550. /*
  551.  *******************************************************************************
  552.  *
  553.  *  Name:  clear_object
  554.  *
  555.  *  Purpose:  this routine nulls out the pointers in an object so that
  556.  *            stray values will not fake other routines.
  557.  *
  558.  *
  559.  *
  560.  *  Input Parameters
  561.  *
  562.  *     obj_ptr - object to be cleared
  563.  *
  564.  *
  565.  *  Output Parameters
  566.  *
  567.  *     none
  568.  *
  569.  *******************************************************************************
  570.  */
  571. void
  572.    clear_object(Poly_Mesh_Obj *obj_ptr)
  573.       {
  574.        int i;
  575.   
  576.        obj_ptr->data = NULL;
  577.        obj_ptr->surfs = NULL;
  578.        obj_ptr->surf_tnorm_flags = NULL;
  579.        obj_ptr->surf_pnorm_flags = NULL;
  580.  
  581.        for (i=0; i<100; i++)
  582.            obj_ptr->surf_norms[i] = NULL;
  583.  
  584.       }
  585.  
  586.  
  587. /*
  588.  *******************************************************************************
  589.  *
  590.  *  Name:  bound_sphere
  591.  *
  592.  *  Purpose: 
  593.  *
  594.  *
  595.  *
  596.  *  Input Parameters
  597.  *
  598.  *     fp - file pointer 
  599.  *
  600.  *
  601.  *  Output Parameters
  602.  *
  603.  *     none
  604.  *
  605.  *******************************************************************************
  606.  */
  607. void
  608.    bound_sphere( Sphere_Obj *s_ptr, Vector min_vec, Vector max_vec)
  609.       {
  610.        Vector delta_vec;
  611.  
  612.  
  613.        delta_vec = Vector_Difference(&max_vec, &min_vec);
  614.        delta_vec = VectorScaler_Division(&delta_vec, (float)2.0);
  615.  
  616.        s_ptr->center_pt = Vector_Sum(&min_vec, &delta_vec);
  617.        s_ptr->radius_pt = max_vec;
  618.       }
  619.  
  620.  
  621.