Search in sources :

Example 16 with IParticleRecord

use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.

the class SerializedDataProvider method loadData.

public List<IParticleRecord> loadData(InputStream is, double factor) {
    try {
        ObjectInputStream ois = new ObjectInputStream(is);
        @SuppressWarnings("unchecked") List<IParticleRecord> // cast is needed.
        l = (List<IParticleRecord>) ois.readObject();
        ois.close();
        // Convert to Array, reconstruct index
        int n = l.size();
        initLists(n);
        list.addAll(l);
        return list;
    } catch (Exception e) {
        logger.error(e);
    }
    return null;
}
Also used : IParticleRecord(gaiasky.scenegraph.particle.IParticleRecord) List(java.util.List) ObjectInputStream(java.io.ObjectInputStream)

Example 17 with IParticleRecord

use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.

the class OctreeGeneratorMag method generateOctree.

@Override
public OctreeNode generateOctree(List<IParticleRecord> catalog) {
    root = IOctreeGenerator.startGeneration(catalog, params);
    // Holds all octree nodes indexed by id
    LongMap<OctreeNode> idMap = new LongMap<>();
    idMap.put(root.pageId, root);
    // Contains the list of objects for each node
    Map<OctreeNode, List<IParticleRecord>> objMap = new HashMap<>();
    int catalogSize = catalog.size();
    int catalogIndex = 0;
    for (int level = 0; level <= 19; level++) {
        logger.info("Generating level " + level + " (" + (catalog.size() - catalogIndex) + " stars left)");
        while (catalogIndex < catalogSize) {
            // Add stars to nodes until we reach max part
            IParticleRecord sb = catalog.get(catalogIndex++);
            double x = sb.x();
            double y = sb.y();
            double z = sb.z();
            Long nodeId = getPositionOctantId(x, y, z, level);
            if (!idMap.containsKey(nodeId)) {
                // Create octant and parents if necessary
                OctreeNode octant = createOctant(nodeId, x, y, z, level);
                // Add to idMap
                idMap.put(octant.pageId, octant);
            }
            // Add star to node
            OctreeNode octant = idMap.get(nodeId);
            int addedNum = addStarToNode(sb, octant, objMap);
            if (addedNum >= params.maxPart) {
                // On to next level!
                break;
            }
        }
        if (catalogIndex >= catalog.size()) {
            // All stars added -> FINISHED
            break;
        }
    }
    if (params.postprocess) {
        logger.info("Post-processing octree: childcount=" + params.childCount + ", parentcount=" + params.parentCount);
        long mergedNodes = 0;
        long mergedObjects = 0;
        // We merge low-count nodes (<= childcount) with parents, if parents' count is <= parentcount
        Object[] nodes = objMap.keySet().toArray();
        // Sort by descending depth
        Arrays.sort(nodes, (node1, node2) -> {
            OctreeNode n1 = (OctreeNode) node1;
            OctreeNode n2 = (OctreeNode) node2;
            return Integer.compare(n2.depth, n1.depth);
        });
        int n = objMap.size();
        for (int i = n - 1; i >= 0; i--) {
            OctreeNode current = (OctreeNode) nodes[i];
            if (current.numChildren() == 0 && current.parent != null && objMap.containsKey(current) && objMap.containsKey(current.parent)) {
                List<IParticleRecord> childArr = objMap.get(current);
                List<IParticleRecord> parentArr = objMap.get(current.parent);
                if (childArr.size() <= params.childCount && parentArr.size() <= params.parentCount) {
                    // Merge children nodes with parent nodes, remove children
                    parentArr.addAll(childArr);
                    objMap.remove(current);
                    current.remove();
                    mergedNodes++;
                    mergedObjects += childArr.size();
                }
            }
        }
        logger.info("POSTPROCESS STATS:");
        logger.info("    Merged nodes:    " + mergedNodes);
        logger.info("    Merged objects:  " + mergedObjects);
    }
    // Tree is ready, create star groups
    Set<OctreeNode> nodes = objMap.keySet();
    for (OctreeNode node : nodes) {
        List<IParticleRecord> list = objMap.get(node);
        StarGroup sg = new StarGroup();
        sg.setData(list, false);
        node.add(sg);
        sg.octant = node;
        sg.octantId = node.pageId;
    }
    root.updateCounts();
    return root;
}
Also used : LongMap(com.badlogic.gdx.utils.LongMap) OctreeNode(gaiasky.util.tree.OctreeNode) StarGroup(gaiasky.scenegraph.StarGroup) IParticleRecord(gaiasky.scenegraph.particle.IParticleRecord)

Example 18 with IParticleRecord

use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.

the class OctreeGeneratorPart method treatLevel.

/**
 * Generate the octree on a per-level basis to have a uniform density in all
 * the nodes of the same level. Breadth-first.
 *
 * @param inputLists List of star beans per octant
 * @param level The depth
 * @param octantsPerLevel Octants of each level
 * @param percentage Percentage
 */
private void treatLevel(Map<OctreeNode, List<IParticleRecord>> inputLists, int level, Array<OctreeNode>[] octantsPerLevel, float percentage) {
    logger.info("Generating level " + level);
    Array<OctreeNode> levelOctants = octantsPerLevel[level];
    octantsPerLevel[level + 1] = new Array<>(false, levelOctants.size * 8);
    /**
     * CREATE OCTANTS FOR LEVEL+1 *
     */
    Iterator<OctreeNode> it = levelOctants.iterator();
    while (it.hasNext()) {
        OctreeNode octant = it.next();
        List<IParticleRecord> list = inputLists.get(octant);
        if (list.size() == 0) {
            // Empty node, remove
            it.remove();
            octant.remove();
        } else {
            boolean leaf = aggregation.sample(list, octant, percentage);
            if (!leaf) {
                // Generate 8 children per each level octant
                double hsx = octant.size.x / 4d;
                double hsy = octant.size.y / 4d;
                double hsz = octant.size.z / 4d;
                /**
                 * CREATE SUB-OCTANTS *
                 */
                // Front - top - left
                octantsPerLevel[level + 1].add(new OctreeNode(octant.centre.x - hsx, octant.centre.y + hsy, octant.centre.z - hsz, hsx, hsy, hsz, octant.depth + 1, octant, 0));
                // Front - top - right
                octantsPerLevel[level + 1].add(new OctreeNode(octant.centre.x + hsx, octant.centre.y + hsy, octant.centre.z - hsz, hsx, hsy, hsz, octant.depth + 1, octant, 1));
                // Front - bottom - left
                octantsPerLevel[level + 1].add(new OctreeNode(octant.centre.x - hsx, octant.centre.y - hsy, octant.centre.z - hsz, hsx, hsy, hsz, octant.depth + 1, octant, 2));
                // Front - bottom - right
                octantsPerLevel[level + 1].add(new OctreeNode(octant.centre.x + hsx, octant.centre.y - hsy, octant.centre.z - hsz, hsx, hsy, hsz, octant.depth + 1, octant, 3));
                // Back - top - left
                octantsPerLevel[level + 1].add(new OctreeNode(octant.centre.x - hsx, octant.centre.y + hsy, octant.centre.z + hsz, hsx, hsy, hsz, octant.depth + 1, octant, 4));
                // Back - top - right
                octantsPerLevel[level + 1].add(new OctreeNode(octant.centre.x + hsx, octant.centre.y + hsy, octant.centre.z + hsz, hsx, hsy, hsz, octant.depth + 1, octant, 5));
                // Back - bottom - left
                octantsPerLevel[level + 1].add(new OctreeNode(octant.centre.x - hsx, octant.centre.y - hsy, octant.centre.z + hsz, hsx, hsy, hsz, octant.depth + 1, octant, 6));
                // Back - bottom - right
                octantsPerLevel[level + 1].add(new OctreeNode(octant.centre.x + hsx, octant.centre.y - hsy, octant.centre.z + hsz, hsx, hsy, hsz, octant.depth + 1, octant, 7));
            }
        }
    }
    /**
     * IF WE HAVE OCTANTS IN THE NEXT LEVEL, INTERSECT *
     */
    if (octantsPerLevel[level + 1].size != 0) {
        /**
         * INTERSECT CATALOG WITH OCTANTS, COMPUTE PERCENTAGE *
         */
        int maxSublevelObjs = 0;
        double maxSublevelMag = Double.MAX_VALUE;
        double minSublevelMag = 0;
        Map<OctreeNode, List<IParticleRecord>> lists = new HashMap<>();
        for (OctreeNode octant : octantsPerLevel[level + 1]) {
            List<IParticleRecord> list = intersect(inputLists.get(octant.parent), octant);
            lists.put(octant, list);
            if (list.size() > maxSublevelObjs) {
                maxSublevelObjs = list.size();
            }
            // Adapt levels by magnitude
            for (IParticleRecord pb : list) {
                IParticleRecord sb = pb;
                if (sb.absmag() < maxSublevelMag) {
                    maxSublevelMag = sb.absmag();
                }
                if (sb.absmag() > minSublevelMag) {
                    minSublevelMag = sb.absmag();
                }
            }
        }
        float sublevelPercentage = MathUtils.clamp((float) aggregation.getMaxPart() / (float) maxSublevelObjs, 0f, 1f);
        /**
         * GO ONE MORE LEVEL DOWN *
         */
        treatLevel(lists, level + 1, octantsPerLevel, sublevelPercentage);
    }
}
Also used : OctreeNode(gaiasky.util.tree.OctreeNode) IParticleRecord(gaiasky.scenegraph.particle.IParticleRecord)

Example 19 with IParticleRecord

use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.

the class UncertaintiesProvider method loadData.

@Override
public List<IParticleRecord> loadData(String file, double factor) {
    FileHandle f = Settings.settings.data.dataFileHandle(file);
    @SuppressWarnings("unchecked") List<IParticleRecord> pointData = loadData(f.read(), factor);
    if (pointData != null)
        logger.info(I18n.txt("notif.nodeloader", pointData.size(), file));
    return pointData;
}
Also used : FileHandle(com.badlogic.gdx.files.FileHandle) IParticleRecord(gaiasky.scenegraph.particle.IParticleRecord)

Example 20 with IParticleRecord

use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.

the class IOctreeGenerator method startGeneration.

/**
 * Computes the maximum axis-aligned bounding box containing
 * all the particles in the catalog, and returns it as the root
 * octree node.
 * @param catalog The incoming catalog
 * @param params The octree generation parameters
 * @return The root octree node
 */
static OctreeNode startGeneration(List<IParticleRecord> catalog, OctreeGeneratorParams params) {
    logger.info("Starting generation of octree");
    // Minimum and maximum positions
    Vector3d min = new Vector3d(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
    Vector3d max = new Vector3d(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE);
    Iterator<IParticleRecord> it = catalog.iterator();
    while (it.hasNext()) {
        IParticleRecord particle = it.next();
        // Min
        if (particle.x() < min.x) {
            min.x = particle.x();
        }
        if (particle.y() < min.y) {
            min.y = particle.y();
        }
        if (particle.z() < min.z) {
            min.z = particle.z();
        }
        // Max
        if (particle.x() > max.x) {
            max.x = particle.x();
        }
        if (particle.y() > max.y) {
            max.y = particle.y();
        }
        if (particle.z() > max.z) {
            max.z = particle.z();
        }
    }
    BoundingBoxd box = new BoundingBoxd(min, max);
    double halfSize = Math.max(Math.max(box.getDepth(), box.getHeight()), box.getWidth()) / 2d;
    OctreeNode root = new OctreeNode(0, box.getCenterX(), box.getCenterY(), box.getCenterZ(), halfSize, halfSize, halfSize, 0);
    return root;
}
Also used : Vector3d(gaiasky.util.math.Vector3d) IParticleRecord(gaiasky.scenegraph.particle.IParticleRecord) OctreeNode(gaiasky.util.tree.OctreeNode) BoundingBoxd(gaiasky.util.math.BoundingBoxd)

Aggregations

IParticleRecord (gaiasky.scenegraph.particle.IParticleRecord)48 Vector3d (gaiasky.util.math.Vector3d)10 StarGroup (gaiasky.scenegraph.StarGroup)8 ArrayList (java.util.ArrayList)6 Array (com.badlogic.gdx.utils.Array)5 Vector3 (com.badlogic.gdx.math.Vector3)4 ParticleGroup (gaiasky.scenegraph.ParticleGroup)4 OctreeNode (gaiasky.util.tree.OctreeNode)4 FileHandle (com.badlogic.gdx.files.FileHandle)3 ParticleRecord (gaiasky.scenegraph.particle.ParticleRecord)3 Coordinates (gaiasky.util.coord.Coordinates)3 Matrix4 (com.badlogic.gdx.math.Matrix4)2 LongMap (com.badlogic.gdx.utils.LongMap)2 Method (com.badlogic.gdx.utils.reflect.Method)2 ReflectionException (com.badlogic.gdx.utils.reflect.ReflectionException)2 IStarGroupDataProvider (gaiasky.data.group.IStarGroupDataProvider)2 SceneGraphNode (gaiasky.scenegraph.SceneGraphNode)2 ICamera (gaiasky.scenegraph.camera.ICamera)2 AbstractOctreeWrapper (gaiasky.scenegraph.octreewrapper.AbstractOctreeWrapper)2 BillboardDataset (gaiasky.scenegraph.particle.BillboardDataset)2