Search in sources :

Example 31 with TIntList

use of gnu.trove.list.TIntList in project OpenTripPlanner by opentripplanner.

the class GTFSPatternHopFactory method run.

/**
 * Generate the edges. Assumes that there are already vertices in the graph for the stops.
 */
public void run(Graph graph) {
    if (fareServiceFactory == null) {
        fareServiceFactory = new DefaultFareServiceFactory();
    }
    fareServiceFactory.processGtfs(_dao);
    // TODO: Why are we loading stops? The Javadoc above says this method assumes stops are aleady loaded.
    loadStops(graph);
    loadPathways(graph);
    loadFeedInfo(graph);
    loadAgencies(graph);
    // TODO: Why is there cached "data", and why are we clearing it? Due to a general lack of comments, I have no idea.
    // Perhaps it is to allow name collisions with previously loaded feeds.
    clearCachedData();
    /* Assign 0-based numeric codes to all GTFS service IDs. */
    for (AgencyAndId serviceId : _dao.getAllServiceIds()) {
        // TODO: FIX Service code collision for multiple feeds.
        graph.serviceCodes.put(serviceId, graph.serviceCodes.size());
    }
    LOG.debug("building hops from trips");
    Collection<Trip> trips = _dao.getAllTrips();
    int tripCount = 0;
    /* First, record which trips are used by one or more frequency entries.
         * These trips will be ignored for the purposes of non-frequency routing, and
         * all the frequency entries referencing the same trip can be added at once to the same
         * Timetable/TripPattern.
         */
    ListMultimap<Trip, Frequency> frequenciesForTrip = ArrayListMultimap.create();
    for (Frequency freq : _dao.getAllFrequencies()) {
        frequenciesForTrip.put(freq.getTrip(), freq);
    }
    /* Then loop over all trips, handling each one as a frequency-based or scheduled trip. */
    int freqCount = 0;
    int nonFreqCount = 0;
    /* The hops don't actually exist when we build their geometries, but we have to build their geometries
         * below, before we throw away the modified stopTimes, saving only the tripTimes (which don't have enough
         * information to build a geometry). So we keep them here.
         *
         *  A trip pattern actually does not have a single geometry, but one per hop, so we store an array.
         *  FIXME _why_ doesn't it have a single geometry?
         */
    Map<TripPattern, LineString[]> geometriesByTripPattern = Maps.newHashMap();
    TRIP: for (Trip trip : trips) {
        if (++tripCount % 100000 == 0) {
            LOG.debug("loading trips {}/{}", tripCount, trips.size());
        }
        // TODO: move to a validator module
        if (!_calendarService.getServiceIds().contains(trip.getServiceId())) {
            LOG.warn(graph.addBuilderAnnotation(new TripUndefinedService(trip)));
            // Invalid trip, skip it, it will break later
            continue TRIP;
        }
        /* Fetch the stop times for this trip. Copy the list since it's immutable. */
        List<StopTime> stopTimes = new ArrayList<StopTime>(_dao.getStopTimesForTrip(trip));
        /* GTFS stop times frequently contain duplicate, missing, or incorrect entries. Repair them. */
        TIntList removedStopSequences = removeRepeatedStops(stopTimes);
        if (!removedStopSequences.isEmpty()) {
            LOG.warn(graph.addBuilderAnnotation(new RepeatedStops(trip, removedStopSequences)));
        }
        filterStopTimes(stopTimes, graph);
        interpolateStopTimes(stopTimes);
        /* If after filtering this trip does not contain at least 2 stoptimes, it does not serve any purpose. */
        if (stopTimes.size() < 2) {
            LOG.warn(graph.addBuilderAnnotation(new TripDegenerate(trip)));
            continue TRIP;
        }
        /* Try to get the direction id for the trip, set to -1 if not found */
        int directionId;
        try {
            directionId = Integer.parseInt(trip.getDirectionId());
        } catch (NumberFormatException e) {
            LOG.debug("Trip {} does not have direction id, defaults to -1");
            directionId = -1;
        }
        /* Get the existing TripPattern for this filtered StopPattern, or create one. */
        StopPattern stopPattern = new StopPattern(stopTimes);
        TripPattern tripPattern = findOrCreateTripPattern(stopPattern, trip.getRoute(), directionId);
        /* Create a TripTimes object for this list of stoptimes, which form one trip. */
        TripTimes tripTimes = new TripTimes(trip, stopTimes, graph.deduplicator);
        /* If this trip is referenced by one or more lines in frequencies.txt, wrap it in a FrequencyEntry. */
        List<Frequency> frequencies = frequenciesForTrip.get(trip);
        if (frequencies != null && !(frequencies.isEmpty())) {
            for (Frequency freq : frequencies) {
                tripPattern.add(new FrequencyEntry(freq, tripTimes));
                freqCount++;
            }
        // TODO replace: createGeometry(graph, trip, stopTimes, hops);
        } else /* This trip was not frequency-based. Add the TripTimes directly to the TripPattern's scheduled timetable. */
        {
            tripPattern.add(tripTimes);
            nonFreqCount++;
        }
        // there would be a trip pattern with no geometry yet because it failed some of these tests
        if (!geometriesByTripPattern.containsKey(tripPattern) && trip.getShapeId() != null && trip.getShapeId().getId() != null && !trip.getShapeId().getId().equals("")) {
            // save the geometry to later be applied to the hops
            geometriesByTripPattern.put(tripPattern, createGeometry(graph, trip, stopTimes));
        }
    }
    // end foreach TRIP
    LOG.info("Added {} frequency-based and {} single-trip timetable entries.", freqCount, nonFreqCount);
    graph.hasFrequencyService = graph.hasFrequencyService || freqCount > 0;
    graph.hasScheduledService = graph.hasScheduledService || nonFreqCount > 0;
    /* Generate unique human-readable names for all the TableTripPatterns. */
    TripPattern.generateUniqueNames(tripPatterns.values());
    /* Generate unique short IDs for all the TableTripPatterns. */
    TripPattern.generateUniqueIds(tripPatterns.values());
    /* Loop over all new TripPatterns, creating edges, setting the service codes and geometries, etc. */
    for (TripPattern tripPattern : tripPatterns.values()) {
        tripPattern.makePatternVerticesAndEdges(graph, context.stationStopNodes);
        // Add the geometries to the hop edges.
        LineString[] geom = geometriesByTripPattern.get(tripPattern);
        if (geom != null) {
            for (int i = 0; i < tripPattern.hopEdges.length; i++) {
                tripPattern.hopEdges[i].setGeometry(geom[i]);
            }
            // Make a geometry for the whole TripPattern from all its constituent hops.
            // This happens only if geometry is found in geometriesByTripPattern,
            // because that means that geometry was created from shapes instead "as crow flies"
            tripPattern.makeGeometry();
        }
        // TODO this could be more elegant
        tripPattern.setServiceCodes(graph.serviceCodes);
        /* Iterate over all stops in this pattern recording mode information. */
        TraverseMode mode = GtfsLibrary.getTraverseMode(tripPattern.route);
        for (TransitStop tstop : tripPattern.stopVertices) {
            tstop.addMode(mode);
            if (mode == TraverseMode.SUBWAY) {
                tstop.setStreetToStopTime(subwayAccessTime);
            }
            graph.addTransitMode(mode);
        }
    }
    /* Identify interlined trips and create the necessary edges. */
    interline(tripPatterns.values(), graph);
    /* Interpret the transfers explicitly defined in transfers.txt. */
    loadTransfers(graph);
    /* Store parent stops in graph, even if not linked. These are needed for clustering*/
    for (TransitStationStop stop : context.stationStopNodes.values()) {
        if (stop instanceof TransitStation) {
            TransitStation parentStopVertex = (TransitStation) stop;
            graph.parentStopById.put(parentStopVertex.getStopId(), parentStopVertex.getStop());
        }
    }
    // it is already done at deserialization, but standalone mode allows using graphs without serializing them.
    for (TripPattern tableTripPattern : tripPatterns.values()) {
        tableTripPattern.scheduledTimetable.finish();
    }
    // eh?
    clearCachedData();
    graph.putService(FareService.class, fareServiceFactory.makeFareService());
    graph.putService(OnBoardDepartService.class, new OnBoardDepartServiceImpl());
}
Also used : AgencyAndId(org.onebusaway.gtfs.model.AgencyAndId) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) FrequencyEntry(org.opentripplanner.routing.trippattern.FrequencyEntry) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) TIntArrayList(gnu.trove.list.array.TIntArrayList) TIntList(gnu.trove.list.TIntList) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) TraverseMode(org.opentripplanner.routing.core.TraverseMode) DefaultFareServiceFactory(org.opentripplanner.routing.impl.DefaultFareServiceFactory) StopTime(org.onebusaway.gtfs.model.StopTime) StopPattern(org.opentripplanner.model.StopPattern) Trip(org.onebusaway.gtfs.model.Trip) TripUndefinedService(org.opentripplanner.graph_builder.annotation.TripUndefinedService) ShapePoint(org.onebusaway.gtfs.model.ShapePoint) TripPattern(org.opentripplanner.routing.edgetype.TripPattern) TransitStation(org.opentripplanner.routing.vertextype.TransitStation) TripDegenerate(org.opentripplanner.graph_builder.annotation.TripDegenerate) LineString(com.vividsolutions.jts.geom.LineString) Frequency(org.onebusaway.gtfs.model.Frequency) RepeatedStops(org.opentripplanner.graph_builder.annotation.RepeatedStops) TIntList(gnu.trove.list.TIntList) TransitStationStop(org.opentripplanner.routing.vertextype.TransitStationStop) OnBoardDepartServiceImpl(org.opentripplanner.routing.impl.OnBoardDepartServiceImpl)

Example 32 with TIntList

use of gnu.trove.list.TIntList in project OpenTripPlanner by opentripplanner.

the class PropagatedTimesStore method setFromArray.

/**
 * @param times for search (varying departure time), an array of travel times to each destination.
 * @param includeInAverages for each iteration, whether that iteration should be included in average calculations.
 *                          In RaptorWorker's Monte Carlo code we also include minima and maxima, which should
 *                          not be included in averages.
 *                          Iterations that are not included in averages are still used to determine extrema.
 */
public void setFromArray(int[][] times, boolean[] includeInAverages, ConfidenceCalculationMethod confidenceCalculationMethod) {
    if (times.length == 0)
        // nothing to do
        return;
    // assume array is rectangular
    int nTargets = times[0].length;
    // cache random numbers. This should be fine as we're mixing it with the number of minutes
    // at which each destination is accessible, which is sometimes not 120, as well as the stop
    // position in the list (note that we have cleverly chosen a number which is a prime
    // so is not divisible by the number of iterations on the bootstrap). Finally recall that
    // the maximum number of times we're sampling from is generally 120 and we modulo this,
    // so the pigeonhole principle applies.
    // this is effectively a "random number generator" with phase 10007
    int[] randomNumbers = random.ints().limit(10007).map(Math::abs).toArray();
    int nextRandom = 0;
    int effectiveIterations = 0;
    for (int i = 0; i < includeInAverages.length; i++) {
        if (includeInAverages[i])
            effectiveIterations++;
    }
    // loop over targets on the outside so we can bootstrap
    TARGETS: for (int target = 0; target < nTargets; target++) {
        // compute the average
        int sum = 0;
        int count = 0;
        TIntList timeList = new TIntArrayList();
        TIntList avgList = new TIntArrayList();
        ITERATIONS: for (int i = 0; i < times.length; i++) {
            if (times[i][target] == RaptorWorker.UNREACHED)
                continue ITERATIONS;
            if (includeInAverages[i]) {
                avgList.add(times[i][target]);
                sum += times[i][target];
                count++;
            }
            timeList.add(times[i][target]);
        }
        // never reachable
        if (count == 0)
            continue TARGETS;
        // wait times as well.
        if (count >= effectiveIterations * req.reachabilityThreshold)
            avgs[target] = sum / count;
        // TODO: correctly handle partial accessibility for bootstrap and percentile options.
        switch(confidenceCalculationMethod) {
            case BOOTSTRAP:
                // now bootstrap out a 95% confidence interval on the time
                int[] bootMeans = new int[N_BOOTSTRAPS];
                // prevent overflow
                nextRandom += N_BOOTSTRAPS * count % randomNumbers.length;
                final int randOff = nextRandom;
                final int finalCount = count;
                IntStream.range(0, N_BOOTSTRAPS).parallel().forEach(boot -> {
                    int bsum = 0;
                    // sample from the Monte Carlo distribution with replacement
                    for (int iter = 0; iter < finalCount; iter++) {
                        bsum += avgList.get(randomNumbers[(randOff + boot * iter) % randomNumbers.length] % avgList.size());
                    // bsum += timeList.get(random.nextInt(count));
                    }
                    bootMeans[boot] = bsum / finalCount;
                });
                Arrays.sort(bootMeans);
                // 2.5 percentile of distribution of means
                mins[target] = bootMeans[N_BOOTSTRAPS / 40];
                // 97.5 percentile of distribution of means
                maxs[target] = bootMeans[N_BOOTSTRAPS - N_BOOTSTRAPS / 40];
                break;
            case PERCENTILE:
                timeList.sort();
                mins[target] = timeList.get(timeList.size() / 40);
                maxs[target] = timeList.get(39 * timeList.size() / 40);
                break;
            case NONE:
                mins[target] = maxs[target] = avgs[target];
                break;
            case MIN_MAX:
            default:
                mins[target] = timeList.min();
                // NB not using count here as it doesn't count iterations that are not included in averages
                if (timeList.size() == times.length)
                    maxs[target] = timeList.max();
                break;
        }
    }
}
Also used : IntStream(java.util.stream.IntStream) Arrays(java.util.Arrays) TIntArrayList(gnu.trove.list.array.TIntArrayList) WTWD(org.opentripplanner.analyst.request.SampleGridRenderer.WTWD) LoggerFactory(org.slf4j.LoggerFactory) Random(java.util.Random) IsochroneData(org.opentripplanner.analyst.core.IsochroneData) SphericalDistanceLibrary(org.opentripplanner.common.geometry.SphericalDistanceLibrary) ArrayList(java.util.ArrayList) WTWDAccumulativeMetric(org.opentripplanner.analyst.request.SampleGridRenderer.WTWDAccumulativeMetric) Graph(org.opentripplanner.routing.graph.Graph) FastMath.toRadians(org.apache.commons.math3.util.FastMath.toRadians) DelaunayIsolineBuilder(org.opentripplanner.common.geometry.DelaunayIsolineBuilder) AccumulativeGridSampler(org.opentripplanner.common.geometry.AccumulativeGridSampler) Coordinate(com.vividsolutions.jts.geom.Coordinate) TIntList(gnu.trove.list.TIntList) Logger(org.slf4j.Logger) ResultSet(org.opentripplanner.analyst.ResultSet) Vertex(org.opentripplanner.routing.graph.Vertex) TimeSurface(org.opentripplanner.analyst.TimeSurface) FastMath(org.apache.commons.math3.util.FastMath) SparseMatrixZSampleGrid(org.opentripplanner.common.geometry.SparseMatrixZSampleGrid) SampleGridRenderer(org.opentripplanner.analyst.request.SampleGridRenderer) List(java.util.List) Stream(java.util.stream.Stream) SampleSet(org.opentripplanner.analyst.SampleSet) ResultEnvelope(org.opentripplanner.analyst.cluster.ResultEnvelope) TIntList(gnu.trove.list.TIntList) TIntArrayList(gnu.trove.list.array.TIntArrayList)

Example 33 with TIntList

use of gnu.trove.list.TIntList in project RecurrentComplex by Ivorforce.

the class IntAreas method visitCoordsExcept.

public static boolean visitCoordsExcept(int[] lower, int[] higher, TIntList except, Visitor<int[]> visitor) {
    TIntList dimensions = new TIntArrayList(Ranges.to(lower.length));
    dimensions.removeAll(except);
    return visitCoords(lower, higher, lower.clone(), dimensions, visitor);
}
Also used : TIntList(gnu.trove.list.TIntList) TIntArrayList(gnu.trove.list.array.TIntArrayList)

Example 34 with TIntList

use of gnu.trove.list.TIntList in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.

the class WorldPhysicsCollider method updatePotentialCollisionCache.

// TODO: The greatest physics lag starts here.
private void updatePotentialCollisionCache() {
    ticksSinceCacheUpdate = 0D;
    // in the same tick
    if (Math.random() > .5) {
        ticksSinceCacheUpdate -= .05D;
    }
    int oldSize = cachedPotentialHits.size();
    // Resets the potential hits array in O(1) time! Isn't that something.
    // cachedPotentialHits.resetQuick();
    cachedPotentialHits.clear();
    AxisAlignedBB shipBBOriginal = parent.getPhysicsTransformAABB();
    if (shipBBOriginal == null) {
        return;
    }
    final AxisAlignedBB shipBB = shipBBOriginal.grow(3);
    // Use the physics tick collision box instead of the game tick collision box.
    // We are using grow(3) on both because for some reason if we don't then ships start
    // jiggling through the ground. God I can't wait for a new physics engine.
    final AxisAlignedBB collisionBB = shipBB.grow(AABB_EXPANSION).expand(calculator.getLinearVelocity().x * .2, calculator.getLinearVelocity().y * .2, calculator.getLinearVelocity().z * .2);
    // Ship is outside of world blockSpace, just skip this all togvalkyrium
    if (collisionBB.maxY < 0 || collisionBB.minY > 255) {
        return;
    }
    // Has a -1 on the minY value, I hope this helps with preventing things from
    // falling through the floor
    BlockPos min = new BlockPos(collisionBB.minX, Math.max(collisionBB.minY - 1, 0), collisionBB.minZ);
    BlockPos max = new BlockPos(collisionBB.maxX, Math.min(collisionBB.maxY, 255), collisionBB.maxZ);
    centerPotentialHit = new BlockPos((min.getX() + max.getX()) / 2D, (min.getY() + max.getY()) / 2D, (min.getZ() + max.getZ()) / 2D);
    ChunkCache cache = parent.getCachedSurroundingChunks();
    if (cache == null) {
        System.err.println("VS Cached Surrounding Chunks was null! This is going to cause catastophric terrible events!!");
        return;
    }
    int chunkMinX = min.getX() >> 4;
    int chunkMaxX = (max.getX() >> 4) + 1;
    int chunkMinZ = min.getZ() >> 4;
    int chunkMaxZ = (max.getZ() >> 4) + 1;
    // long startTime = System.nanoTime();
    int minX = min.getX();
    int minY = min.getY();
    int minZ = min.getZ();
    int maxX = max.getX();
    int maxY = max.getY();
    int maxZ = max.getZ();
    // More multithreading!
    if (VSConfig.MULTITHREADING_SETTINGS.multithreadCollisionCacheUpdate && parent.getBlockPositions().size() > 100) {
        List<Triple<Integer, Integer, TIntList>> tasks = new ArrayList<>();
        for (int chunkX = chunkMinX; chunkX < chunkMaxX; chunkX++) {
            for (int chunkZ = chunkMinZ; chunkZ < chunkMaxZ; chunkZ++) {
                tasks.add(new ImmutableTriple<>(chunkX, chunkZ, new TIntArrayList()));
            }
        }
        Consumer<Triple<Integer, Integer, TIntList>> consumer = i -> {
            // i is a Tuple<Integer, Integer>
            // updateCollisionCacheParrallel(cache, cachedPotentialHits, i.getFirst(),
            // i.getSecond(), minX, minY, minZ, maxX, maxY, maxZ);
            updateCollisionCacheSequential(cache, i.getLeft(), i.getMiddle(), minX, minY, minZ, maxX, maxY, maxZ, shipBB, i.getRight());
        };
        ValkyrienSkiesMod.getPhysicsThreadPool().submit(() -> tasks.parallelStream().forEach(consumer)).join();
        tasks.forEach(task -> cachedPotentialHits.addAll(task.getRight()));
    } else {
        // Cast to double to avoid overflow errors
        double size = ((double) (chunkMaxX - chunkMinX)) * ((double) (chunkMaxZ - chunkMinZ));
        if (size > 300000) {
            // Sanity check; don't execute the rest of the code because we'll just freeze the physics thread.
            return;
        }
        // TODO: VS thread freezes here.
        for (int chunkX = chunkMinX; chunkX < chunkMaxX; chunkX++) {
            for (int chunkZ = chunkMinZ; chunkZ < chunkMaxZ; chunkZ++) {
                updateCollisionCacheSequential(cache, chunkX, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, shipBB, cachedPotentialHits);
            }
        }
    }
}
Also used : AxisAlignedBB(net.minecraft.util.math.AxisAlignedBB) Triple(org.apache.commons.lang3.tuple.Triple) ImmutableTriple(org.apache.commons.lang3.tuple.ImmutableTriple) SpatialDetector(org.valkyrienskies.mod.common.ships.block_relocation.SpatialDetector) TIntArrayList(gnu.trove.list.array.TIntArrayList) AxisAlignedBB(net.minecraft.util.math.AxisAlignedBB) ITerrainOctreeProvider(org.valkyrienskies.mod.common.util.datastructures.ITerrainOctreeProvider) ArrayList(java.util.ArrayList) PhysicsObject(org.valkyrienskies.mod.common.ships.ship_world.PhysicsObject) ValkyrienSkiesMod(org.valkyrienskies.mod.common.ValkyrienSkiesMod) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) MutableBlockPos(net.minecraft.util.math.BlockPos.MutableBlockPos) Vector3d(org.joml.Vector3d) PhysicsCalculations(org.valkyrienskies.mod.common.physics.PhysicsCalculations) Chunk(net.minecraft.world.chunk.Chunk) Triple(org.apache.commons.lang3.tuple.Triple) TIntList(gnu.trove.list.TIntList) ImmutableTriple(org.apache.commons.lang3.tuple.ImmutableTriple) IBitOctree(org.valkyrienskies.mod.common.util.datastructures.IBitOctree) ChunkCache(net.minecraft.world.ChunkCache) Iterator(java.util.Iterator) Collection(java.util.Collection) TransformType(valkyrienwarfare.api.TransformType) BlockPos(net.minecraft.util.math.BlockPos) Consumer(java.util.function.Consumer) IBlockState(net.minecraft.block.state.IBlockState) ShipTransform(org.valkyrienskies.mod.common.ships.ship_transform.ShipTransform) List(java.util.List) VSConfig(org.valkyrienskies.mod.common.config.VSConfig) MathHelper(net.minecraft.util.math.MathHelper) Vector3dc(org.joml.Vector3dc) ExtendedBlockStorage(net.minecraft.world.chunk.storage.ExtendedBlockStorage) ChunkCache(net.minecraft.world.ChunkCache) TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) MutableBlockPos(net.minecraft.util.math.BlockPos.MutableBlockPos) BlockPos(net.minecraft.util.math.BlockPos) TIntArrayList(gnu.trove.list.array.TIntArrayList)

Example 35 with TIntList

use of gnu.trove.list.TIntList in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.

the class WorldWaterCollider method updatePotentialCollisionCache.

private void updatePotentialCollisionCache() {
    secondsSinceCollisionCacheUpdate = 0;
    // ships from all updating in the same tick
    if (Math.random() > .5) {
        secondsSinceCollisionCacheUpdate -= .01;
    }
    cachedPotentialHits.clear();
    AxisAlignedBB shipBBOriginal = parent.getPhysicsTransformAABB();
    if (shipBBOriginal == null) {
        return;
    }
    // We are using grow(3) because its good.
    final AxisAlignedBB shipBB = shipBBOriginal.grow(3);
    final AxisAlignedBB collisionBB = shipBB.grow(AABB_EXPANSION).grow(2 * Math.ceil(RANGE_CHECK));
    // Ship is outside of world blockSpace, just skip this
    if (collisionBB.maxY < 0 || collisionBB.minY > 255) {
        return;
    }
    // Has a -1 on the minY value, I hope this helps with preventing things from
    // falling through the floor
    final BlockPos min = new BlockPos(collisionBB.minX, Math.max(collisionBB.minY - 1, 0), collisionBB.minZ);
    final BlockPos max = new BlockPos(collisionBB.maxX, Math.min(collisionBB.maxY, 255), collisionBB.maxZ);
    centerPotentialHit = new BlockPos((min.getX() + max.getX()) / 2.0, (min.getY() + max.getY()) / 2.0, (min.getZ() + max.getZ()) / 2.0);
    final ChunkCache cache = parent.getCachedSurroundingChunks();
    if (cache == null) {
        System.err.println("VS Cached Surrounding Chunks was null! This is going to cause catastophric terrible events!!");
        return;
    }
    final int chunkMinX = min.getX() >> 4;
    final int chunkMaxX = (max.getX() >> 4) + 1;
    final int chunkMinZ = min.getZ() >> 4;
    final int chunkMaxZ = (max.getZ() >> 4) + 1;
    final int minX = min.getX();
    final int minY = min.getY();
    final int minZ = min.getZ();
    final int maxX = max.getX();
    final int maxY = max.getY();
    final int maxZ = max.getZ();
    // More multithreading!
    if (VSConfig.MULTITHREADING_SETTINGS.multithreadCollisionCacheUpdate && parent.getBlockPositions().size() > 100) {
        final List<Triple<Integer, Integer, TIntList>> tasks = new ArrayList<>();
        for (int chunkX = chunkMinX; chunkX < chunkMaxX; chunkX++) {
            for (int chunkZ = chunkMinZ; chunkZ < chunkMaxZ; chunkZ++) {
                tasks.add(new ImmutableTriple<>(chunkX, chunkZ, new TIntArrayList()));
            }
        }
        Consumer<Triple<Integer, Integer, TIntList>> consumer = i -> updateCollisionCacheSequential(cache, i.getLeft(), i.getMiddle(), minX, minY, minZ, maxX, maxY, maxZ, shipBB, i.getRight());
        ValkyrienSkiesMod.getPhysicsThreadPool().submit(() -> tasks.parallelStream().forEach(consumer)).join();
        tasks.forEach(task -> cachedPotentialHits.addAll(task.getRight()));
    } else {
        // Cast to double to avoid overflow errors
        final double size = ((double) (chunkMaxX - chunkMinX)) * ((double) (chunkMaxZ - chunkMinZ));
        if (size > 300000) {
            // Sanity check; don't execute the rest of the code because we'll just freeze the physics thread.
            return;
        }
        for (int chunkX = chunkMinX; chunkX < chunkMaxX; chunkX++) {
            for (int chunkZ = chunkMinZ; chunkZ < chunkMaxZ; chunkZ++) {
                updateCollisionCacheSequential(cache, chunkX, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, shipBB, cachedPotentialHits);
            }
        }
    }
}
Also used : AxisAlignedBB(net.minecraft.util.math.AxisAlignedBB) ImmutableTriple(org.apache.commons.lang3.tuple.ImmutableTriple) Triple(org.apache.commons.lang3.tuple.Triple) TIntList(gnu.trove.list.TIntList) ImmutableTriple(org.apache.commons.lang3.tuple.ImmutableTriple) SpatialDetector(org.valkyrienskies.mod.common.ships.block_relocation.SpatialDetector) IBitOctree(org.valkyrienskies.mod.common.util.datastructures.IBitOctree) TIntArrayList(gnu.trove.list.array.TIntArrayList) ChunkCache(net.minecraft.world.ChunkCache) AxisAlignedBB(net.minecraft.util.math.AxisAlignedBB) TransformType(valkyrienwarfare.api.TransformType) BlockPos(net.minecraft.util.math.BlockPos) ITerrainOctreeProvider(org.valkyrienskies.mod.common.util.datastructures.ITerrainOctreeProvider) ArrayList(java.util.ArrayList) PhysicsObject(org.valkyrienskies.mod.common.ships.ship_world.PhysicsObject) Consumer(java.util.function.Consumer) List(java.util.List) VSConfig(org.valkyrienskies.mod.common.config.VSConfig) MathHelper(net.minecraft.util.math.MathHelper) ValkyrienSkiesMod(org.valkyrienskies.mod.common.ValkyrienSkiesMod) Vector3d(org.joml.Vector3d) PhysicsCalculations(org.valkyrienskies.mod.common.physics.PhysicsCalculations) Chunk(net.minecraft.world.chunk.Chunk) Triple(org.apache.commons.lang3.tuple.Triple) ExtendedBlockStorage(net.minecraft.world.chunk.storage.ExtendedBlockStorage) ChunkCache(net.minecraft.world.ChunkCache) TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) BlockPos(net.minecraft.util.math.BlockPos) TIntArrayList(gnu.trove.list.array.TIntArrayList)

Aggregations

TIntList (gnu.trove.list.TIntList)35 TIntArrayList (gnu.trove.list.array.TIntArrayList)21 ArrayList (java.util.ArrayList)6 IOException (java.io.IOException)5 List (java.util.List)5 TFloatList (gnu.trove.list.TFloatList)4 ItemStack (net.minecraft.item.ItemStack)4 BlockPos (net.minecraft.util.math.BlockPos)4 Vector2f (org.terasology.math.geom.Vector2f)4 Vector3i (org.terasology.math.geom.Vector3i)4 TIntIterator (gnu.trove.iterator.TIntIterator)3 TShortObjectHashMap (gnu.trove.map.hash.TShortObjectHashMap)3 InputStream (java.io.InputStream)3 Arrays (java.util.Arrays)3 Vector3f (org.terasology.math.geom.Vector3f)3 Lists (com.google.common.collect.Lists)2 TFloatArrayList (gnu.trove.list.array.TFloatArrayList)2 IvMutableBlockPos (ivorius.ivtoolkit.blocks.IvMutableBlockPos)2 IntegerRange (ivorius.ivtoolkit.gui.IntegerRange)2 Consumer (java.util.function.Consumer)2