• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當(dāng)自強(qiáng)而不息

            Working with Maps and Levels(10)

            Continue now with the cBarrier class declaration:

            When you need to assign a mesh to a barrier, use the set_mesh function, passing the
            barrier’s identification number to set, as well as cMesh objects to use.
            For setting an animation for a barrier, you pass the barrier’s
            identification number, cAnimation object, the name of the animation to use, and the
            time the animation is set (using a timer function such as timeGetTime).

            You need to assign meshes and animations.
            Each barrier has a dedicated cObject to use for orientation, but first a mesh must be
            assigned via the set_mesh function. Animations are sure to follow using the set_anim
            function. Take a look at each of the functions responsible for setting those meshes
            and animations.

            After you've loaded or created barriers, assign the meshes by their respective barrier
            identification numbers. Notice that the set_anim function is just like the
            cObject::set_anim_set function—you have the name of the animation and the starting
            time of the animation.

            Both functions simply scan through the linked list of barriers looking for a matching
            identification number.

                void set_mesh(long id, cMesh* mesh)
                {
                    
            for(sBarrier* bar = m_root_barrier; bar != NULL; bar = bar->next)
                    {
                        
            if(bar->id == id)            
                            bar->
            object.create(mesh);
                    }
                }

                
            void set_anim(long id, cAnimation* anim, pcstr name, long start_time)
                {
                    
            for(sBarrier* bar = m_root_barrier; bar != NULL; bar = bar->next)
                    {
                        
            if(bar->id == id)            
                            bar->
            object.set_anim_set(anim, name, start_time);            
                    }
                }

            After you assign a mesh and animation, you can render a barrier to the display using
            the following render function. The render function takes as arguments the current
            time to update the animations (again using timeGetTime) and the viewing frustum to
            use for clipping out the barriers that are out of the viewpoint.

            The only other exclusive function in cBarrier (as opposed to cTrigger) is Render,
            which takes a time value that is used to update the barriers’ animations and a viewing
            frustum that is used to clip out unseen barrier objects. Take a look at the render
            function code:

            void cBarrier::render(ulong time_now, cFrustum* frustum)
            {
                
            for(sBarrier* bar = m_root_barrier; bar != NULL; bar = bar->next)
                {
                    cObject* 
            object = &bar->object;

                    
            float radius;
                    
            object->get_bounds(NULL, NULL, NULL, NULL, NULL, NULL, &radius);

                    
            if(frustum->is_sphere_in(bar->x_pos, bar->y_pos, bar->z_pos, radius))
                    {
                        
            object->move(bar->x_pos, bar->y_pos, bar->z_pos);
                        
            object->rotate(bar->x_rot, bar->y_rot, bar->z_rot);

                        
            object->update_anim(time_now, true);
                        
            object->render();
                    }
                }
            }

            In the preceding render function, the linked list of barriers is scanned, and for each
            barrier, a frustum check is performed. If a barrier is in the view, its respective animation
            is updated and the mesh is rendered.

            When it comes time to start adding barriers to the linked list, the cBarrier class
            comes packed with as many functions to do so as cTrigger.
             

            public:

                
            void add_sphere(long id, bool enabled,
                                
            float x_pos,  float y_pos,  float z_pos,
                                
            float x_rot,  float y_rot,  float z_rot,
                                
            float cx_pos, float cy_pos, float cz_pos,
                                
            float radius)
                {
                    sBarrier* bar = add_barrier(BARRIER_SPHERE, id, enabled, x_pos, y_pos, z_pos, x_rot, y_rot, z_rot);

                    bar->x1     = cx_pos;
                    bar->y1     = cy_pos;
                    bar->z1     = cz_pos;
                    bar->radius = radius * radius;
                }

                
            void add_box(long id, bool enabled,
                             
            float x_pos,  float y_pos,  float z_pos,
                             
            float x_rot,  float y_rot,  float z_rot,
                             
            float x_min,  float y_min,  float z_min,
                             
            float x_max,  float y_max,  float z_max)
                {
                    sBarrier* bar = add_barrier(BARRIER_SPHERE, id, enabled, x_pos, y_pos, z_pos, x_rot, y_rot, z_rot);

                    
            // setup barrier data (fix for min/max values)
                    bar->x1 = min(x_min, x_max);
                    bar->y1 = min(y_min, y_max);
                    bar->z1 = min(z_min, z_max);
                    bar->x2 = max(x_min, x_max);
                    bar->y2 = max(y_min, y_max);
                    bar->z2 = max(z_min, z_max);
                }

                
            void add_cylinder(long id, bool enabled,
                                  
            float x_pos,  float y_pos,  float z_pos,
                                  
            float x_rot,  float y_rot,  float z_rot,
                                  
            float cx_pos, float cy_pos, float cz_pos,
                                  
            float radius, float height)
                {
                    sBarrier* bar = add_barrier(BARRIER_SPHERE, id, enabled, x_pos, y_pos, z_pos, x_rot, y_rot, z_rot);

                    bar->x1     = cx_pos;
                    bar->y1     = cy_pos;
                    bar->z1     = cz_pos;
                    bar->radius = radius * radius;
                    bar->y2     = height;
                }

                
            void add_triangle(long id, bool enabled,
                                  
            float x_pos,  float y_pos,  float z_pos,
                                  
            float x_rot,  float y_rot,  float z_rot,
                                  
            float x1, float z1,
                                  
            float x2, float z2,
                                  
            float x3, float z3,
                                  
            float cy_pos, float height)
                {
                    sBarrier* bar = add_barrier(BARRIER_SPHERE, id, enabled, x_pos, y_pos, z_pos, x_rot, y_rot, z_rot);

                    bar->x1 = x1;
                    bar->z1 = z1;
                    bar->x2 = x2;
                    bar->z2 = z2;
                    bar->x3 = x3;
                    bar->z3 = z3;
                    bar->y1 = cy_pos;
                    bar->y2 = height;
                }   

                
            void remove(long id)
                {
                    sBarrier* bar = m_root_barrier;

                    
            while(bar != NULL)
                    {
                        sBarrier* next_bar = bar->next;

                        
            if(bar->id == id)
                        {
                            
            // remove from list

                            
            if(bar->prev)
                                bar->prev->next = bar->next;
                            
            else
                                m_root_barrier = bar->next;

                            
            if(bar->next)
                                bar->next->prev = bar->prev;

                            bar->next = NULL;
                            delete bar;

                            m_num_barriers--;
                        }

                        bar = next_bar;
                    }
                }

                
            bool get_enable_state(long id)
                {
                    
            for(sBarrier* bar = m_root_barrier; bar != NULL; bar = bar->next)
                    {
                        
            if(bar->id == id)
                            
            return bar->enabled;
                    }

                    
            return false;
                }

                
            void enable(long id)
                {
                    set_enable_state(id, 
            true);
                }

                
            void disable(long id)
                {
                    set_enable_state(id, 
            false);
                }

                
            //////////////////////////////////////////////////////////////////////

            public:
                
            bool load(const char* filename);
                
            bool save(const char* filename);

                
            void render(ulong time_now, cFrustum* frustum);
                
            long get_barrier(float x_pos, float y_pos, float z_pos);    
            } *cBarrierPtr;


            Other function:

            bool cBarrier::load(const char* filename)
            {
                free();     
            // remove all current barriers

                FILE* fp = fopen(filename, "rb");
                
            if(fp == NULL)
                    
            return false;

                
            // start looping, reading in until EOF reached.
                for(;;)
                {
                    
            long id = get_next_long_2(fp);
                    
            if(id == -1)
                        
            break;

                    
            long type    = get_next_long_2(fp);
                    
            bool enabled = get_next_long_2(fp) ? true : false;   

                    
            // get coordinate and rotation
                    float x_pos = get_next_float_2(fp);
                    
            float y_pos = get_next_float_2(fp);
                    
            float z_pos = get_next_float_2(fp);
                    
            float x_rot = get_next_float_2(fp);
                    
            float y_rot = get_next_float_2(fp);
                    
            float z_rot = get_next_float_2(fp);

                    
            float x1, y1, z1, x2, y2, z2, x3, z3, radius;

                    
            // read in rest depending on type
                    switch(type)
                    {
                    
            case BARRIER_SPHERE:
                        x1     = get_next_float_2(fp);
                        y1     = get_next_float_2(fp);
                        z1     = get_next_float_2(fp);
                        radius = get_next_float_2(fp);

                        add_sphere(id, enabled, 
                                   x_pos, y_pos, z_pos, x_rot, y_rot, z_rot, 
                                   x1, y1, z1, radius);
                        
            break;

                    
            case BARRIER_BOX:
                        x1 = get_next_float_2(fp);
                        y1 = get_next_float_2(fp);
                        z1 = get_next_float_2(fp);
                        x2 = get_next_float_2(fp);
                        y2 = get_next_float_2(fp);
                        z2 = get_next_float_2(fp);

                        add_box(id, enabled, 
                                x_pos, y_pos, z_pos, x_rot, y_rot, z_rot,
                                x1, y1, z1, x2, y2, z2);

                        
            break;

                    
            case BARRIER_CYLINDER:
                        x1     = get_next_float_2(fp);
                        y1     = get_next_float_2(fp);
                        z1     = get_next_float_2(fp);
                        radius = get_next_float_2(fp);
                        y2     = get_next_float_2(fp);

                        add_cylinder(id, enabled, 
                                     x_pos, y_pos, z_pos, x_rot, y_rot, z_rot,
                                     x1, y1, z1, radius, y2);

                        
            break;

                    
            case BARRIER_TRIANGLE:
                        x1 = get_next_float_2(fp);
                        z1 = get_next_float_2(fp);
                        x2 = get_next_float_2(fp);
                        z2 = get_next_float_2(fp);
                        x3 = get_next_float_2(fp);
                        z3 = get_next_float_2(fp);
                        y1 = get_next_float_2(fp);
                        y2 = get_next_float_2(fp);

                        add_triangle(id, enabled, 
                                     x_pos, y_pos, z_pos, x_rot, y_rot, z_rot,
                                     x1, z1, x2, z2, x3, z3, y1, y2);

                        
            break;
                
                    
            default:    // some error occurred
                        fclose(fp);
                        free();
                        
            return false;
                    }
                }

                fclose(fp);
                
            return true;
            }

            /////////////////////////////////////////////////////////////////////////////////////////

            bool cBarrier::save(const char* filename)
            {
                
            if(m_num_barriers == 0)
                    
            return false;

                FILE* fp = fopen(filename, "wb");
                
            if(fp == NULL)
                    
            return false;

                
            for(sBarrier* bar = m_root_barrier; bar != NULL; bar = bar->next)
                {
                    
            int enabled = bar->enabled ? 1 : 0;

                    
            char buf[1024];

                    sprintf(buf, "%lu %lu %lu %lf %lf %lf %lf %lf %lf",
                            bar->id, bar->type, enabled,
                            bar->x_pos, bar->y_pos, bar->z_pos,
                            bar->x_rot, bar->y_rot, bar->z_rot);

                    
            // write out remaining data depending on type
                    switch(bar->type)
                    {
                    
            case BARRIER_SPHERE:
                        fprintf(fp, "%s %lf %lf %lf %lf\r\n",
                                buf, bar->x1, bar->y1, bar->z1, bar->radius);

                        
            break;

                    
            case BARRIER_BOX:
                        fprintf(fp, "%s %lf %lf %lf %lf %lf %lf\r\n",
                                buf, bar->x1, bar->y1, bar->z1, bar->x2, bar->y2, bar->z2);

                        
            break;

                    
            case BARRIER_CYLINDER:
                        fprintf(fp, "%s %lf %lf %lf %lf %lf\r\n",
                                buf, bar->x1, bar->y1, bar->z1, bar->radius, bar->y2);

                        
            break;

                    
            case BARRIER_TRIANGLE:
                        fprintf(fp, "%s %lf %lf %lf %lf %lf %lf %lf %lf\r\n",
                                buf,
                                bar->x1, bar->z1, bar->x2, bar->z2, bar->x3, bar->z3,
                                bar->y1, bar->y2);

                        
            break;
                    }
                }

                fclose(fp);
                
            return true;
            }

            /////////////////////////////////////////////////////////////////////////////////////////

            long cBarrier::get_barrier(float x_pos, float y_pos, float z_pos)
            {
                D3DXVECTOR2 norm_vec;

                
            for(sBarrier* bar = m_root_barrier; bar != NULL; bar = bar->next)
                {
                    
            // only bother if enabled
                    if(! bar->enabled)
                        
            continue;

                    
            float x_diff, y_diff, z_diff, dist;

                    
            switch(bar->type)
                    {
                    
            case BARRIER_SPHERE:
                        
            // check distance from sphere
                        x_diff = fabs(bar->x1 - x_pos);
                        y_diff = fabs(bar->y1 - y_pos);
                        z_diff = fabs(bar->z1 - z_pos);

                        dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;

                        
            if(dist <= bar->radius)
                            
            return bar->id;
                        
                        
            break;

                    
            case BARRIER_BOX:
                        
            // check if inside box
                        if((x_pos >= bar->x1 && x_pos <= bar->x2) &&
                           (y_pos >= bar->y1 && y_pos <= bar->y2) &&
                           (z_pos >= bar->z1 && z_pos <= bar->z2))
                        {
                            
            return bar->id;
                        }

                        
            break;

                    
            case BARRIER_CYLINDER:
                        
            // first make sure within height bounds
                        if(y_pos >= bar->y1 && y_pos <= bar->y1 + bar->y2)
                        {
                            
            // check distance from cylinder
                            x_diff = fabs(bar->x1 - x_pos);
                            y_diff = fabs(bar->y1 - y_pos);
                            z_diff = fabs(bar->z1 - z_pos);

                            dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;

                            
            if(dist <= bar->radius)
                                
            return bar->id;
                        }

                        
            break;

                    
            case BARRIER_TRIANGLE:
                        
            // first make sure within height bounds
                        if(y_pos >= bar->y1 && y_pos <= bar->y1 + bar->y2)
                        {
                            
            // check if point in front of all lines

                            // x1,z1 to x2,z2
                            D3DXVec2Normalize(&norm_vec, &D3DXVECTOR2(bar->z2 - bar->z1, bar->x1 - bar->x2));

                            
            if(D3DXVec2Dot(&D3DXVECTOR2(x_pos - bar->x1, z_pos - bar->z1), &norm_vec) < 0)
                                
            break;

                            
            // x2,z2 to x3,z3
                            D3DXVec2Normalize(&norm_vec, &D3DXVECTOR2(bar->z3 - bar->z2, bar->x2 - bar->x3));

                            
            if(D3DXVec2Dot(&D3DXVECTOR2(x_pos - bar->x2, z_pos - bar->z2), &norm_vec) < 0)
                                
            break;

                            
            // x3,z3 to x1,z1
                            D3DXVec2Normalize(&norm_vec, &D3DXVECTOR2(bar->z1 - bar->z3, bar->x3 - bar->x1));

                            
            if(D3DXVec2Dot(&D3DXVECTOR2(x_pos - bar->x3, z_pos - bar->z3), &norm_vec) < 0)
                                
            break;

                            
            return bar->id;
                        }   

                        
            break;
                    }
                }

                
            return 0;   // means no barrier found
            }

            posted on 2007-12-10 14:11 lovedday 閱讀(255) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            久久国产午夜精品一区二区三区| 无码伊人66久久大杳蕉网站谷歌| 中文字幕亚洲综合久久2| 激情五月综合综合久久69| 久久伊人五月天论坛| 欧美日韩久久中文字幕| 精品综合久久久久久97超人| 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久久久成人精品无码中文字幕| 精品国产乱码久久久久久郑州公司 | 精品久久久久中文字| 精品国产乱码久久久久久呢| 久久精品人人做人人爽电影| 国产精品久久久久a影院| 精品久久一区二区三区| 国产成人无码精品久久久性色| 91精品免费久久久久久久久| 久久精品中文无码资源站| 国产午夜精品久久久久九九电影| 亚洲人成网亚洲欧洲无码久久| 国产免费久久久久久无码| 麻豆成人久久精品二区三区免费| 久久久中文字幕日本| 97超级碰碰碰碰久久久久| 精品久久久久久中文字幕人妻最新| 伊人久久亚洲综合影院| 久久久青草青青国产亚洲免观| 99国产精品久久久久久久成人热| 久久婷婷色综合一区二区| 亚洲午夜精品久久久久久app| 青青草原综合久久| 久久精品国产精品青草| 久久久国产乱子伦精品作者| 亚洲AV无码久久精品蜜桃| 久久精品一本到99热免费| 久久精品国产清自在天天线| 伊人久久亚洲综合影院| 99久久香蕉国产线看观香| 欧美日韩精品久久免费| 午夜不卡久久精品无码免费| 亚洲欧美成人综合久久久|