示例#1
0
        /// <summary>
        /// Gets a new instance of Scene.
        /// </summary>
        /// <param name="maxWalls">Max walls that the scene can fit</param>
        /// <param name="maxSprities">Max sprities that the scene can fit</param>
        public Scene(int maxWalls = 512, int maxSprities = 512)
        {
            if (maxWalls <= 0)
            {
                throw new ArgumentException("maxWalls cannot be < 1.");
            }
            if (maxSprities <= 0)
            {
                throw new ArgumentException("maxSprities cannot be < 1.");
            }

            Texture background = new Texture((PixelBuffer) new Bitmap(1, 1));

            unmanaged = SceneData.Create(maxWalls, maxSprities, background);
        }
示例#2
0
        internal static SceneData *Create(int maxWalls, int maxSprities, Texture background)
        {
            int        total_positions = maxWalls + maxSprities + 1;
            SceneData *result          = (SceneData *)Marshal.AllocHGlobal(sizeof(SceneData));

            result->sprities = null;
            //result->sprities = (Sprite_**)Marshal.AllocHGlobal(maxSprities * sizeof(Sprite_*)); // Not implemented yet
            result->walls = (WallData **)Marshal.AllocHGlobal(total_positions * sizeof(void *));
            *result->walls = null;
            result->sprite_count = 0;
            result->sprite_max   = maxSprities;
            result->wall_count   = 0;
            result->wall_max     = maxWalls;
            result->background   = background;
            return(result);
        }
示例#3
0
        private WallData *NearestWallTest(SceneData *map, out float nearest_dist, out float nearest_hratio)
        {
            nearest_dist   = float.PositiveInfinity;
            nearest_hratio = 2f;
            WallData * nearest = null;
            WallData **pptr    = map->walls;

            while (*pptr != null)
            {
                //Medium performance impact.
                GetCollisionData(*pptr, out float cur_dist, out float cur_split);
                if (cur_dist < nearest_dist)
                {
                    nearest_hratio = cur_split;
                    nearest_dist   = cur_dist;
                    nearest        = *pptr;
                }
                pptr++;
            }
            return(nearest);
        }
示例#4
0
        internal WallData *NearestWall(SceneData *map, out float nearest_dist, out float nearest_ratio)
        {
            nearest_dist  = float.PositiveInfinity;
            nearest_ratio = 2f;
            int        wallcount = map->wall_count;
            WallData **cur       = map->walls;
            WallData * nearest   = null;

            for (int i = 0; i < wallcount; i++)
            {
                //walls cannot be null.
                GetCollisionData(*cur, out float cur_dist, out float cur_ratio);
                if (cur_dist < nearest_dist)
                {
                    nearest_ratio = cur_ratio;
                    nearest_dist  = cur_dist;
                    nearest       = *cur;
                }
                cur++;
            }
            return(nearest);
        }
示例#5
0
        private unsafe static void CLRRender(PixelBuffer target, SceneData *scene)        // Must be changed
        {
            //Caching frequently used values.
            uint *  buffer     = target.uint0;
            int     width      = target.width;
            int     height     = target.height;
            Texture background = scene->background;

            if (ParallelRendering)
            {
                Parallel.For(0, width, Loop);
            }
            else
            {
                for (int i = 0; i < width; i++)
                {
                    Loop(i);
                }
            }

            void Loop(int ray_id)
            //for (int ray_id = 0; ray_id < rendererData->bitmap_width; ray_id++)
            {
                //Caching
                float ray_cos   = cache->cosines[ray_id];
                float ray_angle = cache->angles[ray_id] + scene->activeObserver->rotation;
                Ray   ray       = new Ray(scene->activeObserver->position, ray_angle);

                //Cast the ray towards every wall.
                WallData *nearest = ray.NearestWall(scene, out float nearest_dist, out float nearest_ratio);

                if (nearest_ratio != 2f)
                {
                    float columnHeight = (cache->colHeight1 / (ray_cos * nearest_dist)); //Wall column size in pixels

                    float column_start      = (height - columnHeight) / 2f;
                    float column_end        = (height + columnHeight) / 2f;
                    int   draw_column_start = (int)column_start;
                    int   draw_column_end   = (int)column_end;
                    if (draw_column_start < 0)
                    {
                        draw_column_start = 0;
                    }
                    if (draw_column_end > height)
                    {
                        draw_column_end = height;
                    }

                    for (int line = 0; line < draw_column_start; line++)
                    {
                        //PURPOSELY REPEATED CODE!
                        float background_hratio = ray_angle / 360 + 1; //Temporary bugfix to avoid hratio being < 0
                        float screenVratio      = (float)line / height;
                        float background_vratio = (1 - ray_cos) / 2 + ray_cos * screenVratio;
                        uint  color             = background.MapPixel(background_hratio, background_vratio);
                        buffer[width * line + ray_id] = color;
                    }
                    for (int line = draw_column_start; line < draw_column_end; line++)
                    {
                        float vratio = (line - column_start) / columnHeight;
                        uint  pixel  = nearest->texture.MapPixel(nearest_ratio, vratio);
                        buffer[width * line + ray_id] = pixel;
                    }
                    for (int line = draw_column_end; line < height; line++)
                    {
                        //PURPOSELY REPEATED CODE!
                        float background_hratio = ray_angle / 360 + 1; //Temporary bugfix to avoid hratio being < 0
                        float screenVratio      = (float)line / height;
                        float background_vratio = (1 - ray_cos) / 2 + ray_cos * screenVratio;
                        uint  color             = background.MapPixel(background_hratio, background_vratio);
                        buffer[width * line + ray_id] = color;
                    }
                }
                else
                {
                    for (int line = 0; line < height; line++)
                    {
                        //Critical performance impact.
                        //PURPOSELY REPEATED CODE!
                        float background_hratio = ray_angle / 360 + 1;
                        float screenVratio      = (float)line / height;
                        float background_vratio = (1 - ray_cos) / 2 + ray_cos * screenVratio;
                        uint  color             = background.MapPixel(background_hratio, background_vratio);
                        buffer[width * line + ray_id] = color;
                    }
                }
            }
        }
示例#6
0
 public static void Delete(SceneData *item)
 {
     Marshal.FreeHGlobal((IntPtr)item->sprities);
     Marshal.FreeHGlobal((IntPtr)item->walls);
     Marshal.FreeHGlobal((IntPtr)item);
 }