[chimera-dev] warped dome

Tom Goddard goddard at sonic.net
Fri Oct 24 18:07:25 PDT 2014


I’ll take a look next week.

	Tom


On Oct 24, 2014, at 5:23 PM, Dougherty, Matthew T <matthewd at bcm.edu> wrote:

> Hi Tom,
> 
> Attached are two warp files and the spec:
>         * File example::
>         *      mode
>         *      width height
>         *      n0_x n0_y n0_u n0_v n0_i
>         *      n1_x n1_y n1_u n1_v n1_i
>         *      n2_x n1_y n2_u n2_v n2_i
>         *      n3_x n3_y n3_u n3_v n3_i
>         *      (...)
> 
> 
>         * First line is the image type the mesh is support to be applied to: 2 = fisheye, 1=radial
>         * The next line has the mesh dimensions
>         * Rest of the lines are the nodes of the mesh. Each line has x y u v i
>         *   (x,y) are the normalized screen coordinates
>         *   (u,v) texture coordinates
>         *   i a multiplicative intensity factor
> 
>         * x varies from -screen aspect to screen aspect
>         * y varies from -1 to 1
>         * u and v vary from 0 to 1
>         * i ranges from 0 to 1, if negative don't draw that mesh node
>         */
> 
> Below is the extracted blender code to do the parsing and part of the code to do a similar warping on their mesh.
> 
> Take a shot at it.  If it looks like it will take a lot of your time let me know and I will give it a try.
> 
> Thanks,
> 
> 
> Matthew Dougherty
> National Center for Macromolecular Imaging
> Baylor College of Medicine
> ===========================================================================
> ________________________________________
> From: Tom Goddard [goddard at sonic.net]
> Sent: Friday, October 24, 2014 6:41 PM
> To: Dougherty, Matthew T
> Cc: chimera-dev at cgl.ucsf.edu
> Subject: Re: [chimera-dev] warped dome
> 
> Hi Matt,
> 
>  It would be a lot of fun to see Chimera used in some interactive dome visualization.  Using a warping other than fisheye is pretty easy in the Chimera code because it is already using a mesh with texture coordinates that define the warping.  The basic trick is what file can be read in, or what equation can be used to define the warping  (x,y) -> (new x, new y) where x,y is fish eye, and new x, new y is warped position on the projector image.  Alternatively you could define spherical coordinates phi,theta mapping to projector x,y coordinates.  I thought you told me in the past there was a file format for defining a dome warping, but I never got a specification and example file from you.  If you give me this I would give it a shot to allow interactive dome display with warping.  What I’m talking about is for monoscopic dome display.  Currently we don’t support stereoscopic dome display (except by recording each eye view separately for say a movie), so custom warped stereo dome display is a few steps away.
> 
>   Tom
> 
> ===========================================================================
>        //mesh warp functions
>        typedef struct {
>                double x, y, u, v, i;
>        } WarpMeshNode;
> 
>        struct {
>                bool usemesh;
>                int mode;
>                int n_width, n_height; //nodes width and height
>                int imagesize;
>                int bufferwidth, bufferheight;
>                GLuint fboId;
>                vector <vector <WarpMeshNode> > nodes;
>        } warp;
> 
> 
> 
> bool KX_Dome::ParseWarpMesh(STR_String text)
> {
>        /*
>         * //Notes about the supported data format:
>         * File example::
>         *      mode
>         *      width height
>         *      n0_x n0_y n0_u n0_v n0_i
>         *      n1_x n1_y n1_u n1_v n1_i
>         *      n2_x n1_y n2_u n2_v n2_i
>         *      n3_x n3_y n3_u n3_v n3_i
>         *      (...)
>         * First line is the image type the mesh is support to be applied to: 2 = fisheye, 1=radial
>         * The next line has the mesh dimensions
>         * Rest of the lines are the nodes of the mesh. Each line has x y u v i
>         *   (x,y) are the normalized screen coordinates
>         *   (u,v) texture coordinates
>         *   i a multiplicative intensity factor
>         *
>         * x varies from -screen aspect to screen aspect
>         * y varies from -1 to 1
>         * u and v vary from 0 to 1
>         * i ranges from 0 to 1, if negative don't draw that mesh node
>         */
>        int i;
>        int nodeX=0, nodeY=0;
> 
>        vector<STR_String> columns, lines;
> 
>        lines = text.Explode('\n');
>        if (lines.size() < 6) {
>                printf("Dome Error: Warp Mesh File with insufficient data!\n");
>                return false;
>        }
>        columns = lines[1].Explode(' ');
>        if (columns.size() == 1)
>                columns = lines[1].Explode('\t');
> 
>        if (columns.size() !=2) {
>                printf("Dome Error: Warp Mesh File incorrect. The second line should contain: width height.\n");
>                return false;
>        }
> 
>        warp.mode = atoi(lines[0]);// 1 = radial, 2 = fisheye
> 
>        warp.n_width = atoi(columns[0]);
>        warp.n_height = atoi(columns[1]);
> 
>        if ((int)lines.size() < 2 + (warp.n_width * warp.n_height)) {
>                printf("Dome Error: Warp Mesh File with insufficient data!\n");
>                return false;
>        }
>        else {
>                warp.nodes = vector<vector<WarpMeshNode> > (warp.n_height, vector<WarpMeshNode>(warp.n_width));
> 
>                for (i=2; i-2 < (warp.n_width*warp.n_height); i++) {
>                        columns = lines[i].Explode(' ');
>                        if (columns.size() == 1)
>                                columns = lines[i].Explode('\t');
> 
>                        if (columns.size() == 5) {
>                                nodeX = (i-2)%warp.n_width;
>                                nodeY = ((i-2) - nodeX) / warp.n_width;
> 
>                                warp.nodes[nodeY][nodeX].x = atof(columns[0]);
>                                warp.nodes[nodeY][nodeX].y = atof(columns[1]);
>                                warp.nodes[nodeY][nodeX].u = atof(columns[2]);
>                                warp.nodes[nodeY][nodeX].v = atof(columns[3]);
>                                warp.nodes[nodeY][nodeX].i = atof(columns[4]);
>                        }
>                        else {
>                                warp.nodes.clear();
>                                printf("Dome Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n");
>                                return false;
>                        }
>                }
>        }
>        return true;
> }
> 
> ===========================================================================
> // constructor
> KX_Dome::KX_Dome (
>        RAS_ICanvas* canvas,
>        /// rasterizer
>        RAS_IRasterizer* rasterizer,
>        /// engine
>        KX_KetsjiEngine* engine,
> 
>        short res,              //resolution of the mesh
>        short mode,             //mode - fisheye, truncated, warped, panoramic, ...
>        short angle,
>        float resbuf,   //size adjustment of the buffer
>        short tilt,
>        struct Text* warptext
> 
>        ):
>    dlistSupported(false),
>    canvaswidth(-1), canvasheight(-1),
>    m_drawingmode(engine->GetDrawType()),
>    m_resolution(res),
>    m_mode(mode),
>    m_angle(angle),
>    m_resbuffer(resbuf),
>    m_tilt(tilt),
>    m_canvas(canvas),
>    m_rasterizer(rasterizer),
>    m_engine(engine)
> {
>        warp.usemesh = false;
>        fboSupported = false;
> 
>        if (mode >= DOME_NUM_MODES)
>                m_mode = DOME_FISHEYE;
> 
>        if (warptext) // it there is a text data try to warp it
>        {
>                char *buf;
>                buf = txt_to_buf(warptext);
>                if (buf)
>                {
>                        warp.usemesh = ParseWarpMesh(STR_String(buf));
>                        MEM_freeN(buf);
>                }
>        }
> 
>        //setting the viewport size
>        const int *viewport = m_canvas->GetViewPort();
> 
>        SetViewPort(viewport);
> 
>        switch (m_mode) {
>                case DOME_FISHEYE:
>                        if (m_angle <= 180) {
>                                cubetop.resize(1);
>                                cubebottom.resize(1);
>                                cubeleft.resize(2);
>                                cuberight.resize(2);
> 
>                                CreateMeshDome180();
>                                m_numfaces = 4;
>                        }
>                        else if (m_angle > 180) {
>                                cubetop.resize(2);
>                                cubebottom.resize(2);
>                                cubeleft.resize(2);
>                                cubefront.resize(2);
>                                cuberight.resize(2);
> 
>                                CreateMeshDome250();
>                                m_numfaces = 5;
>                        } break;
>        }
> 
>        m_numimages =(warp.usemesh?m_numfaces+1:m_numfaces);
> 
>        CalculateCameraOrientation();
> 
>        CreateGLImages();
> 
>        if (warp.usemesh)
>                fboSupported = CreateFBO();
> 
>        dlistSupported = CreateDL();
> }
> ===========================================================================
> void KX_Dome::CreateMeshDome180(void)
> {
>        /*
>         * 1)-  Define the faces of half of a cube
>         *  - each face is made out of 2 triangles
>         * 2) Subdivide the faces
>         *  - more resolution == more curved lines
>         * 3) Spherize the cube
>         *  - normalize the verts
>         * 4) Flatten onto xz plane
>         *  - transform it onto an equidistant spherical projection techniques to transform the sphere onto a dome image
>         */
>        int i,j;
>        float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
> 
>        m_radangle = DEG2RADF(m_angle); //calculates the radians angle, used for flattening
> 
>        //creating faces for the env mapcube 180deg Dome
>        // Top Face - just a triangle
>        cubetop[0].verts[0][0] = -M_SQRT2 / 2.0;
>        cubetop[0].verts[0][1] = 0.0;
>        cubetop[0].verts[0][2] = 0.5;
>        cubetop[0].u[0] = 0.0;
>        cubetop[0].v[0] = uv_ratio;
> 
>        cubetop[0].verts[1][0] = 0.0;
>        cubetop[0].verts[1][1] = M_SQRT2 / 2.0;
>        cubetop[0].verts[1][2] = 0.5;
>        cubetop[0].u[1] = 0.0;
>        cubetop[0].v[1] = 0.0;
> 
>        cubetop[0].verts[2][0] = M_SQRT2 / 2.0;
>        cubetop[0].verts[2][1] = 0.0;
>        cubetop[0].verts[2][2] = 0.5;
>        cubetop[0].u[2] = uv_ratio;
>        cubetop[0].v[2] = 0.0;
> 
>        nfacestop = 1;
> 
>        /* Bottom face - just a triangle */
>        cubebottom[0].verts[0][0] = -M_SQRT2 / 2.0;
>        cubebottom[0].verts[0][1] = 0.0;
>        cubebottom[0].verts[0][2] = -0.5;
>        cubebottom[0].u[0] = uv_ratio;
>        cubebottom[0].v[0] = 0.0;
> 
>        cubebottom[0].verts[1][0] = M_SQRT2 / 2.0;
>        cubebottom[0].verts[1][1] = 0;
>        cubebottom[0].verts[1][2] = -0.5;
>        cubebottom[0].u[1] = 0.0;
>        cubebottom[0].v[1] = uv_ratio;
> 
>        cubebottom[0].verts[2][0] = 0.0;
>        cubebottom[0].verts[2][1] = M_SQRT2 / 2.0;
>        cubebottom[0].verts[2][2] = -0.5;
>        cubebottom[0].u[2] = 0.0;
>        cubebottom[0].v[2] = 0.0;
> 
>        nfacesbottom = 1;
> 
>        /* Left face - two triangles */
> 
>        cubeleft[0].verts[0][0] = -M_SQRT2 / 2.0;
>        cubeleft[0].verts[0][1] = 0.0;
>        cubeleft[0].verts[0][2] = -0.5;
>        cubeleft[0].u[0] = 0.0;
>        cubeleft[0].v[0] = 0.0;
> 
>        cubeleft[0].verts[1][0] = 0.0;
>        cubeleft[0].verts[1][1] = M_SQRT2 / 2.0;
>        cubeleft[0].verts[1][2] = -0.5;
>        cubeleft[0].u[1] = uv_ratio;
>        cubeleft[0].v[1] = 0.0;
> 
>        cubeleft[0].verts[2][0] = -M_SQRT2 / 2.0;
>        cubeleft[0].verts[2][1] = 0.0;
>        cubeleft[0].verts[2][2] = 0.5;
>        cubeleft[0].u[2] = 0.0;
>        cubeleft[0].v[2] = uv_ratio;
> 
>        //second triangle
>        cubeleft[1].verts[0][0] = -M_SQRT2 / 2.0;
>        cubeleft[1].verts[0][1] = 0.0;
>        cubeleft[1].verts[0][2] = 0.5;
>        cubeleft[1].u[0] = 0.0;
>        cubeleft[1].v[0] = uv_ratio;
> 
>        cubeleft[1].verts[1][0] = 0.0;
>        cubeleft[1].verts[1][1] = M_SQRT2 / 2.0;
>        cubeleft[1].verts[1][2] = -0.5;
>        cubeleft[1].u[1] = uv_ratio;
>        cubeleft[1].v[1] = 0.0;
> 
>        cubeleft[1].verts[2][0] = 0.0;
>        cubeleft[1].verts[2][1] = M_SQRT2 / 2.0;
>        cubeleft[1].verts[2][2] = 0.5;
>        cubeleft[1].u[2] = uv_ratio;
>        cubeleft[1].v[2] = uv_ratio;
> 
>        nfacesleft = 2;
> 
>        /* Right face - two triangles */
>        cuberight[0].verts[0][0] = 0.0;
>        cuberight[0].verts[0][1] = M_SQRT2 / 2.0;
>        cuberight[0].verts[0][2] = -0.5;
>        cuberight[0].u[0] = 0.0;
>        cuberight[0].v[0] = 0.0;
> 
>        cuberight[0].verts[1][0] = M_SQRT2 / 2.0;
>        cuberight[0].verts[1][1] = 0.0;
>        cuberight[0].verts[1][2] = -0.5;
>        cuberight[0].u[1] = uv_ratio;
>        cuberight[0].v[1] = 0.0;
> 
>        cuberight[0].verts[2][0] = M_SQRT2 / 2.0;
>        cuberight[0].verts[2][1] = 0.0;
>        cuberight[0].verts[2][2] = 0.5;
>        cuberight[0].u[2] = uv_ratio;
>        cuberight[0].v[2] = uv_ratio;
> 
>        //second triangle
>        cuberight[1].verts[0][0] = 0.0;
>        cuberight[1].verts[0][1] = M_SQRT2 / 2.0;
>        cuberight[1].verts[0][2] = -0.5;
>        cuberight[1].u[0] = 0.0;
>        cuberight[1].v[0] = 0.0;
> 
>        cuberight[1].verts[1][0] = M_SQRT2 / 2.0;
>        cuberight[1].verts[1][1] = 0.0;
>        cuberight[1].verts[1][2] = 0.5;
>        cuberight[1].u[1] = uv_ratio;
>        cuberight[1].v[1] = uv_ratio;
> 
>        cuberight[1].verts[2][0] = 0.0;
>        cuberight[1].verts[2][1] = M_SQRT2 / 2.0;
>        cuberight[1].verts[2][2] = 0.5;
>        cuberight[1].u[2] = 0.0;
>        cuberight[1].v[2] = uv_ratio;
> 
>        nfacesright = 2;
> 
>        //Refine a triangular mesh by bisecting each edge forms 3 new triangles for each existing triangle on each iteration
>        //Could be made more efficient for drawing if the triangles were ordered in a fan. Not that important since we are using DisplayLists
> 
>        for (i=0;i<m_resolution;i++) {
>                cubetop.resize(4*nfacestop);
>                SplitFace(cubetop,&nfacestop);
>                cubebottom.resize(4*nfacesbottom);
>                SplitFace(cubebottom,&nfacesbottom);
>                cubeleft.resize(4*nfacesleft);
>                SplitFace(cubeleft,&nfacesleft);
>                cuberight.resize(4*nfacesright);
>                SplitFace(cuberight,&nfacesright);
>        }
> 
>        // Turn into a hemisphere
>        for (j=0;j<3;j++) {
>                for (i=0;i<nfacestop;i++)
>                        cubetop[i].verts[j].normalize();
>                for (i=0;i<nfacesbottom;i++)
>                        cubebottom[i].verts[j].normalize();
>                for (i=0;i<nfacesleft;i++)
>                        cubeleft[i].verts[j].normalize();
>                for (i=0;i<nfacesright;i++)
>                        cuberight[i].verts[j].normalize();
>        }
> 
>        //flatten onto xz plane
>        for (i=0;i<nfacestop;i++)
>                FlattenDome(cubetop[i].verts);
>        for (i=0;i<nfacesbottom;i++)
>                FlattenDome(cubebottom[i].verts);
>        for (i=0;i<nfacesleft;i++)
>                FlattenDome(cubeleft[i].verts);
>        for (i=0;i<nfacesright;i++)
>                FlattenDome(cuberight[i].verts);
> 
> }
> 
> ===========================================================================
> void KX_Dome::CreateMeshDome250(void)
> {
>        /*
>         * 1)-  Define the faces of a cube without the back face
>         *  - each face is made out of 2 triangles
>         * 2) Subdivide the faces
>         *  - more resolution == more curved lines
>         * 3) Spherize the cube
>         *  - normalize the verts
>         * 4) Flatten onto xz plane
>         *  - transform it onto an equidistant spherical projection techniques to transform the sphere onto a dome image
>         */
> 
>        int i,j;
>        float uv_height, uv_base;
>        float verts_height;
> 
>        float rad_ang = m_angle * MT_PI / 180.0;
>        float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
> 
>        m_radangle = m_angle * M_PI/180.0;//calculates the radians angle, used for flattening
>        /*
>         * verts_height is the exactly needed height of the cube faces (not always 1.0).
>         * When we want some horizontal information (e.g. for horizontal 220deg domes) we don't need to create and tessellate the whole cube.
>         * Therefore the lateral cube faces could be small, and the tessellate mesh would be completely used.
>         * (if we always worked with verts_height = 1.0, we would be discarding a lot of the calculated and tessellated geometry).
>         *
>         * So I came out with this formula:
>         * verts_height = tan((rad_ang/2) - (MT_PI/2))*sqrt(2.0);
>         *
>         * Here we take half the sphere(rad_ang/2) and subtract a quarter of it (MT_PI/2)
>         * Therefore we have the length in radians of the dome/sphere over the horizon.
>         * Once we take the tangent of that angle, you have the verts coordinate corresponding to the verts on the side faces.
>         * Then we need to multiply it by sqrt(2.0) to get the coordinate of the verts on the diagonal of the original cube.
>         */
>        verts_height = tanf((rad_ang / 2.0f) - (float)(MT_PI / 2.0)) * (float)M_SQRT2;
> 
>        uv_height = uv_ratio * (       (verts_height / 2.0f) + 0.5f);
>        uv_base   = uv_ratio * (1.0 - ((verts_height / 2.0f) + 0.5f));
> 
>        //creating faces for the env mapcube 180deg Dome
>        // Front Face - 2 triangles
>        cubefront[0].verts[0][0] =-1.0;
>        cubefront[0].verts[0][1] = 1.0;
>        cubefront[0].verts[0][2] =-1.0;
>        cubefront[0].u[0] = 0.0;
>        cubefront[0].v[0] = 0.0;
> 
>        cubefront[0].verts[1][0] = 1.0;
>        cubefront[0].verts[1][1] = 1.0;
>        cubefront[0].verts[1][2] = 1.0;
>        cubefront[0].u[1] = uv_ratio;
>        cubefront[0].v[1] = uv_ratio;
> 
>        cubefront[0].verts[2][0] =-1.0;
>        cubefront[0].verts[2][1] = 1.0;
>        cubefront[0].verts[2][2] = 1.0;
>        cubefront[0].u[2] = 0.0;
>        cubefront[0].v[2] = uv_ratio;
> 
>        //second triangle
>        cubefront[1].verts[0][0] = 1.0;
>        cubefront[1].verts[0][1] = 1.0;
>        cubefront[1].verts[0][2] = 1.0;
>        cubefront[1].u[0] = uv_ratio;
>        cubefront[1].v[0] = uv_ratio;
> 
>        cubefront[1].verts[1][0] =-1.0;
>        cubefront[1].verts[1][1] = 1.0;
>        cubefront[1].verts[1][2] =-1.0;
>        cubefront[1].u[1] = 0.0;
>        cubefront[1].v[1] = 0.0;
> 
>        cubefront[1].verts[2][0] = 1.0;
>        cubefront[1].verts[2][1] = 1.0;
>        cubefront[1].verts[2][2] =-1.0;
>        cubefront[1].u[2] = uv_ratio;
>        cubefront[1].v[2] = 0.0;
> 
>        nfacesfront = 2;
> 
>        // Left Face - 2 triangles
>        cubeleft[0].verts[0][0] =-1.0;
>        cubeleft[0].verts[0][1] = 1.0;
>        cubeleft[0].verts[0][2] =-1.0;
>        cubeleft[0].u[0] = uv_ratio;
>        cubeleft[0].v[0] = 0.0;
> 
>        cubeleft[0].verts[1][0] =-1.0;
>        cubeleft[0].verts[1][1] =-verts_height;
>        cubeleft[0].verts[1][2] = 1.0;
>        cubeleft[0].u[1] = uv_base;
>        cubeleft[0].v[1] = uv_ratio;
> 
>        cubeleft[0].verts[2][0] =-1.0;
>        cubeleft[0].verts[2][1] =-verts_height;
>        cubeleft[0].verts[2][2] =-1.0;
>        cubeleft[0].u[2] = uv_base;
>        cubeleft[0].v[2] = 0.0;
> 
>        //second triangle
>        cubeleft[1].verts[0][0] =-1.0;
>        cubeleft[1].verts[0][1] =-verts_height;
>        cubeleft[1].verts[0][2] = 1.0;
>        cubeleft[1].u[0] = uv_base;
>        cubeleft[1].v[0] = uv_ratio;
> 
>        cubeleft[1].verts[1][0] =-1.0;
>        cubeleft[1].verts[1][1] = 1.0;
>        cubeleft[1].verts[1][2] =-1.0;
>        cubeleft[1].u[1] = uv_ratio;
>        cubeleft[1].v[1] = 0.0;
> 
>        cubeleft[1].verts[2][0] =-1.0;
>        cubeleft[1].verts[2][1] = 1.0;
>        cubeleft[1].verts[2][2] = 1.0;
>        cubeleft[1].u[2] = uv_ratio;
>        cubeleft[1].v[2] = uv_ratio;
> 
>        nfacesleft = 2;
> 
>        // right Face - 2 triangles
>        cuberight[0].verts[0][0] = 1.0;
>        cuberight[0].verts[0][1] = 1.0;
>        cuberight[0].verts[0][2] = 1.0;
>        cuberight[0].u[0] = 0.0;
>        cuberight[0].v[0] = uv_ratio;
> 
>        cuberight[0].verts[1][0] = 1.0;
>        cuberight[0].verts[1][1] =-verts_height;
>        cuberight[0].verts[1][2] =-1.0;
>        cuberight[0].u[1] = uv_height;
>        cuberight[0].v[1] = 0.0;
> 
>        cuberight[0].verts[2][0] = 1.0;
>        cuberight[0].verts[2][1] =-verts_height;
>        cuberight[0].verts[2][2] = 1.0;
>        cuberight[0].u[2] = uv_height;
>        cuberight[0].v[2] = uv_ratio;
> 
>        //second triangle
>        cuberight[1].verts[0][0] = 1.0;
>        cuberight[1].verts[0][1] =-verts_height;
>        cuberight[1].verts[0][2] =-1.0;
>        cuberight[1].u[0] = uv_height;
>        cuberight[1].v[0] = 0.0;
> 
>        cuberight[1].verts[1][0] = 1.0;
>        cuberight[1].verts[1][1] = 1.0;
>        cuberight[1].verts[1][2] = 1.0;
>        cuberight[1].u[1] = 0.0;
>        cuberight[1].v[1] = uv_ratio;
> 
>        cuberight[1].verts[2][0] = 1.0;
>        cuberight[1].verts[2][1] = 1.0;
>        cuberight[1].verts[2][2] =-1.0;
>        cuberight[1].u[2] = 0.0;
>        cuberight[1].v[2] = 0.0;
> 
>        nfacesright = 2;
> 
>        // top Face - 2 triangles
>        cubetop[0].verts[0][0] =-1.0;
>        cubetop[0].verts[0][1] = 1.0;
>        cubetop[0].verts[0][2] = 1.0;
>        cubetop[0].u[0] = 0.0;
>        cubetop[0].v[0] = 0.0;
> 
>        cubetop[0].verts[1][0] = 1.0;
>        cubetop[0].verts[1][1] =-verts_height;
>        cubetop[0].verts[1][2] = 1.0;
>        cubetop[0].u[1] = uv_ratio;
>        cubetop[0].v[1] = uv_height;
> 
>        cubetop[0].verts[2][0] =-1.0;
>        cubetop[0].verts[2][1] =-verts_height;
>        cubetop[0].verts[2][2] = 1.0;
>        cubetop[0].u[2] = 0.0;
>        cubetop[0].v[2] = uv_height;
> 
>        //second triangle
>        cubetop[1].verts[0][0] = 1.0;
>        cubetop[1].verts[0][1] =-verts_height;
>        cubetop[1].verts[0][2] = 1.0;
>        cubetop[1].u[0] = uv_ratio;
>        cubetop[1].v[0] = uv_height;
> 
>        cubetop[1].verts[1][0] =-1.0;
>        cubetop[1].verts[1][1] = 1.0;
>        cubetop[1].verts[1][2] = 1.0;
>        cubetop[1].u[1] = 0.0;
>        cubetop[1].v[1] = 0.0;
> 
>        cubetop[1].verts[2][0] = 1.0;
>        cubetop[1].verts[2][1] = 1.0;
>        cubetop[1].verts[2][2] = 1.0;
>        cubetop[1].u[2] = uv_ratio;
>        cubetop[1].v[2] = 0.0;
> 
>        nfacestop = 2;
> 
>        // bottom Face - 2 triangles
>        cubebottom[0].verts[0][0] =-1.0;
>        cubebottom[0].verts[0][1] =-verts_height;
>        cubebottom[0].verts[0][2] =-1.0;
>        cubebottom[0].u[0] = 0.0;
>        cubebottom[0].v[0] = uv_base;
> 
>        cubebottom[0].verts[1][0] = 1.0;
>        cubebottom[0].verts[1][1] = 1.0;
>        cubebottom[0].verts[1][2] =-1.0;
>        cubebottom[0].u[1] = uv_ratio;
>        cubebottom[0].v[1] = uv_ratio;
> 
>        cubebottom[0].verts[2][0] =-1.0;
>        cubebottom[0].verts[2][1] = 1.0;
>        cubebottom[0].verts[2][2] =-1.0;
>        cubebottom[0].u[2] = 0.0;
>        cubebottom[0].v[2] = uv_ratio;
> 
>        //second triangle
>        cubebottom[1].verts[0][0] = 1.0;
>        cubebottom[1].verts[0][1] = 1.0;
>        cubebottom[1].verts[0][2] =-1.0;
>        cubebottom[1].u[0] = uv_ratio;
>        cubebottom[1].v[0] = uv_ratio;
> 
>        cubebottom[1].verts[1][0] =-1.0;
>        cubebottom[1].verts[1][1] =-verts_height;
>        cubebottom[1].verts[1][2] =-1.0;
>        cubebottom[1].u[1] = 0.0;
>        cubebottom[1].v[1] = uv_base;
> 
>        cubebottom[1].verts[2][0] = 1.0;
>        cubebottom[1].verts[2][1] =-verts_height;
>        cubebottom[1].verts[2][2] =-1.0;
>        cubebottom[1].u[2] = uv_ratio;
>        cubebottom[1].v[2] = uv_base;
> 
>        nfacesbottom = 2;
> 
>        //Refine a triangular mesh by bisecting each edge forms 3 new triangles for each existing triangle on each iteration
>        //It could be made more efficient for drawing if the triangles were ordered in a strip!
> 
>        for (i=0;i<m_resolution;i++) {
>                cubefront.resize(4*nfacesfront);
>                SplitFace(cubefront,&nfacesfront);
>                cubetop.resize(4*nfacestop);
>                SplitFace(cubetop,&nfacestop);
>                cubebottom.resize(4*nfacesbottom);
>                SplitFace(cubebottom,&nfacesbottom);
>                cubeleft.resize(4*nfacesleft);
>                SplitFace(cubeleft,&nfacesleft);
>                cuberight.resize(4*nfacesright);
>                SplitFace(cuberight,&nfacesright);
>        }
> 
>        // Turn into a hemisphere/sphere
>        for (j=0;j<3;j++) {
>                for (i=0;i<nfacesfront;i++)
>                        cubefront[i].verts[j].normalize();
>                for (i=0;i<nfacestop;i++)
>                        cubetop[i].verts[j].normalize();
>                for (i=0;i<nfacesbottom;i++)
>                        cubebottom[i].verts[j].normalize();
>                for (i=0;i<nfacesleft;i++)
>                        cubeleft[i].verts[j].normalize();
>                for (i=0;i<nfacesright;i++)
>                        cuberight[i].verts[j].normalize();
>        }
> 
>        //flatten onto xz plane
>        for (i=0;i<nfacesfront;i++)
>                FlattenDome(cubefront[i].verts);
>        for (i=0;i<nfacestop;i++)
>                FlattenDome(cubetop[i].verts);
>        for (i=0;i<nfacesbottom;i++)
>                FlattenDome(cubebottom[i].verts);
>        for (i=0;i<nfacesleft;i++)
>                FlattenDome(cubeleft[i].verts);
>        for (i=0;i<nfacesright;i++)
>                FlattenDome(cuberight[i].verts);
> }
> <goDomeWarp-6m.data><CMU-DOME.data>





More information about the Chimera-dev mailing list