Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #21

Merged
merged 12 commits into from
Feb 10, 2023
Merged

Dev #21

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,32 @@ craft your terrain. It is also the main interface for setting up the terrain and
#### TaleSpire_Object
This node is used to import a TaleSpire Tile, Prop or Slab for use in the system. It has controls over the
placement of these objects in regard to how they interact with other nodes like TaleSpire_Tiler and TaleSpire_Scatter.
You can also export directly from this node, in case you just want to rotate or replace assets.
#### TaleSpire_Biome
This node defines a Biome which controls what TaleSpire Tiles and Props get put on to the terrain. It has
subnetworks within for defining sets of objects, rules for placing Tiles and rules for placing/scattering Props.
#### TaleSpire_Tiler
This node is used within the TaleSpire_Biome node to define what areas specific sets of tiles are placed on the terrain.
#### TaleSpire_Scatter
This node is used within the TaleSpire_Biome node to scatter props on to a terrain based on rules and masks.
This node is used to scatter props on to a heightfield terrain based on rules and masks. It can work inside a
TaleSpire_Biome node or externally if used with the new TaleSpire_Object_Set node.

### NEW Nodes!
The following nodes are new as of v0.19.0-alpha and are considered Work In Progress.
Some features may be missing or broken.
#### TaleSpire_Copy
This node allows you to place assets on specific points fed in to the 1st input. It can work
inside or outside a biome. The 2nd input can be used to designate which objects to place on the
points, as defined in a TaleSpire_Object_Set node.
#### TaleSpire_Object_Set
This node is a container for TaleSpire_Object nodes, it works similar to the objects network
in the TaleSpire_Biome node. This allows you to define sets of objects to use in nodes like
TaleSpire_Scatter and TaleSpire_Copy allowing those nodes to work external from a Biome if desired.
#### TaleSpire_Export
This node can take the data from TaleSpire_Scatter and TaleSpire_Copy nodes and export them directly
to a slab or multi-slab without needing to set up a terrain.
Its feature set is currently limited but will eventually support all the features of the terrain nodes export.


## Installation
The installation instructions are available on the wiki.
Expand Down
Binary file modified otls/OBJ_TaleSpire_Biome.hdanc
Binary file not shown.
Binary file modified otls/OBJ_TaleSpire_Object.hdanc
Binary file not shown.
Binary file modified otls/OBJ_TaleSpire_Terrain.hdanc
Binary file not shown.
Binary file added otls/SOP_TaleSpire_Copy.hdanc
Binary file not shown.
Binary file added otls/SOP_TaleSpire_Export.hdanc
Binary file not shown.
Binary file added otls/SOP_TaleSpire_Object_Set.hdanc
Binary file not shown.
Binary file modified otls/SOP_TaleSpire_Scatter.hdanc
Binary file not shown.
Binary file modified otls/SOP_TaleSpire_Tiler.hdanc
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gAAAAABj4_yUxXHdsPpf5auK85sD9qxzQ43rfPulPMtt3kO6nUzsWGtlZLXH7NFaPqt6ssiepAphRihOVjSPei0PYI50tBSs1l_DIh_ak4AudzVIE6N3pNfKMK3bnNpBBLDKY29WaLzrnDWPxZxSbbMZm0z3nKgMSbPLclaqpCw99ZQdXZn2EtxUa_S5PAC5rzZpHTko-nSXU78AARkWERDVtYifBl7OjcOOdk2eZj_AfO4mdhXAODYxA1PkblazkbLobvtbR7WiqwP5VKPUPxzNx7gc2n7mYray6qOPYimNRO52LbDtmV8XdiqsBvS8Xmsb0B9U11SYtct5KdDbB3_20qWMomBVUTMGzIuUDEBC6zVd_4bDTusQ7LeVPsvPRjEV0ieVJf-taEI-kF9JqR3OF4pdjhbhpxWQFvaevlvGtKol_bkAPdh0MOoW1n_BroWeuEenEdCxgyQ-rk3RyPy2NWTKeBVYAuATzls4mPkXAHGXWOmLfkd8g8tGHjXsd_JazoidgDrWGPpz7G1ohmqtX38vKAloCcJ-_lanyyHNazrxEsW7DEgIdrat1UIEpcRsLdxSAKdgrHAFDIdfk4N5pS0ud4DvZyKSv6V9yqO0yrNJGVwBIut2zLk6BRa21lepf4RuajsxzCuvLpsfPTFiQiX0hmsqxqslXiY52cRKW5O6jF1M9pI0LUxJAe_vLr7CT3M9l4ULZT6tBYv_P4oaQXEIAm3CyHHlQwe6AWSga6Ar3e3h4mKYV1EeLlJrUtwEeiCFKZVXFD0yGcuX-ddspdcrDRcjpjodLG3iSxeg7XPl_8HXtMDiRFEiL6CBzJIahuRttDfAPKPHyCIvwCWeuVpUx5tcNa-0sFCXRNGtSbsg5K5P06A23c8S8c5NVUQ3dTc91k-HDLQnevWnjIgswU9XGjqnFDO93-Rxgl_ymQmqwe5tMCLJwRg968dYknIUhHcprQzYXl15E_gxrkZFlM9DXtV50lqj2zsTPN2R2Zh3_mJNY076GXG9-szp7R_J_Kbr4SNsBmq5tNWqDM_XkyMKjXcBTg==
5 changes: 5 additions & 0 deletions scripts/python/htg/nodes/OBJ_TaleSpire_Object.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,8 @@ def decode_slab(node=None):

slab_points_node = hou.node(node.path() + '/TS_Object/slab_points')
slab_points_node.cook(force=True)


def copy_slab(node=None):
export_node = hou.node(node.path()+'/TS_Object/Export')
export_node.parm('copy_slab').pressButton()
93 changes: 93 additions & 0 deletions scripts/python/htg/nodes/SOP_TaleSpire_Export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Most of the code in here is a duplicate of what is in OBJ_TaleSpire_Terrain as the features are being moved.
# Once this node is complete the redundant functions will be removed.
import json
import htg.utils
import talespire.encode as ts_encode
import hou


def set_slab_range(node=None):
si1_parm = node.parm('slabindex1')
si2_parm = node.parm('slabindex2')
slabs_node = hou.node(node.path()+'/NUM_SLABS')
num_points = len(slabs_node.geometry().points())
si1_parm.set(1)
si2_parm.deleteAllKeyframes()
si2_parm.set(num_points)


def copy_slab_from_node(node=None):
json_data = get_js(node)
slab = ts_encode.encode(json_data)
htg.utils.copy_to_clipboard(slab.strip("b'`"))


def get_js(geonode=None):
geo = geonode.geometry()
uuid_data = {}
for point in geo.points():
uuid = point.attribValue('ts_uuid')
x = point.attribValue('ts_x')
y = point.attribValue('ts_y')
z = point.attribValue('ts_z')
degree = point.attribValue('ts_degree')
if uuid not in uuid_data:
uuid_data[uuid] = []
uuid_data[uuid].append({'x': x, 'y': y, 'z': z, 'degree': degree})

data = {'unique_asset_count': len(uuid_data.keys()), 'asset_data': []}
for auuid in uuid_data.keys():
asset_data = {
'uuid': auuid,
'instance_count': len(uuid_data[auuid]),
'instances': uuid_data[auuid]
}
data['asset_data'].append(asset_data)

json_dump = json.dumps(data)
return data


def get_slab_with_pos(node=None):
offset_node = hou.node(node.path() + '/First_Tile')
geo = offset_node.geometry()
point = geo.point(0)
try:
pos = tuple(point.position())
json_data = get_js(node)
slab = ts_encode.encode(json_data)
out = {
"position": {"x": pos[0], "y": pos[1], "z": -pos[2]},
"code": slab.strip("b'`")
}
except AttributeError:
out = None

return out


def encode_slabs(node=None):
num_assets = 1 # Disabled while developing
do_export = True
if num_assets >= 1000000:
button_result = hou.ui.displayMessage('Warning: This map contains more that 1 Million assets.\n'
'TaleSpire will likely crash.\n'
'Are you sure you want to do this?',
buttons=('OK', 'Cancel'))
if button_result != 0:
do_export = False

if do_export:
grid_node = hou.node(node.path() + '/SLAB_GRID')
num_slabs = len(grid_node.geometry().prims())
slab_index_parm = node.parm('slabindex1')
og_index = slab_index_parm.eval()

slab_json = []
for i in range(1, num_slabs + 1):
slab_index_parm.set(i)
slab_pos = get_slab_with_pos(node)
if slab_pos is not None:
slab_json.append(slab_pos)
htg.utils.copy_to_clipboard(json.dumps(slab_json))
slab_index_parm.set(og_index)
29 changes: 29 additions & 0 deletions scripts/python/htg/nodes/SOP_TaleSpire_Object_Set.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import hou
import htg.utils
import htg.nodes.common as ts_common


def refresh_objects(node=None):
cook_paths = ['/object_set_points']

for cook_path in cook_paths:
cook_node = hou.node(node.path()+cook_path)
cook_node.cook(force=True)


def edit_objects(node=None):
dest_node = hou.node(node.path() + '/object_sets')
htg.utils.set_network(node, dest_node)


def load_default_networks(node=None):
networks = {
'object_sets': 'TaleSpire_Object_Set_object_sets_contents.net'
}
ts_common.load_networks(node, networks)


def save_object_sets_network(node=None):
file_name = 'TaleSpire_Object_Set_object_sets_contents.net'
net_node = hou.node(node.path() + '/object_sets')
ts_common.save_network(net_node, file_name, mode='node')