diff --git a/.gitmodules b/.gitmodules
index 07c7c7370..ecb55ae45 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -31,3 +31,6 @@
[submodule "infinigen/datagen/customgt/dependencies/glfw"]
path = infinigen/datagen/customgt/dependencies/glfw
url = https://github.com/glfw/glfw.git
+[submodule "infinigen/OcMesher"]
+ path = infinigen/OcMesher
+ url = git@github.com:princeton-vl/OcMesher.git
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 4ff957e77..c398593fc 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -20,3 +20,6 @@ v1.1.0
- Update to blender 3.6, install blender either via pip or standalone
- Restructure project into an `infinigen` python package and `infinigen_examples` directory
- Add unit tests
+
+v1.2.0
+- Integrate OcMesher terrain option - see https://github.com/princeton-vl/OcMesher
\ No newline at end of file
diff --git a/docs/ConfiguringInfinigen.md b/docs/ConfiguringInfinigen.md
index e232d4b3b..e739b1f58 100644
--- a/docs/ConfiguringInfinigen.md
+++ b/docs/ConfiguringInfinigen.md
@@ -103,7 +103,6 @@ If you have more than one GPU and are using a `local_*.gin` compute config, each
Generating a video, stereo or other dataset typically requires more render jobs, so we must instruct `manage_jobs.py` to run those jobs. `datagen/configs/data_schema/` provides many options for you to use in your `--pipeline_configs`, including `monocular_video.gin` and `stereo.gin`.
These configs are typically mutually exclusive, and you must include at least one
-:exclamation: Our terrain system resolves its signed distance function (SDF) to view-specific meshes, which must be updated as the camera moves. For video rendering, we strongly recommend using the `high_quality_terrain` config to avoid perceptible flickering and temporal aliasing. This config meshes the SDF at very high detail, to create seamless video. However, it has high compute costs, so we recommend also using `--pipeline_config cuda_terrain` on a machine with an NVIDIA GPU. For applications with fast moving cameras, you may need to update the terrain mesh more frequently by decreasing `iterate_scene_tasks.view_block_size = 16`.
To create longer videos, modify `iterate_scene_tasks.frame_range` in `monocular_video.gin` (note: we use 24fps video by default). `iterate_scene_tasks.view_block_size` controls how many frames will be grouped into each `fine_terrain` and render / ground-truth task.
@@ -166,14 +165,14 @@ If you have any issues with these commands, or wish to customize them to your ne
All commands below are shown with using `local_256GB` config, but you can attempt to swap this for any compute config as discussed in [Configuring available computing resources](#configuring-available-computing-resources).
-#### Creating videos similar to the intro video
+#### Creating high quality videos
-Most videos in the "Introducing Infinigen" launch video were made using commands similar to the following:
+We recommend this command as a starting point for generating high quality videos. Generating multi-view consistent terrain is not computationally tractible without CUDA accelleration, so make sure to follow the CUDA Terrain instructions in Installation.md, and we recommend not to remove the `cuda_terrain` flag below.
````
python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_scenes 500 \
--pipeline_config slurm monocular_video cuda_terrain opengl_gt \
- --cleanup big_files --warmup_sec 60000 --config high_quality_terrain
+ --cleanup big_files --warmup_sec 60000 --config video high_quality_terrain
````
#### Creating large-scale stereo datasets
@@ -219,7 +218,7 @@ python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_
```
python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_scenes 500 \
--pipeline_config slurm monocular_video cuda_terrain opengl_gt \
- --cleanup big_files --warmup_sec 30000 --config high_quality_terrain \
+ --cleanup big_files --warmup_sec 30000 --config video high_quality_terrain \
--overrides camera.camera_pose_proposal.altitude=["uniform", 20, 30]
```
@@ -229,7 +228,7 @@ python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_
```
python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_scenes 500 \
--pipeline_config slurm monocular_video cuda_terrain opengl_gt \
- --cleanup big_files --warmup_sec 30000 --config high_quality_terrain \
+ --cleanup big_files --warmup_sec 30000 --config video high_quality_terrain \
--pipeline_overrides iterate_scene_tasks.frame_range=[1,25]
```
diff --git a/infinigen/OcMesher b/infinigen/OcMesher
new file mode 160000
index 000000000..4e5fad7b0
--- /dev/null
+++ b/infinigen/OcMesher
@@ -0,0 +1 @@
+Subproject commit 4e5fad7b0dd495444acf3ab2037bf08dd4b5d676
diff --git a/infinigen/__init__.py b/infinigen/__init__.py
index c898176f1..6e429ebd4 100644
--- a/infinigen/__init__.py
+++ b/infinigen/__init__.py
@@ -1,3 +1,3 @@
import logging
-__version__ = "1.1.0"
\ No newline at end of file
+__version__ = "1.2.0"
\ No newline at end of file
diff --git a/infinigen/core/execute_tasks.py b/infinigen/core/execute_tasks.py
index ff3c35e8d..f294ba4ad 100644
--- a/infinigen/core/execute_tasks.py
+++ b/infinigen/core/execute_tasks.py
@@ -342,7 +342,7 @@ def execute_tasks(
group_collections()
- if input_folder is not None:
+ if input_folder is not None and input_folder != output_folder:
for mesh in os.listdir(input_folder):
if (mesh.endswith(".glb") or mesh.endswith(".b_displacement.npy")) and not os.path.islink(output_folder / mesh):
os.symlink(input_folder / mesh, output_folder / mesh)
diff --git a/infinigen/core/nodes/node_info.py b/infinigen/core/nodes/node_info.py
index f7b8ceb1b..d248d4df2 100644
--- a/infinigen/core/nodes/node_info.py
+++ b/infinigen/core/nodes/node_info.py
@@ -42,8 +42,10 @@ class Nodes:
CombineHSV = 'ShaderNodeCombineHSV'
SeparateRGB = 'ShaderNodeSeparateRGB'
SeparateColor = 'ShaderNodeSeparateColor'
+ CompSeparateColor = 'CompositorNodeSeparateColor'
CombineRGB = 'ShaderNodeCombineRGB'
CombineColor = 'ShaderNodeCombineColor'
+ CompCombineColor = 'CompositorNodeCombineColor'
#bl3.5 additions
SeparateComponents = 'GeometryNodeSeparateComponents'
diff --git a/infinigen/core/rendering/render.py b/infinigen/core/rendering/render.py
index ebec75cbc..6416463ff 100644
--- a/infinigen/core/rendering/render.py
+++ b/infinigen/core/rendering/render.py
@@ -138,7 +138,12 @@ def configure_compositor_output(nw, frames_folder, image_denoised, image_noisy,
setattr(viewlayer.cycles, f"use_pass_{viewlayer_pass}", True)
slot_input = file_output_node.file_slots.new(socket_name)
render_socket = render_layers.outputs[socket_name]
- nw.links.new(render_socket, slot_input)
+ if viewlayer_pass == "vector":
+ separate_color = nw.new_node(Nodes.CompSeparateColor, [render_socket])
+ comnbine_color = nw.new_node(Nodes.CompCombineColor, [0, (separate_color, 3), (separate_color, 2), 0])
+ nw.links.new(comnbine_color.outputs[0], slot_input)
+ else:
+ nw.links.new(render_socket, slot_input)
file_slot_list.append(file_output_node.file_slots[slot_input.name])
slot_input = file_output_node.file_slots['Image']
diff --git a/infinigen/core/util/blender.py b/infinigen/core/util/blender.py
index c8f4a60a2..2e0fb568b 100644
--- a/infinigen/core/util/blender.py
+++ b/infinigen/core/util/blender.py
@@ -206,10 +206,11 @@ def __exit__(self, *_):
def select_none():
- if bpy.context.active_object is not None:
+ if hasattr(bpy.context, "active_object") and bpy.context.active_object is not None:
bpy.context.active_object.select_set(False)
- for obj in bpy.context.selected_objects:
- obj.select_set(False)
+ if hasattr(bpy.context, "selected_objects"):
+ for obj in bpy.context.selected_objects:
+ obj.select_set(False)
def select(objs):
diff --git a/infinigen/datagen/configs/data_schema/block_terrain_experiment.gin b/infinigen/datagen/configs/data_schema/block_terrain_experiment.gin
new file mode 100644
index 000000000..140bd0bb6
--- /dev/null
+++ b/infinigen/datagen/configs/data_schema/block_terrain_experiment.gin
@@ -0,0 +1,10 @@
+iterate_scene_tasks.global_tasks = [
+ {'name': 'coarse', 'func': @queue_coarse},
+ {'name': "populate", 'func': @queue_populate},
+ {'name': 'backuppopulate', 'func': @renderbackup/queue_populate, 'condition': 'prev_failed'},
+]
+iterate_scene_tasks.view_dependent_tasks = [
+ {'name': "fineterrain", 'func': @queue_fine_terrain},
+]
+
+queue_populate.input_prefix = "coarse"
\ No newline at end of file
diff --git a/infinigen/datagen/configs/data_schema/monocular_video.gin b/infinigen/datagen/configs/data_schema/monocular_video.gin
index 8f8655862..05733762c 100644
--- a/infinigen/datagen/configs/data_schema/monocular_video.gin
+++ b/infinigen/datagen/configs/data_schema/monocular_video.gin
@@ -1,16 +1,15 @@
iterate_scene_tasks.frame_range = [1, 192]
-iterate_scene_tasks.view_block_size = 8
+iterate_scene_tasks.view_block_size = 192
+iterate_scene_tasks.cam_block_size = 8
iterate_scene_tasks.cam_id_ranges = [1, 1]
iterate_scene_tasks.global_tasks = [
{'name': 'coarse', 'func': @queue_coarse},
+ {'name': "fineterrain", 'func': @queue_fine_terrain},
{'name': "populate", 'func': @queue_populate},
{'name': 'backuppopulate', 'func': @renderbackup/queue_populate, 'condition': 'prev_failed'},
- {'name': "fineterrain", 'func': @queue_fine_terrain},
-]
-iterate_scene_tasks.view_dependent_tasks = [
- {'name': "fineterrain", 'func': @queue_fine_terrain},
]
+iterate_scene_tasks.view_dependent_tasks = []
iterate_scene_tasks.camera_dependent_tasks = [
{'name': 'shortrender', 'func': @rendershort/queue_render},
{'name': 'backuprender', 'func': @renderbackup/queue_render, 'condition': 'prev_failed'},
diff --git a/infinigen/datagen/job_funcs.py b/infinigen/datagen/job_funcs.py
index d3d712d03..13984db48 100644
--- a/infinigen/datagen/job_funcs.py
+++ b/infinigen/datagen/job_funcs.py
@@ -121,6 +121,7 @@ def queue_populate(
seed,
configs,
taskname=None,
+ input_prefix="fine",
overrides=[],
input_indices=None, output_indices=None,
**kwargs,
@@ -132,7 +133,7 @@ def queue_populate(
input_suffix = get_suffix(input_indices)
output_suffix = get_suffix(output_indices)
- input_folder = folder/f'coarse{input_suffix}'
+ input_folder = folder/f'{input_prefix}{input_suffix}'
output_folder = input_folder
cmd = get_cmd(seed, 'populate', configs, taskname,
diff --git a/infinigen/datagen/manage_jobs.py b/infinigen/datagen/manage_jobs.py
index 2c4258ae3..888ddfb08 100644
--- a/infinigen/datagen/manage_jobs.py
+++ b/infinigen/datagen/manage_jobs.py
@@ -187,7 +187,9 @@ def init_db_from_existing(output_folder: Path):
existing_db = pd.read_csv(db_path, converters={"configs": literal_eval})
def init_scene(seed_folder):
- if not seed_folder.is_dir():
+ if not seed_folder.is_symlink() and not seed_folder.is_dir():
+ return None
+ if seed_folder.is_symlink() and not seed_folder.readlink().is_dir():
return None
if not (seed_folder/'logs').exists():
logger.warning(f'Skipping {seed_folder=} due to missing "logs" subdirectory')
diff --git a/infinigen/terrain/assets/landtiles/ant_landscape.py b/infinigen/terrain/assets/landtiles/ant_landscape.py
index cc631cc54..e20f44316 100644
--- a/infinigen/terrain/assets/landtiles/ant_landscape.py
+++ b/infinigen/terrain/assets/landtiles/ant_landscape.py
@@ -13,7 +13,7 @@
from infinigen.terrain.land_process.erosion import run_erosion
from infinigen.terrain.land_process.snowfall import run_snowfall
-from infinigen.terrain.utils import smooth, random_int
+from infinigen.terrain.utils import smooth, random_nat
from infinigen.core.util.organization import AssetFile, LandTile
@@ -23,7 +23,7 @@ def create(
subdivision_y,
):
def presets(**kwargs):
- bpy.ops.mesh.landscape_add(ant_terrain_name="Landscape", land_material="", water_material="", texture_block="", at_cursor=True, smooth_mesh=True, tri_face=False, sphere_mesh=False, subdivision_x=subdivision_x, subdivision_y=subdivision_y, mesh_size=2, mesh_size_x=2, mesh_size_y=2, random_seed=max(0, random_int()), water_plane=False, water_level=0.01, remove_double=False, show_main_settings=True, show_noise_settings=True, show_displace_settings=True, refresh=True, auto_refresh=True, **kwargs)
+ bpy.ops.mesh.landscape_add(ant_terrain_name="Landscape", land_material="", water_material="", texture_block="", at_cursor=True, smooth_mesh=True, tri_face=False, sphere_mesh=False, subdivision_x=subdivision_x, subdivision_y=subdivision_y, mesh_size=2, mesh_size_x=2, mesh_size_y=2, random_seed=random_nat(), water_plane=False, water_level=0.01, remove_double=False, show_main_settings=True, show_noise_settings=True, show_displace_settings=True, refresh=True, auto_refresh=True, **kwargs)
if preset_name == LandTile.Canyon:
strata = np.random.randint(6, 12)
diff --git a/infinigen/terrain/assets/landtiles/custom.py b/infinigen/terrain/assets/landtiles/custom.py
index baab0f92c..46d43aefb 100644
--- a/infinigen/terrain/assets/landtiles/custom.py
+++ b/infinigen/terrain/assets/landtiles/custom.py
@@ -141,6 +141,7 @@ def multi_mountains_asset(
coverage=params["coverage"],
slope_freq=params["slope_freq"],
slope_height=params["slope_height"],
+ is_asset=True,
)
heightmap = mountains.get_heightmap(X, Y)
mountains.cleanup()
@@ -175,6 +176,7 @@ def coast_asset(
coverage=params1["coverage"],
slope_freq=params1["slope_freq"],
slope_height=params1["slope_height"],
+ is_asset=True,
)
heightmap = mountains.get_heightmap(X, Y)
mountains.cleanup()
diff --git a/infinigen/terrain/core.py b/infinigen/terrain/core.py
index ad4b2571a..c16fcf5d6 100644
--- a/infinigen/terrain/core.py
+++ b/infinigen/terrain/core.py
@@ -12,16 +12,19 @@
import gin
import numpy as np
from mathutils.bvhtree import BVHTree
+
+from infinigen.OcMesher.ocmesher import OcMesher as UntexturedOcMesher
from infinigen.terrain.mesher import OpaqueSphericalMesher, TransparentSphericalMesher, UniformMesher
from infinigen.terrain.scene import scene, transfer_scene_info
from infinigen.terrain.surface_kernel.core import SurfaceKernel
-from infinigen.terrain.utils import Mesh, move_modifier, Vars, AttributeType, FieldsType
+from infinigen.terrain.utils import Mesh, move_modifier, Vars, AttributeType, FieldsType, get_caminfo, write_attributes
from infinigen.terrain.assets.ocean import ocean_asset
from infinigen.core.util.blender import SelectObjects, delete
from infinigen.core.util.logging import Timer
from infinigen.core.util.math import FixedSeed, int_hash
from infinigen.core.util.organization import SurfaceTypes, Attributes, Task, TerrainNames, ElementNames, Transparency, Materials, Assets, ElementTag, Tags, SelectionCriterions
from infinigen.assets.utils.tag import tag_object, tag_system
+
from numpy import ascontiguousarray as AC
logger = logging.getLogger(__name__)
@@ -39,6 +42,36 @@ def get_surface_type(surface, degrade_sdf_to_displacement=True):
return SurfaceTypes.Displacement
return surface.type
+
+class OcMesher(UntexturedOcMesher):
+ def __init__(self, cameras, **kwargs):
+ UntexturedOcMesher.__init__(self, get_caminfo(cameras)[0], **kwargs)
+
+ def __call__(self, kernels):
+ sdf_kernels = [(lambda x, k0=k: k0(x)[Vars.SDF]) for k in kernels]
+ meshes, in_view_tags = UntexturedOcMesher.__call__(self, sdf_kernels)
+ with Timer("compute attributes"):
+ write_attributes(kernels, None, meshes)
+ for mesh, tag in zip(meshes, in_view_tags):
+ mesh.vertex_attributes[Tags.OutOfView] = (~tag).astype(np.int32)
+ with Timer("concat meshes"):
+ mesh = Mesh.cat(meshes)
+ return mesh
+
+class CollectiveOcMesher(UntexturedOcMesher):
+ def __init__(self, cameras, **kwargs):
+ UntexturedOcMesher.__init__(self, get_caminfo(cameras)[0], **kwargs)
+
+ def __call__(self, kernels):
+ sdf_kernels = [lambda x: np.stack([k(x)[Vars.SDF] for k in kernels], -1).min(axis=-1)]
+ mesh, in_view_tag = UntexturedOcMesher.__call__(self, sdf_kernels)
+ mesh = mesh[0]
+ with Timer("compute attributes"):
+ write_attributes(kernels, mesh, [])
+ mesh.vertex_attributes[Tags.OutOfView] = (~in_view_tag[0]).astype(np.int32)
+ mesh = Mesh(mesh=mesh)
+ return mesh
+
@gin.configurable
class Terrain:
def __init__(
@@ -99,11 +132,10 @@ def cleanup(self):
@gin.configurable("export")
def export(self,
- spherical=False,
+ dynamic=False,
+ spherical=True, # false for OcMesher
cameras=None,
main_terrain_only=False,
- collective_transparent_overrides={},
- coarse_hidden=True,
remove_redundant_attrs=True,
):
meshes_dict = {}
@@ -112,11 +144,9 @@ def export(self,
opaque_elements = [element for element in self.elements_list if element.transparency == Transparency.Opaque]
if opaque_elements != []:
attributes_dict[TerrainNames.OpaqueTerrain] = set()
- if spherical:
- if coarse_hidden:
- mesher = OpaqueSphericalMesher(cameras=cameras)
- else:
- mesher = TransparentSphericalMesher(cameras=cameras)
+ if dynamic:
+ if spherical: mesher = OpaqueSphericalMesher(cameras=cameras)
+ else: mesher = OcMesher(cameras=cameras)
else:
mesher = UniformMesher()
with Timer(f"meshing {TerrainNames.OpaqueTerrain}"):
@@ -128,12 +158,13 @@ def export(self,
individual_transparent_elements = [element for element in self.elements_list if element.transparency == Transparency.IndividualTransparent]
for element in individual_transparent_elements:
if not main_terrain_only or element.__class__.name == self.main_terrain:
- if spherical:
+ if dynamic:
special_args = {}
if element.__class__.name == ElementNames.Atmosphere:
- special_args["coarse_multiplier"] = 64
- special_args["upscale"] = 1
- mesher = TransparentSphericalMesher(cameras=cameras, **special_args)
+ special_args["pixels_per_cube"] = 100
+ special_args["inv_scale"] = 1
+ if spherical: mesher = TransparentSphericalMesher(cameras=cameras, **special_args)
+ else: mesher = OcMesher(cameras=cameras, simplify_occluded=False, **special_args)
else: mesher = UniformMesher(enclosed=True)
with Timer(f"meshing {element.__class__.name}"):
mesh = mesher([element])
@@ -144,8 +175,9 @@ def export(self,
collective_transparent_elements = [element for element in self.elements_list if element.transparency == Transparency.CollectiveTransparent]
if collective_transparent_elements != []:
attributes_dict[TerrainNames.CollectiveTransparentTerrain] = set()
- if spherical:
- mesher = TransparentSphericalMesher(cameras=cameras, **collective_transparent_overrides)
+ if dynamic:
+ if spherical: mesher = TransparentSphericalMesher(cameras=cameras)
+ else: mesher = CollectiveOcMesher(cameras=cameras, simplify_occluded=False)
else:
mesher = UniformMesher()
with Timer(f"meshing {TerrainNames.CollectiveTransparentTerrain}"):
@@ -154,7 +186,7 @@ def export(self,
for element in collective_transparent_elements:
attributes_dict[TerrainNames.CollectiveTransparentTerrain].update(element.attributes)
- if main_terrain_only or spherical:
+ if main_terrain_only or dynamic:
for mesh_name in meshes_dict:
mesh_name_unapplied = mesh_name
if mesh_name + "_unapplied" in bpy.data.objects.keys():
@@ -173,7 +205,7 @@ def export(self,
if get_surface_type(surface) == SurfaceTypes.BlenderDisplacement:
meshes_dict[mesh_name].blender_displacements.append(surface.mod_name)
- if spherical:
+ if dynamic:
if remove_redundant_attrs:
for mesh_name in meshes_dict:
if len(attributes_dict[mesh_name]) == 1:
@@ -263,7 +295,7 @@ def fine_terrain(self, output_folder, optimize_terrain_diskusage=True):
with FixedSeed(int_hash(["Ocean", self.seed])):
ocean_asset(output_folder / Assets.Ocean, bpy.context.scene.frame_start, bpy.context.scene.frame_end, link_folder=self.on_the_fly_asset_folder / Assets.Ocean)
self.surfaces_into_sdf()
- fine_meshes, _ = self.export(spherical=True, cameras=[bpy.context.scene.camera])
+ fine_meshes, _ = self.export(dynamic=True, cameras=[bpy.context.scene.camera])
for mesh_name in fine_meshes:
obj = fine_meshes[mesh_name].export_blender(mesh_name + "_fine")
if mesh_name not in hidden_in_viewport: self.tag_terrain(obj)
diff --git a/infinigen/terrain/elements/core.py b/infinigen/terrain/elements/core.py
index 688d8f5e6..e9b3b8861 100644
--- a/infinigen/terrain/elements/core.py
+++ b/infinigen/terrain/elements/core.py
@@ -6,15 +6,18 @@
from ctypes import POINTER, c_float, c_int32, c_size_t
+import gin
import numpy as np
from numpy import ascontiguousarray as AC
from infinigen.terrain.utils import ASFLOAT, ASINT, Vars, load_cdll, register_func
from infinigen.core.util.organization import Materials
-
+@gin.configurable
class Element:
called_time = {}
- def __init__(self, lib_name, material, transparency):
+ def __init__(self, lib_name, material, transparency, bounding_shape=None, is_asset=False):
+ self.bounding_shape = bounding_shape
+ self.is_asset = is_asset
if lib_name in Element.called_time:
lib_name_X = f"{lib_name}_{Element.called_time[lib_name]}"
print(f"{lib_name} already loaded, loading {lib_name_X} instead")
@@ -76,6 +79,14 @@ def __call__(self, positions, sdf_only=False):
else:
auxs.append(None)
self.call(N, ASFLOAT(AC(positions.astype(np.float32))), ASFLOAT(sdf), *[POINTER(c_float)() if x is None else ASFLOAT(x) for x in auxs])
+ bounding_shape = self.bounding_shape
+ if not self.is_asset and bounding_shape is not None:
+ if bounding_shape[0] == "cube":
+ x_min, x_max, y_min, y_max, z_min, z_max = bounding_shape[1:]
+ out_bound = (positions[:, 0] < x_min) | (positions[:, 0] > x_max) \
+ | (positions[:, 1] < y_min) | (positions[:, 1] > y_max) \
+ | (positions[:, 2] < z_min) | (positions[:, 2] > z_max)
+ sdf[out_bound] = 1e6
ret = {}
ret[Vars.SDF] = sdf
diff --git a/infinigen/terrain/elements/landtiles.py b/infinigen/terrain/elements/landtiles.py
index 4a53ed1e5..7c128b01f 100644
--- a/infinigen/terrain/elements/landtiles.py
+++ b/infinigen/terrain/elements/landtiles.py
@@ -53,6 +53,7 @@ def __init__(
transparency=Transparency.Opaque,
use_cblerp=False,
smooth=False,
+ direction_deg=0,
):
self.device = device
self.on_the_fly_asset_folder = on_the_fly_asset_folder
@@ -105,7 +106,8 @@ def __init__(
randomness, frequency, attribute_probability, attribute_distance_range, island_probability, tile_size,
none_to_0(height_modification_start), none_to_0(height_modification_end),
none_to_0(attribute_modification_start_height), none_to_0(attribute_modification_end_height),
- attribute_modification_distort_freq, attribute_modification_distort_mag, empty_below, y_tilt, y_tilt_clip, sharpen, mask_random_freq,
+ attribute_modification_distort_freq, attribute_modification_distort_mag, empty_below, y_tilt, y_tilt_clip, sharpen,
+ mask_random_freq, direction_deg,
*tile_heights,
]), float_data)).astype(np.float32))
diff --git a/infinigen/terrain/elements/mountains.py b/infinigen/terrain/elements/mountains.py
index 52992acdf..6ef567bfd 100644
--- a/infinigen/terrain/elements/mountains.py
+++ b/infinigen/terrain/elements/mountains.py
@@ -34,6 +34,7 @@ def __init__(
slope_octaves=9,
material=Materials.MountainCollection,
transparency=Transparency.Opaque,
+ is_asset=False,
):
self.device = device
min_freq = rg(min_freq)
@@ -57,5 +58,5 @@ def __init__(
slope_freq, slope_octaves, slope_height,
], dtype=np.float32))
- Element.__init__(self, "mountains", material, transparency)
+ Element.__init__(self, "mountains", material, transparency, is_asset=is_asset)
self.tag = ElementTag.Terrain
\ No newline at end of file
diff --git a/infinigen/terrain/land_process/erosion.py b/infinigen/terrain/land_process/erosion.py
index 97ac3991d..712c39d97 100644
--- a/infinigen/terrain/land_process/erosion.py
+++ b/infinigen/terrain/land_process/erosion.py
@@ -20,18 +20,19 @@
def run_erosion(
folder,
Ns=[512, 2048],
- n_iters = [int(1e4), int(5e5)],
+ n_iters=[int(1e4), int(5e5)],
mask_height_range=None,
spatial=1,
mask_range=(4, 47),
ground_depth=25,
sinking_rate=0.05,
+ c_eq_factor=[1, 1],
):
dll = load_cdll("terrain/lib/cpu/soil_machine/SoilMachine.so")
func = dll.run
func.argtypes = [
POINTER(c_float), POINTER(c_float), POINTER(c_float),
- c_int32, c_int32, c_int32, c_int32, c_int32, c_float, c_char_p
+ c_int32, c_int32, c_int32, c_int32, c_int32, c_float, c_float, c_char_p
]
func.restype = None
@@ -46,14 +47,15 @@ def run_erosion(
if N > M: heightmap = smooth(heightmap, 3)
original_heightmap = heightmap.copy()
ground_level = heightmap.min() - ground_depth
- heightmap = AC((heightmap - ground_level).astype(np.float32))
+ height_scale = 1
+ heightmap = AC((heightmap - ground_level).astype(np.float32) * height_scale)
result_heightmap = np.zeros_like(heightmap)
watertrack = np.zeros_like(heightmap)
func(
ASFLOAT(heightmap), ASFLOAT(result_heightmap), ASFLOAT(watertrack),
- N, N, 0, n_iter, 0, spatial * tile_size, str(soil_config_path).encode('utf-8'),
+ N, N, 0, n_iter, 0, spatial * tile_size, c_eq_factor[i], str(soil_config_path).encode('utf-8'),
)
- heightmap = result_heightmap + ground_level
+ heightmap = result_heightmap / height_scale + ground_level
watertrack = watertrack.reshape((N, N))
watertrack = np.clip((watertrack - mask_range[0]) / (mask_range[1] - mask_range[0]), a_min=0, a_max=1)
watertrack = watertrack ** 0.2
diff --git a/infinigen/terrain/mesher/spherical_mesher.py b/infinigen/terrain/mesher/spherical_mesher.py
index 80598b784..df666fe99 100644
--- a/infinigen/terrain/mesher/spherical_mesher.py
+++ b/infinigen/terrain/mesher/spherical_mesher.py
@@ -14,9 +14,8 @@
magnifier = 1e6
-# bounding_box for trailer use
@gin.configurable
-def kernel_caller(kernels, XYZ, r_bound_max=None, cam_loc=None, bounding_box=None):
+def kernel_caller(kernels, XYZ, r_bound_max=None, cam_loc=None):
sdfs = []
for kernel in kernels:
ret = kernel(XYZ, sdf_only=1)
@@ -25,12 +24,6 @@ def kernel_caller(kernels, XYZ, r_bound_max=None, cam_loc=None, bounding_box=Non
R = np.linalg.norm(XYZ - cam_loc, axis=-1)
mask = R / r_bound_max - 1
sdf = np.maximum(sdf, mask * magnifier)
- if bounding_box is not None:
- x_min, x_max, y_min, y_max, z_min, z_max = bounding_box
- out_bound = (XYZ[:, 0] < x_min) | (XYZ[:, 0] > x_max) \
- | (XYZ[:, 1] < y_min) | (XYZ[:, 1] > y_max) \
- | (XYZ[:, 2] < z_min) | (XYZ[:, 2] > z_max)
- sdf[out_bound] = 1e6
sdfs.append(sdf)
ret = np.stack(sdfs, -1)
return ret
@@ -43,7 +36,7 @@ def __init__(self,
r_max=1e3,
complete_depth_test=True,
):
- self.cam_pose, _, self.fov, self.H, self.W, _ = get_caminfo(cameras)
+ _, self.cam_pose, self.fov, self.H, self.W, _ = get_caminfo(cameras)
assert self.fov[0] < np.pi / 2 and self.fov[1] < np.pi / 2, "the algorithm does not support larger-than-90-degree fov yet"
self.r_min = r_min
self.r_max = r_max
@@ -120,20 +113,19 @@ def __init__(self,
base_90d_resolution=None,
pixels_per_cube=1.84,
test_downscale=5,
- upscale=8,
+ inv_scale=8,
r_lengthen=3,
- coarse_multiplier=1,
camera_annotation_frames=None,
):
SphericalMesher.__init__(self, cameras)
self.cameras = cameras
self.camera_annotation_frames = camera_annotation_frames
assert bool(base_90d_resolution is None) ^ bool(pixels_per_cube is None)
- if base_90d_resolution is None: base_90d_resolution = int(1 / (pixels_per_cube * upscale * self.fov[0] / np.pi * 2 / self.H))
- base_90d_resolution = base_90d_resolution // coarse_multiplier // test_downscale * test_downscale
+ if base_90d_resolution is None: base_90d_resolution = int(1 / (pixels_per_cube * inv_scale * self.fov[0] / np.pi * 2 / self.H))
+ base_90d_resolution = base_90d_resolution // test_downscale * test_downscale
base_R = int((np.log(self.r_max) - np.log(self.r_min)) / (np.pi/2 / base_90d_resolution) / r_lengthen)
- print(f"In view mesh angle resolution 90d/{base_90d_resolution * upscale}, about {base_90d_resolution * upscale * self.fov[0] / np.pi * 2 / self.H: .2f} marching cube per pixel")
+ print(f"In view mesh angle resolution 90d/{base_90d_resolution * inv_scale}, about {base_90d_resolution * inv_scale * self.fov[0] / np.pi * 2 / self.H: .2f} marching cube per pixel")
print(f"Out view mesh angle resolution 90d/{base_90d_resolution}, about {base_90d_resolution * self.fov[0] / np.pi * 2 / self.H: .2f} marching cube per pixel")
fov = self.fov
@@ -147,7 +139,7 @@ def __init__(self,
base_90d_resolution,
base_R,
test_downscale=test_downscale,
- inview_upscale=upscale,
+ inview_upscale=inv_scale,
H_fov=rounded_fov[0], W_fov=rounded_fov[1],
N0=N0, N1=N1,
complete_depth_test=self.complete_depth_test,
diff --git a/infinigen/terrain/source/common/elements/landtiles.h b/infinigen/terrain/source/common/elements/landtiles.h
index 0331e686e..bed726ffa 100644
--- a/infinigen/terrain/source/common/elements/landtiles.h
+++ b/infinigen/terrain/source/common/elements/landtiles.h
@@ -55,7 +55,8 @@ DEVICE_FUNC void landtiles(
float y_tilt_clip = f_params[14];
float sharpen = f_params[15];
float mask_random_freq = f_params[16];
- const int f_offset = 17;
+ float direction_deg = f_params[17];
+ const int f_offset = 18;
float *tile_heights = f_params + f_offset;
float *heightmap = f_params + f_offset + len_tiles;
@@ -63,7 +64,11 @@ DEVICE_FUNC void landtiles(
float *coast_direction = f_params + f_offset + len_tiles + \
len_tiles * n_instances * N * N + intrinsic_auxiliaries * len_tiles * n_instances * N * N;
-
+ direction_deg = 90 - direction_deg;
+ float px = position.x;
+ position.x = position.x * cos(direction_deg / 180 * acosf(-1.0)) - position.y * sin(direction_deg / 180 * acosf(-1.0));
+ position.y = position.y * cos(direction_deg / 180 * acosf(-1.0)) + px * sin(direction_deg / 180 * acosf(-1.0));
+
const int n_neighbors = 8;
float heights_i0, height_grad_i0, covers_i0[intrinsic_auxiliaries];
for (int i = 0; i < n_lattice; i++) {
diff --git a/infinigen/terrain/source/cpu/soil_machine/SoilMachine.cpp b/infinigen/terrain/source/cpu/soil_machine/SoilMachine.cpp
index 10f77a2f6..db8d6a06b 100644
--- a/infinigen/terrain/source/cpu/soil_machine/SoilMachine.cpp
+++ b/infinigen/terrain/source/cpu/soil_machine/SoilMachine.cpp
@@ -33,6 +33,7 @@ extern "C" {
int NWATER,
int NWIND,
float SCALE0,
+ float c_eq_factor,
char* soil_file
) {
layers.clear();
@@ -44,18 +45,19 @@ extern "C" {
WindParticle::init(SIZEX, SIZEY);
Layermap map(SEED, glm::ivec2(SIZEX, SIZEY), SCALE0, heightmap);
+ c_eq_factor /= 80;
for(int i = 0; i < NWATER; i++){
WaterParticle particle(map, SCALE0);
while(true){
- while(particle.move(map, vertexpool) && particle.interact(map, vertexpool));
- if(!particle.flood(map, vertexpool))
+ while(particle.move(map, vertexpool) && particle.interact(c_eq_factor, map, vertexpool));
+ if(!particle.flood(c_eq_factor, map, vertexpool))
break;
}
}
- WaterParticle::seep(SCALE0, map, vertexpool);
+ WaterParticle::seep(c_eq_factor, SCALE0, map, vertexpool);
for(int i = 0; i < NWIND; i++){
WindParticle particle(map, SCALE0);
diff --git a/infinigen/terrain/source/cpu/soil_machine/particle/particle.h b/infinigen/terrain/source/cpu/soil_machine/particle/particle.h
index ded47a361..d9063ccc5 100644
--- a/infinigen/terrain/source/cpu/soil_machine/particle/particle.h
+++ b/infinigen/terrain/source/cpu/soil_machine/particle/particle.h
@@ -36,7 +36,7 @@ struct Particle {
// because I can't solve the bug, I'm not familiar with static in c++, so I make SCALE an arg --- Zeyu
//This is applied to multiple types of erosion, so I put it in here!
- static void cascade(float SCALE, vec2 pos, Layermap& map, Vertexpool& vertexpool, int transferloop = 0){
+ static void cascade(float c_eq_factor, float SCALE, vec2 pos, Layermap& map, Vertexpool& vertexpool, int transferloop = 0){
ivec2 ipos = round(pos);
@@ -72,7 +72,7 @@ struct Particle {
for(auto& npos: sn){
//Full Height-Different Between Positions!
- float diff = (map.height(ipos) - map.height(npos))*(float)SCALE/80.0f;
+ float diff = (map.height(ipos) - map.height(npos))*(float)SCALE * c_eq_factor;
if(diff == 0) //No Height Difference
continue;
@@ -98,12 +98,13 @@ struct Particle {
if(map.remove(tpos, transfer) != 0)
recascade = true;
- map.add(bpos, map.pool.get(transfer, param.cascades));
+ sec *addition = map.pool.get(transfer, param.cascades);
+ map.add(bpos, addition);
// map.update(tpos, vertexpool);
// map.update(bpos, vertexpool);
if(recascade && transferloop > 0)
- cascade(SCALE, npos, map, vertexpool, --transferloop);
+ cascade(c_eq_factor, SCALE, npos, map, vertexpool, --transferloop);
}
diff --git a/infinigen/terrain/source/cpu/soil_machine/particle/water.h b/infinigen/terrain/source/cpu/soil_machine/particle/water.h
index aa5fbc897..0def8e196 100644
--- a/infinigen/terrain/source/cpu/soil_machine/particle/water.h
+++ b/infinigen/terrain/source/cpu/soil_machine/particle/water.h
@@ -112,10 +112,10 @@ struct WaterParticle : public Particle {
}
- bool interact(Layermap& map, Vertexpool& vertexpool){
+ bool interact(float c_eq_factor, Layermap& map, Vertexpool& vertexpool){
//Equilibrium Sediment Transport Amount
- double c_eq = param.solubility*(map.height(ipos)-map.height(pos))*(double)SCALE/80.0;
+ double c_eq = param.solubility*(map.height(ipos)-map.height(pos))*(double)SCALE * c_eq_factor;
if(c_eq < 0.0) c_eq = 0.0;
if(c_eq > 1.0) c_eq = 1.0;
@@ -145,12 +145,13 @@ struct WaterParticle : public Particle {
else if(cdiff < 0) {
sediment += soils[contains].equrate*cdiff;
- map.add(ipos, map.pool.get(-soils[contains].equrate*cdiff*volume, contains));
+ sec *addition = map.pool.get(-soils[contains].equrate*cdiff*volume, contains);
+ map.add(ipos, addition);
}
//Particle Cascade: Thermal Erosion!
- Particle::cascade(SCALE, pos, map, vertexpool, 0);
+ Particle::cascade(c_eq_factor, SCALE, pos, map, vertexpool, 0);
//Update Map, Particle
sediment /= (1.0-evaprate);
@@ -160,7 +161,7 @@ struct WaterParticle : public Particle {
}
- bool flood(Layermap& map, Vertexpool& vertexpool){
+ bool flood(float c_eq_factor, Layermap& map, Vertexpool& vertexpool){
if(volume < minvol || spill-- <= 0)
return false;
@@ -170,13 +171,15 @@ struct WaterParticle : public Particle {
// Add Water
// Add Remaining Soil
+ sec *addition;
+ addition = map.pool.get(sediment*soils[contains].equrate, contains);
+ map.add(ipos, addition);
+ Particle::cascade(c_eq_factor, SCALE, pos, map, vertexpool, 0);
- map.add(ipos, map.pool.get(sediment*soils[contains].equrate, contains));
- Particle::cascade(SCALE, pos, map, vertexpool, 0);
-
- map.add(ipos, map.pool.get(volume*volumeFactor, soilmap["Air"]));
+ addition = map.pool.get(volume*volumeFactor, soilmap["Air"]);
+ map.add(ipos, addition);
seep(ipos, map, vertexpool);
- WaterParticle::cascade(SCALE, ipos, map, vertexpool, spill);
+ WaterParticle::cascade(c_eq_factor, SCALE, ipos, map, vertexpool, spill);
// map.update(ipos, vertexpool);
return false;
@@ -187,7 +190,7 @@ struct WaterParticle : public Particle {
- static void cascade(float SCALE, vec2 pos, Layermap& map, Vertexpool& vertexpool, int spill = 0){
+ static void cascade(float c_eq_factor, float SCALE, vec2 pos, Layermap& map, Vertexpool& vertexpool, int spill = 0){
ivec2 ipos = pos;
@@ -244,7 +247,7 @@ struct WaterParticle : public Particle {
fB = secB->floor;
// Actual Height Difference Between Watertables
- double diff = (fA + whA - fB - whB)*(double)SCALE/80.0;
+ double diff = (fA + whA - fB - whB)*(double)SCALE * c_eq_factor;
if(diff == 0) //No Height Difference
continue;
@@ -274,7 +277,6 @@ struct WaterParticle : public Particle {
bool recascade = false;
if(transfer == wh){
-
double diff = map.remove(tpos, transfer);
// map.update(tpos, vertexpool);
@@ -286,15 +288,14 @@ struct WaterParticle : public Particle {
particle.volume = transfer / WaterParticle::volumeFactor;
while(true){
- while(particle.move(map, vertexpool) && particle.interact(map, vertexpool));
- if(!particle.flood(map, vertexpool))
+ while(particle.move(map, vertexpool) && particle.interact(c_eq_factor, map, vertexpool));
+ if(!particle.flood(c_eq_factor, map, vertexpool))
break;
}
}
else {
-
if(map.remove(tpos, transfer) != 0)
recascade = true;
if(transfer > 0) recascade = true;
@@ -306,7 +307,7 @@ struct WaterParticle : public Particle {
}
if(recascade && spill > 0)
- WaterParticle::cascade(SCALE, npos, map, vertexpool, --spill);
+ WaterParticle::cascade(c_eq_factor, SCALE, npos, map, vertexpool, --spill);
}
@@ -351,8 +352,9 @@ struct WaterParticle : public Particle {
if(transfer > 0){
// Remove from Top Layer
- if(top->type == soilmap["Air"])
+ if(top->type == soilmap["Air"]) {
double diff = map.remove(ipos, seepage*transfer);
+ }
else
top->saturation -= (seepage*transfer) / (top->size*param.porosity);
@@ -368,12 +370,12 @@ struct WaterParticle : public Particle {
}
- static void seep(float SCALE, Layermap& map, Vertexpool& vertexpool){
+ static void seep(float c_eq_factor, float SCALE, Layermap& map, Vertexpool& vertexpool){
for(size_t x = 0; x < map.dim.x; x++)
for(size_t y = 0; y < map.dim.y; y++){
seep(ivec2(x,y), map, vertexpool);
- WaterParticle::cascade(SCALE, ivec2(x,y), map, vertexpool, 3);
+ WaterParticle::cascade(c_eq_factor, SCALE, ivec2(x,y), map, vertexpool, 3);
}
}
diff --git a/infinigen/terrain/source/cpu/soil_machine/particle/wind.h b/infinigen/terrain/source/cpu/soil_machine/particle/wind.h
index 5126c62e8..569b5392d 100644
--- a/infinigen/terrain/source/cpu/soil_machine/particle/wind.h
+++ b/infinigen/terrain/source/cpu/soil_machine/particle/wind.h
@@ -127,7 +127,7 @@ struct WindParticle : public Particle {
double diff = map.remove(ipos, param.suspension*force);
sediment += (param.suspension*force - diff);
- Particle::cascade(SCALE, ipos, map, vertexpool, 1);
+ Particle::cascade(1.0/80, SCALE, ipos, map, vertexpool, 1);
// map.update(ipos, vertexpool);
}
@@ -141,10 +141,10 @@ struct WindParticle : public Particle {
map.add(npos, map.pool.get(0.5f*soils[contains].suspension*sediment, contains));
map.add(ipos, map.pool.get(0.5f*soils[contains].suspension*sediment, contains));
- Particle::cascade(SCALE, ipos, map, vertexpool, 1);
+ Particle::cascade(1.0/80, SCALE, ipos, map, vertexpool, 1);
// map.update(ipos, vertexpool);
- Particle::cascade(SCALE, npos, map, vertexpool, 1);
+ Particle::cascade(1.0/80, SCALE, npos, map, vertexpool, 1);
// map.update(npos, vertexpool);
}
diff --git a/infinigen/terrain/utils/__init__.py b/infinigen/terrain/utils/__init__.py
index 734ed1b77..1f1862aef 100644
--- a/infinigen/terrain/utils/__init__.py
+++ b/infinigen/terrain/utils/__init__.py
@@ -11,7 +11,7 @@
from .image_processing import (
boundary_smooth, smooth, read, sharpen, grid_distance, get_normal
)
-from .random import perlin_noise, chance, drive_param, random_int, random_int_large
+from .random import perlin_noise, chance, drive_param, random_int, random_int_large, random_nat
from .kernelizer_util import (
ATTRTYPE_DIMS, ATTRTYPE_FIELDS, ATTRTYPE_NP, NODE_ATTRS_AVAILABLE,
diff --git a/infinigen/terrain/utils/camera.py b/infinigen/terrain/utils/camera.py
index ee6fe80a4..295dfcda0 100644
--- a/infinigen/terrain/utils/camera.py
+++ b/infinigen/terrain/utils/camera.py
@@ -47,31 +47,46 @@ def get_expanded_fov(cam_pose0, cam_poses, fov):
@gin.configurable
-def get_caminfo(cameras, relax=1.05):
+def get_caminfo(cameras, relax=1.05, ids_within_rig=2):
cam_poses = []
+ fovs = []
+ Ks = []
+ Hs = []
+ Ws = []
coords_trans_matrix = np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
fs, fe = bpy.context.scene.frame_start, bpy.context.scene.frame_end
fc = bpy.context.scene.frame_current
for f in range(fs, fe + 1):
bpy.context.scene.frame_set(f)
for cam in cameras:
- cam_pose = np.array(cam.matrix_world)
- cam_pose = np.dot(np.array(cam_pose), coords_trans_matrix)
- cam_poses.append(cam_pose)
- fov_rad = cam.data.angle
_, cid0, cid1 = cam.name.split("/")
- cam = get_camera(cid0, 1 - int(cid1), 1)
- if cam is None: continue
- cam_pose = np.array(cam.matrix_world)
- cam_pose = np.dot(np.array(cam_pose), coords_trans_matrix)
- cam_poses.append(cam_pose)
+ rig = []
+ if ids_within_rig is not None:
+ for id in range(ids_within_rig):
+ c = get_camera(cid0, id, 1)
+ if c is not None: rig.append(c)
+ else:
+ rig.append(cam)
+ for c in rig:
+ cam_pose = np.array(c.matrix_world)
+ cam_pose = np.dot(np.array(cam_pose), coords_trans_matrix)
+ cam_poses.append(cam_pose)
+ fov_rad = cam.data.angle
+ fov_rad *= relax
+ H, W = bpy.context.scene.render.resolution_y, bpy.context.scene.render.resolution_x
+ fov0 = np.arctan(H / 2 / (W / 2 / np.tan(fov_rad / 2))) * 2
+ fov = np.array([fov0, fov_rad])
+ fovs.append(fov)
+ K = getK(fov, H, W)
+ Ks.append(K)
+ Hs.append(H)
+ Ws.append(W)
bpy.context.scene.frame_set(fc)
cam_poses = np.stack(cam_poses)
cam_pose = pose_average(cam_poses)
- fov_rad *= relax
- H, W = bpy.context.scene.render.resolution_y, bpy.context.scene.render.resolution_x
- fov0 = np.arctan(H / 2 / (W / 2 / np.tan(fov_rad / 2))) * 2
- fov = (fov0, fov_rad)
+ fovs = np.stack(fovs)
+ fov = fovs.max(axis=0)
fov = get_expanded_fov(cam_pose, cam_poses, fov)
- K = getK(fov, H, W)
- return cam_pose, cam_poses, fov, H, W, K
+ H = max(Hs)
+ W = max(Ws)
+ return (cam_poses, Ks, Hs, Ws), cam_pose, fov, H, W, K
diff --git a/infinigen/terrain/utils/mesh.py b/infinigen/terrain/utils/mesh.py
index 3dfe84720..a9c70ab0a 100644
--- a/infinigen/terrain/utils/mesh.py
+++ b/infinigen/terrain/utils/mesh.py
@@ -71,6 +71,7 @@ def __init__(self, normal_mode=NormalMode.Mean,
path=None,
heightmap=None, L=None, downsample=1,
vertices=None, faces=None, vertex_attributes=None,
+ mesh=None,
obj=None, mesh_only=False, **kwargs
):
self.normal_mode = normal_mode
@@ -100,6 +101,8 @@ def __init__(self, normal_mode=NormalMode.Mean,
_trimesh = trimesh.Trimesh(verts, faces)
elif vertices is not None:
_trimesh = trimesh.Trimesh(vertices=vertices, faces=faces.astype(np.int32), vertex_attributes=vertex_attributes, process=False)
+ elif mesh is not None:
+ _trimesh = mesh
elif obj is not None:
verts_bpy = obj.data.vertices
faces_bpy = obj.data.polygons
diff --git a/infinigen/terrain/utils/random.py b/infinigen/terrain/utils/random.py
index 549bfd6e2..608664902 100644
--- a/infinigen/terrain/utils/random.py
+++ b/infinigen/terrain/utils/random.py
@@ -16,6 +16,11 @@
def random_int():
return np.random.randint(np.iinfo(np.int32).min, np.iinfo(np.int32).max)
+
+def random_nat():
+ return np.random.randint(1, np.iinfo(np.int32).max)
+
+
def random_int_large():
return random.getrandbits(128)
diff --git a/infinigen/tools/terrain/generate_terrain_assets.py b/infinigen/tools/terrain/generate_terrain_assets.py
index 976737c24..45fa00f8d 100644
--- a/infinigen/tools/terrain/generate_terrain_assets.py
+++ b/infinigen/tools/terrain/generate_terrain_assets.py
@@ -4,9 +4,6 @@
# Authors: Zeyu Ma
-'''
-fileheader placeholder
-'''
import os
import sys
diff --git a/infinigen/tools/terrain/landtile_viewer.py b/infinigen/tools/terrain/landtile_viewer.py
index 1d21bdc85..a1e56df30 100644
--- a/infinigen/tools/terrain/landtile_viewer.py
+++ b/infinigen/tools/terrain/landtile_viewer.py
@@ -22,6 +22,8 @@
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', type=str)
parser.add_argument('-o', '--overlay', type=int, default=False)
+ parser.add_argument('--mesh', type=str, default="")
+ parser.add_argument('--scene', type=str, default="")
args = init.parse_args_blender(parser)
folder = os.path.dirname(args.input)
@@ -33,6 +35,7 @@
mesh.vertex_attributes["attribute"] = image.reshape(-1).astype(np.float32)
clear_scene()
obj = mesh.export_blender("preview")
+ if args.mesh != "": mesh.save(args.mesh)
if args.overlay:
material = bpy.data.materials.new(name="preview_material")
material.use_nodes = True
@@ -40,3 +43,5 @@
new_attribute_node = nw.new_node(Nodes.Attribute, [], {"attribute_name": "attribute"})
material.node_tree.links.new(new_attribute_node.outputs['Color'], material.node_tree.nodes['Principled BSDF'].inputs['Base Color'])
obj.active_material = material
+ if args.scene != "": bpy.ops.wm.save_mainfile(filepath=args.scene)
+
diff --git a/infinigen_examples/configs/experimental.gin b/infinigen_examples/configs/extras/experimental.gin
similarity index 100%
rename from infinigen_examples/configs/experimental.gin
rename to infinigen_examples/configs/extras/experimental.gin
diff --git a/infinigen_examples/configs/stereo_training.gin b/infinigen_examples/configs/extras/stereo_training.gin
similarity index 100%
rename from infinigen_examples/configs/stereo_training.gin
rename to infinigen_examples/configs/extras/stereo_training.gin
diff --git a/infinigen_examples/configs/use_cached_fire.gin b/infinigen_examples/configs/extras/use_cached_fire.gin
similarity index 100%
rename from infinigen_examples/configs/use_cached_fire.gin
rename to infinigen_examples/configs/extras/use_cached_fire.gin
diff --git a/infinigen_examples/configs/use_on_the_fly_fire.gin b/infinigen_examples/configs/extras/use_on_the_fly_fire.gin
similarity index 100%
rename from infinigen_examples/configs/use_on_the_fly_fire.gin
rename to infinigen_examples/configs/extras/use_on_the_fly_fire.gin
diff --git a/infinigen_examples/configs/performance/fast_terrain_assets.gin b/infinigen_examples/configs/performance/fast_terrain_assets.gin
index 7c830ba23..931086c0d 100644
--- a/infinigen_examples/configs/performance/fast_terrain_assets.gin
+++ b/infinigen_examples/configs/performance/fast_terrain_assets.gin
@@ -3,8 +3,4 @@ upsidedown_mountains.load_assets.on_the_fly_instances = 1
caves.load_assets.on_the_fly_instances = 1
run_erosion.n_iters = [1,1]
-scene.caves_chance=0.0
-
-multi_mountains_asset.snowfall = False
-coast_asset.snowfall = False
-ant_landscape_asset.snowfall = False
\ No newline at end of file
+scene.caves_chance=0.0
\ No newline at end of file
diff --git a/infinigen_examples/configs/performance/high_quality_terrain.gin b/infinigen_examples/configs/performance/high_quality_terrain.gin
index 892667666..068eae244 100644
--- a/infinigen_examples/configs/performance/high_quality_terrain.gin
+++ b/infinigen_examples/configs/performance/high_quality_terrain.gin
@@ -1,3 +1,4 @@
+OcMesher.pixels_per_cube = 3
OpaqueSphericalMesher.pixels_per_cube = 0.92
TransparentSphericalMesher.pixels_per_cube = 1.38
diff --git a/infinigen_examples/configs/scene_types/cave.gin b/infinigen_examples/configs/scene_types/cave.gin
index 2be9df77d..772d750f8 100644
--- a/infinigen_examples/configs/scene_types/cave.gin
+++ b/infinigen_examples/configs/scene_types/cave.gin
@@ -4,7 +4,7 @@ compose_scene.underwater_domain_tags = 'landscape,liquid_covered'
compose_scene.trees_chance = 0.4
compose_scene.rocks_chance = 0.8
-compose_scene.glowing_rocks_chance = 0.5
+compose_scene.glowing_rocks_chance = 1
compose_scene.grass_chance = 0.4
compose_scene.ferns_chance = 0.6
compose_scene.mushroom_chance = 0.8
diff --git a/infinigen_examples/configs/video.gin b/infinigen_examples/configs/video.gin
new file mode 100644
index 000000000..e412998c5
--- /dev/null
+++ b/infinigen_examples/configs/video.gin
@@ -0,0 +1 @@
+export.spherical = False # use OcMesher
\ No newline at end of file
diff --git a/install.sh b/install.sh
deleted file mode 100755
index 0a62b520c..000000000
--- a/install.sh
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/bin/bash
-
-set -e
-
-if ! command -v wget &> /dev/null
-then
- echo "wget could not be found, please 'sudo apt-get install wget' or 'brew install wget'"
- exit
-fi
-
-OS=$(uname -s)
-ARCH=$(uname -m)
-
-if [ "${OS}" = "Linux" ]; then
- BLENDER_WGET_LINK='https://download.blender.org/release/Blender3.3/blender-3.3.1-linux-x64.tar.xz'
- BLENDER_WGET_FILE='blender.tar.xz'
-
- BLENDER_UNTAR_DIR='blender-3.3.1-linux-x64'
- BLENDER_DIR='blender'
- BLENDER_PYTHON="${BLENDER_DIR}/3.3/python/bin/python3.10"
- BLENDER_INCLUDE="${BLENDER_DIR}/3.3/python/include/python3.10"
- BLENDER_PACKAGES="${BLENDER_DIR}/3.3/python/lib/python3.10/site-packages"
- BLENDER_ADDONS="${BLENDER_DIR}/3.3/scripts/addons"
- BLENDER_EXE="${BLENDER_DIR}/blender"
-
- NURBS_SCRIPT="setup_linux.py"
-elif [ "${OS}" = "Darwin" ]; then
- if [ "${ARCH}" = "arm64" ]; then
- BLENDER_WGET_LINK='https://download.blender.org/release/Blender3.3/blender-3.3.1-macos-arm64.dmg'
- NURBS_SCRIPT="setup_macos_as.py"
- else
- BLENDER_WGET_LINK='https://download.blender.org/release/Blender3.3/blender-3.3.1-macos-x64.dmg'
- NURBS_SCRIPT="setup_macos.py"
- fi
- if [ "${ARCH}" = "arm64" ]; then
- HOMEBREW_PREFIX="/opt/homebrew/"
- else
- HOMEBREW_PREFIX="/usr/local"
- fi
- BLENDER_WGET_FILE='blender.dmg'
-
- BLENDER_VOLM='/Volumes/Blender'
- BLENDER_DIR='./Blender.app'
- BLENDER_PYTHON="${BLENDER_DIR}/Contents/Resources/3.3/python/bin/python3.10"
- BLENDER_INCLUDE="${BLENDER_DIR}/Contents/Resources/3.3/python/include/python3.10"
- BLENDER_PACKAGES="${BLENDER_DIR}/Contents/Resources/3.3/python/lib/python3.10/site-packages"
- BLENDER_ADDONS="${BLENDER_DIR}/Contents/Resources/3.3/scripts/addons"
- BLENDER_EXE="${BLENDER_DIR}/Contents/MacOS/Blender"
-
- export CC="${HOMEBREW_PREFIX}/opt/llvm/bin/clang"
- export CPATH="${HOMEBREW_PREFIX}/include:${CPATH}"
-else
- echo "Unsupported OS"
- exit -1
-fi
-REQUIREMENTS_PATH='./requirements.txt'
-PYTHON_WGET_LINK='https://www.python.org/ftp/python/3.10.2/Python-3.10.2.tgz'
-PYTHON_WGET_FILE='Python-3.10.2.tgz'
-PYTHON_DIR='Python-3.10.2'
-
-git submodule init
-git submodule update
-
-if [ ! -d "${BLENDER_DIR}" ]; then
- # Download Blender
- wget -O "${BLENDER_WGET_FILE}" "${BLENDER_WGET_LINK}"
-
- # Unzip Blender
- if [ "${OS}" = "Darwin" ]; then
- hdiutil attach "${BLENDER_WGET_FILE}"
- cp -r "${BLENDER_VOLM}/Blender.app" "${BLENDER_DIR}"
- hdiutil detach "${BLENDER_VOLM}"
- else
- tar -xf "${BLENDER_WGET_FILE}"
- mv "${BLENDER_UNTAR_DIR}" "${BLENDER_DIR}"
- fi
-
- rm "${BLENDER_WGET_FILE}"
-fi
-
-# Install llvm for MacOS
-if [ "${OS}" = "Darwin" ]; then
- brew install llvm open-mpi libomp glm glew
-fi
-
-# Install Conda dependencies
-pip install -r "${REQUIREMENTS_PATH}"
-pip install fake-bpy-module-latest
-
-if [ ! -d "${PYTHON_DIR}" ]; then
- # Install Python include file
- wget -O "${PYTHON_WGET_FILE}" "${PYTHON_WGET_LINK}"
- tar -xf "${PYTHON_WGET_FILE}"
- rm "${PYTHON_WGET_FILE}"
-fi
-cp -r "${PYTHON_DIR}/Include/"* "${BLENDER_INCLUDE}"
-
-# Install Blender dependencies
-"${BLENDER_PYTHON}" -m ensurepip
-CFLAGS="-I$(realpath ${BLENDER_INCLUDE}) ${CFLAGS}" "${BLENDER_PYTHON}" -m pip install -r "${REQUIREMENTS_PATH}"
-
-# Build terrain
-rm -rf ${BLENDER_PACKAGES}/terrain-*
-rm -rf *.egg-info
-rm -rf __pycache__
-rm -rf ./worldgen/terrain/build
-
-cd ./worldgen/terrain
-if [ -f "/usr/local/cuda/bin/nvcc" ]; then
- USE_CUDA=1 bash install_terrain.sh
-else
- USE_CUDA=0 bash install_terrain.sh
-fi
-"../../${BLENDER_PYTHON}" setup.py build_ext --inplace --force
-cd -
-
-# Build NURBS
-cd ./worldgen/assets/creatures/geometry/cpp_utils
-rm -f *.so
-rm -rf build
-"../../../../../${BLENDER_PYTHON}" "${NURBS_SCRIPT}" build_ext --inplace
-cd -
-
-if [ "$1" = "opengl" ]; then
- bash ./worldgen/tools/install/compile_opengl.sh
-fi
-
-
-# Build Flip Fluids addon
-if [ "$1" = "flip_fluids" ] || [ "$2" = "flip_fluids" ]; then
- bash ./worldgen/tools/install/compile_flip_fluids.sh
-fi
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 7e1f752b7..b06857dd4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -43,7 +43,8 @@ dependencies = [
"landlab>=2.6.0",
"pycparser",
"pyrender",
- "pandas"
+ "pandas",
+ "vnoise",
]
[project.optional-dependencies]
diff --git a/scripts/install/compile_terrain.sh b/scripts/install/compile_terrain.sh
index e02362f26..44849a4d3 100644
--- a/scripts/install/compile_terrain.sh
+++ b/scripts/install/compile_terrain.sh
@@ -134,4 +134,8 @@ gx1 -o lib/cpu/soil_machine/SoilMachine.o source/cpu/soil_machine/SoilMachine.cp
gx2 -o lib/cpu/soil_machine/SoilMachine.so lib/cpu/soil_machine/SoilMachine.o
echo "compiled lib/cpu/soil_machine/SoilMachine.so"
+cd -
+
+cd ./infinigen/OcMesher
+source install.sh
cd -
\ No newline at end of file
diff --git a/worldgen/assets/leaves/__init__.py b/worldgen/assets/leaves/__init__.py
deleted file mode 100644
index 26f5722fb..000000000
--- a/worldgen/assets/leaves/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from .leaf import LeafFactory, BerryFactory
-from .leaf_broadleaf import LeafFactoryBroadleaf
-from .leaf_ginko import LeafFactoryGinko
-from .leaf_maple import LeafFactoryMaple
-from .leaf_pine import LeafFactoryPine
-from .leaf_v2 import LeafFactoryV2
-from .leaf_wrapped import LeafFactoryWrapped
\ No newline at end of file
diff --git a/worldgen/config/performance/simple.gin b/worldgen/config/performance/simple.gin
deleted file mode 100644
index 10185747f..000000000
--- a/worldgen/config/performance/simple.gin
+++ /dev/null
@@ -1,6 +0,0 @@
-include 'config/performance/dev.gin'
-include 'config/disable_assets/no_creatures.gin'
-include 'config/performance/fast_terrain_assets.gin'
-
-run_erosion.n_iters = [1,1]
-full/render_image.num_samples = 100
\ No newline at end of file