Skip to content

Commit

Permalink
Merge pull request #18 from radiatoryang/develop
Browse files Browse the repository at this point in the history
v1.2.3 merge from develop
  • Loading branch information
radiatoryang authored Dec 12, 2021
2 parents feac4e6 + 21e57a0 commit 5b2e1fc
Show file tree
Hide file tree
Showing 92 changed files with 210 additions and 34 deletions.
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# changelog

This is an ongoing changelog for Hedera, a free open-source 3D ivy painting plug-in package for Unity. https://github.com/radiatoryang/hedera

## v1.2.3 - 12 December 2021
- started a formal changelog
- in IvyEditor, added no-alt keyboard modifier, so orbiting 3D camera in scene view doesn't cause painting (https://github.com/radiatoryang/hedera/issues/12)
- move example ivy profiles and textures to "Samples" folder, so that Package Manager users can import the data directly into their Assets (and thus modify them)
- added better adhesion -- fires raycasts to calculate nearest surface, good for mesh colliders? enable / disable with the new checkbox right below the "Start Painting" button... thanks for the PR, @alexjhetherington ! (see https://github.com/radiatoryang/hedera/pull/14 + https://github.com/radiatoryang/hedera/issues/13)


## v1.2.0 - 2 November 2020

- Merge pull request #10 from radiatoryang/develop
- corrected package.json
- fix SceneView.drawGizmos bug (see https://github.com/radiatoryang/hedera/issues/9 ), change LightmapStatic to ContributeGI for 2019.2+, moved Examples to Samples folder (for UPM), update package.json to reflect new package
- if leaf mesher doesn't find cling vector for ivy node, then re-use the last one it had
- speed up simulation tick FPS from 10 FPS to 24 FPS
- add specular highlights / glossy reflections toggles to HederaIvyFoliage example shader


## v1.1.0 - 14 August 2020

- Merge pull request #8 from radiatoryang/develop
- fix leaf positioning and rotation; leaves now face outwards based on ivy cling normal (see https://github.com/radiatoryang/hedera/issues/5)
- clamp leaf density and leaf sunlight back to 100%, instead of weird hacks
- rotated all leaf textures 90 degrees counterclockwise, for leaf alignment fix
- Merge pull request #7 from radiatoryang/develop
- trying to fix bug where tool gizmos (move, rotate, scale, etc) can get stuck hidden, if the IvyEditor doesn't have time to re-enable them
- ivy painting now ignores colliders marked as triggers
- added warning if gizmos are disabled in Unity 2019+ which breaks OnSceneGUI ... see https://github.com/radiatoryang/hedera/issues/6 (thanks id-0-ru and Roland09)
- added .asmdef


## v1.0.0 - 9 July 2019

- initial release
7 changes: 7 additions & 0 deletions CHANGELOG.md.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 57 additions & 7 deletions Editor/Scripts/IvyCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void OnEditorUpdate()
}
foreach ( var ivy in ivyB.ivyGraphs) {
if ( ivy.isGrowing ) {
GrowIvyStep(ivy, ivyB.profileAsset.ivyProfile);
GrowIvyStep(ivy, ivyB.profileAsset.ivyProfile, ivyB.useBetterAdhesion);
if ( ivy.generateMeshDuringGrowth ) {
IvyMesh.GenerateMesh(ivy, ivyB.profileAsset.ivyProfile);
}
Expand Down Expand Up @@ -266,7 +266,7 @@ public static void ForceRandomIvyBranch ( IvyGraph graph, IvyProfile ivyProfile
TryGrowIvyBranch( graph, ivyProfile, randomRoot, randomNode, randomLength);
}

public static void GrowIvyStep(IvyGraph graph, IvyProfile ivyProfile)
public static void GrowIvyStep(IvyGraph graph, IvyProfile ivyProfile, bool useBetterAdhesion)
{
// if there are no longer any live roots, then we're dead
if ( graph.isGrowing ) {
Expand Down Expand Up @@ -307,7 +307,7 @@ public static void GrowIvyStep(IvyGraph graph, IvyProfile ivyProfile)
Vector3 randomVector = (Random.onUnitSphere * 0.5f + exploreVector).normalized;

//adhesion influence to the nearest triangle = weighted sum of previous adhesion vectors
Vector3 adhesionVector = ComputeAdhesion(lastNode.p + graph.seedPos, ivyProfile);
Vector3 adhesionVector = ComputeAdhesion(lastNode.p + graph.seedPos, ivyProfile, useBetterAdhesion);
if ( adhesionVector.sqrMagnitude <= 0.01f) {
adhesionVector = lastNode.c;
}
Expand Down Expand Up @@ -458,14 +458,32 @@ static void CacheTerrainColliderStuff () {

/** compute the adhesion of scene objects at a point pos*/
static Dictionary<Mesh, Vector3[]> adhesionMeshCache = new Dictionary<Mesh, Vector3[]>();
static Vector3 ComputeAdhesion(Vector3 pos, IvyProfile ivyProfile)
static Vector3 ComputeAdhesion(Vector3 pos, IvyProfile ivyProfile, bool useBetterAdhesion)
{
Vector3 adhesionVector = Vector3.zero;

float minDistance = ivyProfile.maxAdhesionDistance;

// find nearest colliders
var nearbyColliders = Physics.OverlapSphere( pos, ivyProfile.maxAdhesionDistance, ivyProfile.collisionMask, QueryTriggerInteraction.Ignore);
//Raycast solution does not need to find colliders
if (useBetterAdhesion)
{
//Inverse resolution should be 1-360. Higher number means less rays. 20 seems to work well.
//I multiply rays by a small amount to avoid edge case but it's force of habit and probably not necessary
RaycastHit closestRaycastHit = GetClosestHitInSphere(pos, ivyProfile.maxAdhesionDistance * 1.05f, 20, ivyProfile.collisionMask, QueryTriggerInteraction.Ignore);

if (closestRaycastHit.collider != null)
{
if (closestRaycastHit.distance < minDistance)
{
adhesionVector = (closestRaycastHit.point - pos).normalized;
adhesionVector *= 1.0f - closestRaycastHit.distance / ivyProfile.maxAdhesionDistance;
return adhesionVector;
}
}
}

// find nearest colliders
var nearbyColliders = Physics.OverlapSphere( pos, ivyProfile.maxAdhesionDistance, ivyProfile.collisionMask, QueryTriggerInteraction.Ignore);

// find closest point on each collider
foreach ( var col in nearbyColliders ) {
Expand Down Expand Up @@ -538,7 +556,39 @@ static Vector3 ComputeAdhesion(Vector3 pos, IvyProfile ivyProfile)
return adhesionVector;
}

public static void RegenerateDebugLines( Vector3 seedPos, IvyRoot root) {
//https://answers.unity.com/questions/747840/what-is-the-best-way-to-send-raycasts-out-in-a-sph.html
public static RaycastHit GetClosestHitInSphere(Vector3 origin, float maxDistance, float inverseResolution, LayerMask raycastMask, QueryTriggerInteraction useTriggers)
{
Ray ray = new Ray();
ray.origin = origin;
Vector3 direction = Vector3.right;
int steps = Mathf.FloorToInt(360f / inverseResolution);
Quaternion xRotation = Quaternion.Euler(Vector3.right * inverseResolution);
Quaternion yRotation = Quaternion.Euler(Vector3.up * inverseResolution);
Quaternion zRotation = Quaternion.Euler(Vector3.forward * inverseResolution);

RaycastHit closest = new RaycastHit();

for (int x = 0; x < steps / 2; x++)
{
direction = zRotation * direction;
for (int y = 0; y < steps; y++)
{
direction = xRotation * direction;
ray.direction = direction;
RaycastHit candidate;
Physics.Raycast(ray, out candidate, maxDistance, raycastMask, useTriggers);
if (candidate.collider != null && (closest.collider == null || closest.distance > candidate.distance))
{
closest = candidate;
}
}
}

return closest;
}

public static void RegenerateDebugLines( Vector3 seedPos, IvyRoot root) {
root.debugLineSegmentsArray = new Vector3[(root.nodes.Count-1)*2];

var cache = IvyRoot.GetMeshCacheFor(root);
Expand Down
8 changes: 6 additions & 2 deletions Editor/Scripts/IvyEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ private void OnSceneGUI()

if ((current.type == EventType.MouseDrag || current.type == EventType.MouseDown) )
{
if (current.button == 0 && (lastPos == Vector3.zero || CanDraw()) && !current.shift)
// 11 Dec 2021: add no-alt keyboard modifier, so orbiting camera doesn't cause painting (https://github.com/radiatoryang/hedera/issues/12)
if (current.button == 0 && (lastPos == Vector3.zero || CanDraw()) && !current.shift && !current.alt)
{
mouseDirection = Vector3.MoveTowards( mouseDirection, (mousePos - lastPos).normalized, System.Convert.ToSingle(deltaTime) );
lastPos = mousePos;
Expand Down Expand Up @@ -298,9 +299,12 @@ public override void OnInspectorGUI()
content = new GUIContent( " Enable Growth Sim AI", "If disabled, then you can just paint ivy without simulation or AI, which is useful when you want small strokes or full control." );
ivyBehavior.enableGrowthSim = EditorGUILayout.ToggleLeft(content, ivyBehavior.enableGrowthSim);

content = new GUIContent( " Make Mesh During Painting / Growth", "Generate 3D ivy mesh during painting and growth. Very cool, but very processing intensive. If your computer gets very slow while painting, then disable this." );
content = new GUIContent( " Make Mesh During Painting / Growth", "Generate 3D ivy mesh during painting and growth. Very cool, but can potentially be very processing intensive. If your computer gets very slow while painting, then disable this." );
ivyBehavior.generateMeshDuringGrowth = EditorGUILayout.ToggleLeft(content, ivyBehavior.generateMeshDuringGrowth);

content = new GUIContent( " Do More Adhesion Calculations", "If enabled, fires additional raycasts near painting cursor for better painting on concave surfaces and/or mesh colliders with sparse topology. Can potentially be processing intensive. If your computer gets very slow while painting, then disable this.");
ivyBehavior.useBetterAdhesion = EditorGUILayout.ToggleLeft(content, ivyBehavior.useBetterAdhesion);

int visibleIvy = ivyBehavior.ivyGraphs.Where( ivy => ivy.isVisible ).Count();
GUI.enabled = isInARealScene && visibleIvy > 0;
EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
Expand Down
File renamed without changes.
7 changes: 7 additions & 0 deletions LICENSE.md.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 0 additions & 8 deletions LICENSE.txt.meta

This file was deleted.

5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
- curious about vert count / polycount? [download sample ivy .OBJ (right-click Save As)](https://raw.githubusercontent.com/radiatoryang/hedera/master/Example/ExampleIvyMeshExport.obj)
- merge multiple ivy meshes to save draw calls, or just let static batching work
- randomize vertex colors for subtle color variation, auto-unwrap ivy UV2s for lightmapping
- store ivy meshes directly in your project, or export to .OBJ
- store ivy meshes directly in your project, or export to .OBJ (note: OBJ file format doesn't support vertex color nor UV2)
- 25+ different ivy settings to tweak for your own presets! guide and user documentation is on the [Wiki](https://github.com/radiatoryang/hedera/wiki)
- tested on Unity 5.6.7f1 and 2019.1.8 (but probably works ok on other Unity versions too)
- tested on Unity 5.6.7f1 and 2019.1.8 and 2021.2.0f1 (but probably works ok on other Unity versions too)
- no HDRP or URP shaders included yet, maybe in 2022? lol

### usage
- download the latest .unitypackage from [Releases](https://github.com/radiatoryang/hedera/releases)
Expand Down
Binary file removed Runtime/Materials/IvyBranchWood.mat
Binary file not shown.
2 changes: 1 addition & 1 deletion Runtime/Scripts/IvyBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class IvyBehavior : MonoBehaviour {
// strip out ivy generator code upon compile
#if UNITY_EDITOR
public List<IvyGraph> ivyGraphs = new List<IvyGraph>();
public bool generateMeshDuringGrowth = true, enableGrowthSim = true;
public bool generateMeshDuringGrowth = true, enableGrowthSim = true, useBetterAdhesion = true;
public bool showProfileFoldout;
public IvyProfileAsset profileAsset;
public Color debugColor = Color.yellow;
Expand Down
9 changes: 0 additions & 9 deletions Samples.meta

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
79 changes: 79 additions & 0 deletions Samples~/ExampleIvyScene/Materials/IvyBranchWood.mat
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: IvyBranchWood
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords: _METALLICGLOSSMAP _NORMALMAP
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 2800000, guid: d0bf026e9ba99ec41b4d607aa3cf4680, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 6137995bbeee3e04a9447753e6d3a579, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 2800000, guid: ee75804f2ab74a24fb1fc6cd6bc83a5c, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BumpScale: 3
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 0.2
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 0.5
- _Parallax: 0.045
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.82444817, g: 0.9150943, b: 0.8248356, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes
18 changes: 13 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
{
"name": "com.radiatoryang.hedera",
"displayName": "Hedera",
"description": "Paint 3D ivy in the editor and simulate ivy growth patterns in your scene.",
"version": "1.2.0",
"description": "Paint 3D ivy in the editor and simulate ivy growth. \n\n IMPORTANT: in Package Manager, click 'Samples' below to import default ivy profiles and textures into your project's Assets folder.",
"version": "1.2.3",
"unity": "2018.3",
"license": "GPL 2.0",
"license": "GPL-2.0-or-later",
"documentationUrl": "https://github.com/radiatoryang/hedera/wiki",
"author": {
"name": "Robert Yang",
"email": "[email protected]",
"url": "https://debacle.us"
},
"keywords": [
"ivy", "foliage", "environment", "paint"
"ivy", "foliage", "environment", "paint", "art", "3d", "world", "env"
],
"dependencies": {

}
},
"samples": [
{
"displayName": "Example Ivy Profiles and Textures",
"description": "Sample ivy scene + ivy profiles + textures you can use.",
"path": "Samples~/ExampleIvyScene"
}
]

}

0 comments on commit 5b2e1fc

Please sign in to comment.