private void addConduitCores(List<CollidableComponent> result, IConduit con) { CollidableCache cc = CollidableCache.instance; Class<? extends IConduit> type = con.getCollidableType(); if (con.hasConnections()) { for (ForgeDirection dir : con.getExternalConnections()) { result.addAll( cc.getCollidables( cc.createKey( type, getOffset(con.getBaseConduitType(), dir), ForgeDirection.UNKNOWN, false), con)); } for (ForgeDirection dir : con.getConduitConnections()) { result.addAll( cc.getCollidables( cc.createKey( type, getOffset(con.getBaseConduitType(), dir), ForgeDirection.UNKNOWN, false), con)); } } else { result.addAll( cc.getCollidables( cc.createKey( type, getOffset(con.getBaseConduitType(), ForgeDirection.UNKNOWN), ForgeDirection.UNKNOWN, false), con)); } }
private void addConnectors(List<CollidableComponent> result) { if (conduits.isEmpty()) { return; } for (IConduit con : conduits) { boolean b = con.haveCollidablesChangedSinceLastCall(); collidablesDirty = collidablesDirty || b; connectorsDirty = connectorsDirty || b; } if (!connectorsDirty && !cachedConnectors.isEmpty()) { result.addAll(cachedConnectors); return; } cachedConnectors.clear(); // TODO: What an unholly mess! List<CollidableComponent> coreBounds = new ArrayList<CollidableComponent>(); for (IConduit con : conduits) { addConduitCores(coreBounds, con); } cachedConnectors.addAll(coreBounds); result.addAll(coreBounds); // 1st algorithm List<CollidableComponent> conduitsBounds = new ArrayList<CollidableComponent>(); for (IConduit con : conduits) { conduitsBounds.addAll(con.getCollidableComponents()); addConduitCores(conduitsBounds, con); } Set<Class<IConduit>> collidingTypes = new HashSet<Class<IConduit>>(); for (CollidableComponent conCC : conduitsBounds) { for (CollidableComponent innerCC : conduitsBounds) { if (!InsulatedRedstoneConduit.COLOR_CONTROLLER_ID.equals(innerCC.data) && !InsulatedRedstoneConduit.COLOR_CONTROLLER_ID.equals(conCC.data) && conCC != innerCC && conCC.bound.intersects(innerCC.bound)) { collidingTypes.add((Class<IConduit>) conCC.conduitType); } } } // TODO: Remove the core geometries covered up by this as no point in rendering these if (!collidingTypes.isEmpty()) { List<CollidableComponent> colCores = new ArrayList<CollidableComponent>(); for (Class<IConduit> c : collidingTypes) { IConduit con = getConduit(c); if (con != null) { addConduitCores(colCores, con); } } BoundingBox bb = null; for (CollidableComponent cBB : colCores) { if (bb == null) { bb = cBB.bound; } else { bb = bb.expandBy(cBB.bound); } } if (bb != null) { bb = bb.scale(1.05, 1.05, 1.05); CollidableComponent cc = new CollidableComponent( null, bb, ForgeDirection.UNKNOWN, ConduitConnectorType.INTERNAL); result.add(cc); cachedConnectors.add(cc); } } // 2nd algorithm for (IConduit con : conduits) { if (con.hasConnections()) { List<CollidableComponent> cores = new ArrayList<CollidableComponent>(); addConduitCores(cores, con); if (cores.size() > 1) { BoundingBox bb = cores.get(0).bound; float area = bb.getArea(); for (CollidableComponent cc : cores) { bb = bb.expandBy(cc.bound); } if (bb.getArea() > area * 1.5f) { bb = bb.scale(1.05, 1.05, 1.05); CollidableComponent cc = new CollidableComponent( null, bb, ForgeDirection.UNKNOWN, ConduitConnectorType.INTERNAL); result.add(cc); cachedConnectors.add(cc); } } } } // Merge all internal conduit connectors into one box BoundingBox conBB = null; for (int i = 0; i < result.size(); i++) { CollidableComponent cc = result.get(i); if (cc.conduitType == null && cc.data == ConduitConnectorType.INTERNAL) { conBB = conBB == null ? cc.bound : conBB.expandBy(cc.bound); result.remove(i); i--; cachedConnectors.remove(cc); } } if (conBB != null) { CollidableComponent cc = new CollidableComponent( null, conBB, ForgeDirection.UNKNOWN, ConduitConnectorType.INTERNAL); result.add(cc); cachedConnectors.add(cc); } // External Connectors EnumSet<ForgeDirection> externalDirs = EnumSet.noneOf(ForgeDirection.class); for (IConduit con : conduits) { Set<ForgeDirection> extCons = con.getExternalConnections(); if (extCons != null) { for (ForgeDirection dir : extCons) { if (con.getConnectionMode(dir) != ConnectionMode.DISABLED) { externalDirs.add(dir); } } } } for (ForgeDirection dir : externalDirs) { BoundingBox bb = ConduitGeometryUtil.instance.getExternalConnectorBoundingBox(dir); CollidableComponent cc = new CollidableComponent(null, bb, dir, ConduitConnectorType.EXTERNAL); result.add(cc); cachedConnectors.add(cc); } connectorsDirty = false; }