/*
        public override void setMaterial(Material m)
        {
            int numobjs = objs.Count;
            for(int i = 0; i < numobjs; i++)
            {
                objs[i].setMaterial(m);
            }
        }
        */
        public static CompoundRenderable LoadCompoundRenderable(XmlElement def)
        {
            CompoundRenderable toReturn = new CompoundRenderable();

            //Select all renderable children of this compound object container
            XmlNodeList children = def.SelectNodes("renderable");
            foreach(XmlElement e in children)
            {
                //Load each child and store in list
                RenderableObject rend = RenderableObject.LoadRenderableObject(e);
                if (rend != null)
                    toReturn.AddObject(rend);
            }

            return toReturn;
        }
Example #2
0
        /*
        public override BoundingBox get_bounding_box()
        {
            return bbox;
        }
        */
        /// <summary>
        /// Sets up the grid acceleration structure
        /// </summary>
        public void SetupCells()
        {
            //Construct bounding box
            Point3D pmin = MinimumCoordinates();
            Point3D pmax = max_coordinates();

            _boundingBox.corner0 = pmin.Coordinates;
            _boundingBox.corner1 = pmax.Coordinates;
            //bbox.x0 = pmin.coords.X; bbox.y0 = pmin.coords.Y; bbox.z0 = pmin.coords.Z;
            //bbox.x1 = pmax.coords.X; bbox.y1 = pmax.coords.Y; bbox.z1 = pmax.coords.Z;

            int numobjs = containedObjects.Count;
            //Find width of grid structure
            float wx = pmax.X - pmin.X;
            float wy = pmax.Y - pmin.Y;
            float wz = pmax.Z - pmin.Z;
            float multiplier = 2.0f; //For approximately 8x the number of cells as objects.

            //Calculate number of cells according to formulae given by Shirley (2000)
            //s = (wxwywz/n)^(1/3)
            //n = trunc(mw/s) + 1;
            float s = (float)Math.Pow((double)((wx * wy * wz) / numobjs), (1.0 / 3.0));
            nx = (int)(multiplier * wx / s + 1);
            ny = (int)(multiplier * wy / s + 1);
            nz = (int)(multiplier * wz / s + 1);

            //Get the computed number of cells
            int num_cells = nx * ny * nz;
            //Null initialize the set of cells
            cells = new RenderableObject[num_cells];
            for(int i = 0; i < num_cells; i++)
            {
                cells[i] = null;
            }

            //Temporary list to hold the number of objects in each cell
            int[] counts = new int[num_cells];
            for(int i = 0;i < num_cells;i++)
            {
                counts[i] = 0;
            }

            BoundingBox objectBoundingBox;
            int index;

            //Put objects in cells
            for(int i = 0; i < numobjs; i++)
            {
                objectBoundingBox = containedObjects[i].BoundingBox;

                //Find the corners of the bounding box in terms of cell indices of the grid
                //According to the mathematical relationship f(p) = (px - p0x)/(p1x-p0x) [0.0,1.0]
                //index = nf(p)
                int ixmin = (int)Clamp((objectBoundingBox.corner0.X - pmin.X) * nx / (pmax.X - pmin.X), 0, nx - 1);
                int iymin = (int)Clamp((objectBoundingBox.corner0.Y - pmin.Y) * ny / (pmax.Y - pmin.Y), 0, ny - 1);
                int izmin = (int)Clamp((objectBoundingBox.corner0.Z - pmin.Z) * nz / (pmax.Z - pmin.Z), 0, nz - 1);
                int ixmax = (int)Clamp((objectBoundingBox.corner1.X - pmin.X) * nx / (pmax.X - pmin.X), 0, nx - 1);
                int iymax = (int)Clamp((objectBoundingBox.corner1.Y - pmin.Y) * ny / (pmax.Y - pmin.Y), 0, ny - 1);
                int izmax = (int)Clamp((objectBoundingBox.corner1.Z - pmin.Z) * nz / (pmax.Z - pmin.Z), 0, nz - 1);

                //int ixmin = (int)clamp((object_bbox.x0 - pmin.coords.X) * nx / (pmax.coords.X - pmin.coords.X), 0, nx - 1);
                //int iymin = (int)clamp((object_bbox.y0 - pmin.coords.Y) * ny / (pmax.coords.Y - pmin.coords.Y), 0, ny - 1);
                //int izmin = (int)clamp((object_bbox.z0 - pmin.coords.Z) * nz / (pmax.coords.Z - pmin.coords.Z), 0, nz - 1);
                //int ixmax = (int)clamp((object_bbox.x1 - pmin.coords.X) * nx / (pmax.coords.X - pmin.coords.X), 0, nx - 1);
                //int iymax = (int)clamp((object_bbox.y1 - pmin.coords.Y) * ny / (pmax.coords.Y - pmin.coords.Y), 0, ny - 1);
                //int izmax = (int)clamp((object_bbox.z1 - pmin.coords.Z) * nz / (pmax.coords.Z - pmin.coords.Z), 0, nz - 1);

                //With the index information traverse all cells and add objects to cells that they are contained in.
                for(int iz = izmin; iz <= izmax; iz++)
                {
                    for(int iy = iymin; iy <= iymax; iy++)
                    {
                        for(int ix = ixmin; ix<= ixmax;ix++)
                        {
                            index = ix + (nx * iy) + (nx * ny * iz);

                            //Just add the object if no objects are stored in cell already
                            if(counts[index] == 0)
                            {
                                cells[index] = containedObjects[i];
                                counts[index]++;
                            }
                            //If object is already stored in cell, create a new compound object and store
                            //the two objects in it
                            else if(counts[index] == 1)
                            {
                                CompoundRenderable compoundObject = new CompoundRenderable();
                                compoundObject.AddObject(cells[index]);
                                compoundObject.AddObject(containedObjects[i]);

                                cells[index] = compoundObject;
                                counts[index]++;
                            }
                            //If more than one object is in the cell, just add it to the compound object already contained in the cell
                            else if(counts[index] > 1)
                            {
                                //Safe to assume that if this code is running, the object at cells[index] is a compoundrenderable
                                ((CompoundRenderable)cells[index]).AddObject(containedObjects[i]);
                                counts[index]++;
                            }
                        }

                    }
                }
            }
        }