1
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dc35b67709ef0c40b43db9e53709643
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa9a62b0cdcbde94bbc2ef579b40b66e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,290 @@
|
||||
#if GRIFFIN
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using Pinwheel.Griffin.Rendering;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
//[CreateAssetMenu(menuName = "Griffin/Editor Settings")]
|
||||
public partial class GEditorSettings : ScriptableObject, ISerializationCallbackReceiver
|
||||
{
|
||||
private static GEditorSettings instance;
|
||||
public static GEditorSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = Resources.Load<GEditorSettings>("PolarisEditorSettings");
|
||||
if (instance == null)
|
||||
{
|
||||
instance = ScriptableObject.CreateInstance<GEditorSettings>();
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public GeneralSettings general = new GeneralSettings();
|
||||
public LivePreviewSettings livePreview = new LivePreviewSettings();
|
||||
public PaintToolsSettings paintTools = new PaintToolsSettings();
|
||||
public SplineToolsSettings splineTools = new SplineToolsSettings();
|
||||
public BillboardToolsSettings billboardTools = new BillboardToolsSettings();
|
||||
public StampToolsSettings stampTools = new StampToolsSettings();
|
||||
public WizardToolsSettings wizardTools = new WizardToolsSettings();
|
||||
public RenderPipelinesSettings renderPipelines = new RenderPipelinesSettings();
|
||||
public TopographicSettings topographic = new TopographicSettings();
|
||||
public ErosionToolsSettings erosionTools = new ErosionToolsSettings();
|
||||
public LayerSettings layers = new LayerSettings();
|
||||
public DemoAssetSettings demoAssets = new DemoAssetSettings();
|
||||
|
||||
#region Serialization Callbacks
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
SetupLayersAsync();
|
||||
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnPlayModeStateChanged(PlayModeStateChange obj)
|
||||
{
|
||||
//Some hack to clean up billboard meshes
|
||||
GBillboardUtilities.CleanUp();
|
||||
}
|
||||
#endif
|
||||
|
||||
private async void SetupLayersAsync()
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
GLayerInitializer.SetupRaycastLayer();
|
||||
GLayerInitializer.SetupSplineLayer();
|
||||
}
|
||||
}
|
||||
|
||||
public partial class GEditorSettings : ScriptableObject
|
||||
{
|
||||
[System.Serializable]
|
||||
public class GeneralSettings
|
||||
{
|
||||
public bool enableAnalytics = true;
|
||||
public bool enableAffiliateLinks = true;
|
||||
public bool debugMode = false;
|
||||
public bool showGeometryChunkInHierarchy = true;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class LivePreviewSettings
|
||||
{
|
||||
public Mesh[] triangleMeshes;
|
||||
public Mesh[] wireframeMeshes;
|
||||
|
||||
public Mesh GetTriangleMesh(int detail)
|
||||
{
|
||||
if (triangleMeshes == null || triangleMeshes.Length == 0)
|
||||
return null;
|
||||
detail = Mathf.Clamp(detail, 0, triangleMeshes.Length - 1);
|
||||
return triangleMeshes[detail];
|
||||
}
|
||||
|
||||
public Mesh GetWireframeMesh(int detail)
|
||||
{
|
||||
if (wireframeMeshes == null || wireframeMeshes.Length == 0)
|
||||
return null;
|
||||
detail = Mathf.Clamp(detail, 0, wireframeMeshes.Length - 1);
|
||||
return wireframeMeshes[detail];
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class PaintToolsSettings
|
||||
{
|
||||
public bool enableHistory;
|
||||
public bool enableLivePreview;
|
||||
public bool useSimpleCursor;
|
||||
public Color normalActionCursorColor;
|
||||
public Color negativeActionCursorColor;
|
||||
public Color alternativeActionCursorColor;
|
||||
public float radiusStep;
|
||||
public float rotationStep;
|
||||
public float opacityStep;
|
||||
public int densityStep;
|
||||
public bool useMultiSplatsSelector;
|
||||
public bool showTerrainMask;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class SplineToolsSettings
|
||||
{
|
||||
public Color anchorColor;
|
||||
public Color segmentColor;
|
||||
public Color meshColor;
|
||||
public Color selectedElementColor;
|
||||
public Color positiveHighlightColor;
|
||||
public Color negativeHighlightColor;
|
||||
public bool autoTangent;
|
||||
public LayerMask raycastLayers;
|
||||
public bool showTransformGizmos;
|
||||
public LivePreviewToggle livePreview;
|
||||
|
||||
[System.Serializable]
|
||||
public struct LivePreviewToggle
|
||||
{
|
||||
public bool rampMaker;
|
||||
public bool pathPainter;
|
||||
public bool foliageSpawner;
|
||||
public bool foliageRemover;
|
||||
public bool objectSpawner;
|
||||
public bool objectRemover;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class BillboardToolsSettings
|
||||
{
|
||||
public Material atlasMaterial;
|
||||
public Material normalMaterial;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class StampToolsSettings
|
||||
{
|
||||
public Color visualizeColor;
|
||||
public float minRotation;
|
||||
public float maxRotation;
|
||||
public Vector3 minScale;
|
||||
public Vector3 maxScale;
|
||||
public bool showLivePreview;
|
||||
public bool showBounds;
|
||||
public bool showTerrainMask;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class WizardToolsSettings
|
||||
{
|
||||
public GLightingModel lightingModel;
|
||||
public GTexturingModel texturingModel;
|
||||
public GSplatsModel splatsModel;
|
||||
public Vector3 origin;
|
||||
public Vector3 tileSize;
|
||||
public int tileCountX;
|
||||
public int tileCountZ;
|
||||
public int groupId;
|
||||
public string terrainNamePrefix;
|
||||
public string dataDirectory;
|
||||
[System.NonSerialized]
|
||||
public GStylizedTerrain setShaderTerrain;
|
||||
public int setShaderGroupId;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class RenderPipelinesSettings
|
||||
{
|
||||
public Object universalRenderPipelinePackage;
|
||||
|
||||
public string GetUrpPackagePath()
|
||||
{
|
||||
if (universalRenderPipelinePackage == null)
|
||||
return null;
|
||||
string path = AssetDatabase.GetAssetPath(universalRenderPipelinePackage);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class TopographicSettings
|
||||
{
|
||||
public bool enable;
|
||||
public Material topographicMaterial;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ErosionToolsSettings
|
||||
{
|
||||
public enum LivePreviewMode
|
||||
{
|
||||
Geometry, Texture, Off
|
||||
}
|
||||
|
||||
public enum DataViewSelection
|
||||
{
|
||||
SimulationData, SimulationMask, ErosionMap
|
||||
}
|
||||
|
||||
public enum DataViewChannel
|
||||
{
|
||||
R, G, B, A
|
||||
}
|
||||
|
||||
public LivePreviewMode livePreviewMode;
|
||||
public DataViewSelection dataView;
|
||||
public float dataViewScale;
|
||||
public DataViewChannel dataViewChannel;
|
||||
public bool showTerrainMask;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class LayerSettings
|
||||
{
|
||||
public int raycastLayerIndex;
|
||||
public int splineLayerIndex;
|
||||
|
||||
public bool SetupLayer(int index, string layer)
|
||||
{
|
||||
bool success = false;
|
||||
Object tagManager = AssetDatabase.LoadAssetAtPath<Object>("ProjectSettings/TagManager.asset");
|
||||
SerializedObject so = new SerializedObject(tagManager);
|
||||
SerializedProperty layers = so.FindProperty("layers");
|
||||
for (int i = 8; i < 32; ++i)
|
||||
{
|
||||
SerializedProperty li = layers.GetArrayElementAtIndex(i);
|
||||
if (li.stringValue.Equals(layer) && i != index)
|
||||
{
|
||||
li.stringValue = string.Empty;
|
||||
}
|
||||
if (!li.stringValue.Equals(layer) && i == index)
|
||||
{
|
||||
li.stringValue = layer;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
so.ApplyModifiedProperties();
|
||||
so.Dispose();
|
||||
EditorUtility.SetDirty(tagManager);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class DemoAssetSettings
|
||||
{
|
||||
public Material[] demoMaterials;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5f45ad0538dc0d44b0b071a0f813b34
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 18e3e435c7dff9f4a8b77fcd02e98fd2, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,25 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
public class GGeometryGenerationContext
|
||||
{
|
||||
private Color[] heightMapData;
|
||||
private int heightMapResolution;
|
||||
private Color[] subDivMapData;
|
||||
private int subDivMapResolution;
|
||||
|
||||
public GGeometryGenerationContext(GStylizedTerrain terrain, GTerrainData data)
|
||||
{
|
||||
subDivMapData = data.Geometry.Internal_SubDivisionMap.GetPixels();
|
||||
subDivMapResolution = GCommon.SUB_DIV_MAP_RESOLUTION;
|
||||
}
|
||||
|
||||
public Color GetSubdivData(Vector2 uv)
|
||||
{
|
||||
return GUtilities.GetColorBilinear(subDivMapData, subDivMapResolution, subDivMapResolution, uv);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 048c6de9bdbf90449b521a95d0bdd8c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,195 @@
|
||||
#if GRIFFIN
|
||||
using Pinwheel.Griffin.TextureTool;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[System.Serializable]
|
||||
public class GHeightMapFilter : MonoBehaviour
|
||||
{
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
private GStylizedTerrain terrain;
|
||||
public GStylizedTerrain Terrain
|
||||
{
|
||||
get
|
||||
{
|
||||
return terrain;
|
||||
}
|
||||
private set
|
||||
{
|
||||
terrain = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool useBlur;
|
||||
public bool UseBlur
|
||||
{
|
||||
get
|
||||
{
|
||||
return useBlur;
|
||||
}
|
||||
set
|
||||
{
|
||||
useBlur = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int blurRadius;
|
||||
public int BlurRadius
|
||||
{
|
||||
get
|
||||
{
|
||||
return blurRadius;
|
||||
}
|
||||
set
|
||||
{
|
||||
blurRadius = Mathf.Clamp(value, 1, 5);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool useStep;
|
||||
public bool UseStep
|
||||
{
|
||||
get
|
||||
{
|
||||
return useStep;
|
||||
}
|
||||
set
|
||||
{
|
||||
useStep = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int stepCount;
|
||||
public int StepCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return stepCount;
|
||||
}
|
||||
set
|
||||
{
|
||||
stepCount = Mathf.Clamp(value, 1, 1024);
|
||||
}
|
||||
}
|
||||
|
||||
private RenderTexture heightMapBackup;
|
||||
private RenderTexture rt;
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
UseBlur = false;
|
||||
BlurRadius = 1;
|
||||
UseStep = false;
|
||||
StepCount = 25;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Terrain = GetComponent<GStylizedTerrain>();
|
||||
if (Terrain != null)
|
||||
{
|
||||
Terrain.PreProcessHeightMap += OnPreProcessHeightMap;
|
||||
Terrain.PostProcessHeightMap += OnPostProcessHeightMap;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (Terrain != null)
|
||||
{
|
||||
Terrain.PreProcessHeightMap -= OnPreProcessHeightMap;
|
||||
Terrain.PostProcessHeightMap -= OnPostProcessHeightMap;
|
||||
}
|
||||
if (heightMapBackup != null)
|
||||
{
|
||||
GUtilities.DestroyObject(heightMapBackup);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPreProcessHeightMap(Texture2D heightMap)
|
||||
{
|
||||
if (!UseBlur && !UseStep)
|
||||
return;
|
||||
|
||||
InitRtSize(heightMap, ref heightMapBackup);
|
||||
CopyTo(heightMap, heightMapBackup);
|
||||
ApplyFilters(heightMap);
|
||||
}
|
||||
|
||||
private void OnPostProcessHeightMap(Texture2D heightMap)
|
||||
{
|
||||
if (!UseBlur && !UseStep)
|
||||
return;
|
||||
|
||||
RestoreHeightMap(heightMap);
|
||||
}
|
||||
|
||||
private void CopyTo(Texture2D heightMap, RenderTexture targetRt)
|
||||
{
|
||||
GCommon.CopyToRT(heightMap, targetRt);
|
||||
}
|
||||
|
||||
private void CopyTo(RenderTexture rt, Texture2D targetTex)
|
||||
{
|
||||
GCommon.CopyFromRT(targetTex, rt);
|
||||
targetTex.Apply();
|
||||
}
|
||||
|
||||
private void InitRtSize(Texture src, ref RenderTexture targetRt)
|
||||
{
|
||||
if (targetRt == null)
|
||||
{
|
||||
targetRt = new RenderTexture(src.width, src.height, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
||||
}
|
||||
if (targetRt.width != src.width ||
|
||||
targetRt.height != src.height)
|
||||
{
|
||||
targetRt.Release();
|
||||
GUtilities.DestroyObject(targetRt);
|
||||
targetRt = new RenderTexture(src.width, src.height, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreHeightMap(Texture2D heightMap)
|
||||
{
|
||||
if (heightMapBackup != null && heightMapBackup.IsCreated())
|
||||
{
|
||||
GCommon.CopyFromRT(heightMap, heightMapBackup);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyFilters(Texture2D heightMap)
|
||||
{
|
||||
InitRtSize(heightMap, ref rt);
|
||||
CopyTo(heightMap, rt);
|
||||
GTextureFilterParams param = new GTextureFilterParams();
|
||||
if (UseBlur)
|
||||
{
|
||||
GBlurParams blurParam = GBlurParams.Create();
|
||||
blurParam.Radius = BlurRadius;
|
||||
param.Blur = blurParam;
|
||||
|
||||
GBlurFilter blurFilter = new GBlurFilter();
|
||||
blurFilter.Apply(rt, param);
|
||||
}
|
||||
if (UseStep)
|
||||
{
|
||||
GStepParams stepParam = GStepParams.Create();
|
||||
stepParam.Count = StepCount;
|
||||
param.Step = stepParam;
|
||||
|
||||
GStepFilter stepFilter = new GStepFilter();
|
||||
stepFilter.Apply(rt, param);
|
||||
}
|
||||
CopyTo(rt, heightMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a08652ec214402438899dc29d8a96cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,59 @@
|
||||
#if GRIFFIN
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
public class GInteractiveGrassAgent : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private float radius;
|
||||
public float Radius
|
||||
{
|
||||
get
|
||||
{
|
||||
return radius;
|
||||
}
|
||||
set
|
||||
{
|
||||
radius = Mathf.Max(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
IEnumerator<GStylizedTerrain> terrains = GStylizedTerrain.ActiveTerrains.GetEnumerator();
|
||||
while (terrains.MoveNext())
|
||||
{
|
||||
GStylizedTerrain t = terrains.Current;
|
||||
if (t.TerrainData == null)
|
||||
continue;
|
||||
if (t.TerrainData.Foliage.EnableInteractiveGrass == false)
|
||||
continue;
|
||||
DrawOnTerrain(t);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawOnTerrain(GStylizedTerrain t)
|
||||
{
|
||||
Vector3[] worldCorners = GCommon.GetBrushQuadCorners(transform.position, Radius, 0);
|
||||
Vector2[] uvCorners = new Vector2[worldCorners.Length];
|
||||
for (int i = 0; i < uvCorners.Length; ++i)
|
||||
{
|
||||
uvCorners[i] = t.WorldPointToUV(worldCorners[i]);
|
||||
}
|
||||
|
||||
Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
|
||||
if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
|
||||
return;
|
||||
|
||||
RenderTexture rt = t.GetGrassVectorFieldRenderTexture();
|
||||
Material mat = GInternalMaterials.InteractiveGrassVectorFieldMaterial;
|
||||
mat.SetFloat("_Opacity", t.TerrainData.Foliage.BendSensitive);
|
||||
int pass = 0;
|
||||
GCommon.DrawQuad(rt, uvCorners, mat, pass);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e54b1d91fbf090499aa1e288f351c90
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,313 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
//[CreateAssetMenu(menuName = "Griffin/Runtime Settings")]
|
||||
public partial class GRuntimeSettings : ScriptableObject
|
||||
{
|
||||
private static GRuntimeSettings instance;
|
||||
public static GRuntimeSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = Resources.Load<GRuntimeSettings>("PolarisRuntimeSettings");
|
||||
if (instance == null)
|
||||
{
|
||||
instance = ScriptableObject.CreateInstance<GRuntimeSettings>();
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public GeometryDefaultSettings geometryDefault = new GeometryDefaultSettings();
|
||||
public ShadingDefaultSettings shadingDefault = new ShadingDefaultSettings();
|
||||
public RenderingDefaultSettings renderingDefault = new RenderingDefaultSettings();
|
||||
public FoliageDefaultSettings foliageDefault = new FoliageDefaultSettings();
|
||||
public MaskDefaultSettings maskDefault = new MaskDefaultSettings();
|
||||
public GeometryGenerationSettings geometryGeneration = new GeometryGenerationSettings();
|
||||
public TerrainRenderingSettings terrainRendering = new TerrainRenderingSettings();
|
||||
public FoliageRenderingSettings foliageRendering = new FoliageRenderingSettings();
|
||||
public InternalShaderSettings internalShaders = new InternalShaderSettings();
|
||||
public DefaultTexturesSettings defaultTextures = new DefaultTexturesSettings();
|
||||
|
||||
public bool isEditingGeometry;
|
||||
public bool isEditingFoliage;
|
||||
}
|
||||
|
||||
public partial class GRuntimeSettings : ScriptableObject
|
||||
{
|
||||
[System.Serializable]
|
||||
public class GeometryDefaultSettings
|
||||
{
|
||||
public float width;
|
||||
public float height;
|
||||
public float length;
|
||||
public int heightMapResolution;
|
||||
public int meshBaseResolution;
|
||||
public int meshResolution;
|
||||
public int chunkGridSize;
|
||||
public int lodCount;
|
||||
public int displacementSeed;
|
||||
public float displacementStrength;
|
||||
public GAlbedoToVertexColorMode albedoToVertexColorMode;
|
||||
public GGeometry.GStorageMode storageMode;
|
||||
public bool allowTimeSlicedGeneration;
|
||||
public bool smoothNormal;
|
||||
public bool useSmoothNormalMask;
|
||||
public bool mergeUv;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ShadingDefaultSettings
|
||||
{
|
||||
public int albedoMapResolution;
|
||||
public int metallicMapResolution;
|
||||
public string albedoMapPropertyName;
|
||||
public string metallicMapPropertyName;
|
||||
public Gradient colorByHeight;
|
||||
public Gradient colorByNormal;
|
||||
public AnimationCurve colorBlendCurve;
|
||||
public string colorByHeightPropertyName;
|
||||
public string colorByNormalPropertyName;
|
||||
public string colorBlendPropertyName;
|
||||
public string dimensionPropertyName;
|
||||
public int splatControlResolution;
|
||||
public string splatControlMapPropertyName;
|
||||
public string splatMapPropertyName;
|
||||
public string splatNormalPropertyName;
|
||||
public string splatMetallicPropertyName;
|
||||
public string splatSmoothnessPropertyName;
|
||||
//public GSplatPrototypeGroup splats;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class RenderingDefaultSettings
|
||||
{
|
||||
public bool terrainCastShadow;
|
||||
public bool terrainReceiveShadow;
|
||||
|
||||
public bool drawTrees;
|
||||
public bool enableInstancing;
|
||||
public float billboardStart;
|
||||
public float treeDistance;
|
||||
public float treeCullBias;
|
||||
|
||||
public bool drawGrasses;
|
||||
public float grassDistance;
|
||||
public int grassCellToProcessPerFrame;
|
||||
public float grassFadeStart;
|
||||
public float grassCullBias;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class FoliageDefaultSettings
|
||||
{
|
||||
public GSnapMode treeSnapMode;
|
||||
public LayerMask treeSnapLayerMask;
|
||||
public GSnapMode grassSnapMode;
|
||||
public LayerMask grassSnapLayerMask;
|
||||
public int patchGridSize;
|
||||
public bool enableInteractiveGrass;
|
||||
public int vectorFieldMapResolution;
|
||||
public float bendSensitive;
|
||||
public float restoreSensitive;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class MaskDefaultSettings
|
||||
{
|
||||
public int maskMapResolution;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class GeometryGenerationSettings
|
||||
{
|
||||
public int triangulateIteration;
|
||||
public AnimationCurve lodTransition = AnimationCurve.EaseInOut(0, 1, 1, 0);
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class TerrainRenderingSettings
|
||||
{
|
||||
[System.Serializable]
|
||||
public class TerrainMaterialTemplate
|
||||
{
|
||||
public GLightingModel lightingModel;
|
||||
public GTexturingModel texturingModel;
|
||||
public GSplatsModel splatsModel;
|
||||
public Material material;
|
||||
}
|
||||
|
||||
public List<TerrainMaterialTemplate> builtinRpMaterials;
|
||||
public List<TerrainMaterialTemplate> universalRpMaterials;
|
||||
|
||||
public bool FindMaterialTemplate(Shader shader, GRenderPipelineType pipeline, out TerrainMaterialTemplate template)
|
||||
{
|
||||
template = default;
|
||||
List<TerrainMaterialTemplate> templateList =
|
||||
pipeline == GRenderPipelineType.Builtin ? builtinRpMaterials :
|
||||
pipeline == GRenderPipelineType.Universal ? universalRpMaterials :
|
||||
null;
|
||||
if (templateList == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = templateList.FindIndex((t) =>
|
||||
{
|
||||
return t.material != null && t.material.shader == shader;
|
||||
});
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
template = templateList[index];
|
||||
}
|
||||
|
||||
return index >= 0;
|
||||
}
|
||||
|
||||
public Material GetClonedMaterial(GRenderPipelineType pipeline, GLightingModel light, GTexturingModel texturing, GSplatsModel splats = GSplatsModel.Splats4)
|
||||
{
|
||||
TerrainMaterialTemplate matTemplate;
|
||||
List<TerrainMaterialTemplate> collection =
|
||||
pipeline == GRenderPipelineType.Universal ? universalRpMaterials :
|
||||
builtinRpMaterials;
|
||||
|
||||
if (texturing != GTexturingModel.Splat)
|
||||
{
|
||||
matTemplate = collection.Find(m =>
|
||||
{
|
||||
return m.lightingModel == light && m.texturingModel == texturing;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
matTemplate = collection.Find(m =>
|
||||
{
|
||||
return m.lightingModel == light && m.texturingModel == texturing && m.splatsModel == splats;
|
||||
});
|
||||
}
|
||||
|
||||
Material mat = null;
|
||||
if (matTemplate.material != null)
|
||||
{
|
||||
mat = UnityEngine.Object.Instantiate(matTemplate.material);
|
||||
}
|
||||
|
||||
return mat;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class FoliageRenderingSettings
|
||||
{
|
||||
public Mesh grassQuad;
|
||||
public Mesh grassCross;
|
||||
public Mesh grassTriCross;
|
||||
public Mesh grassClump;
|
||||
|
||||
public Material treeBillboardMaterial;
|
||||
public Material grassMaterial;
|
||||
public Material grassBillboardMaterial;
|
||||
public Material grassInteractiveMaterial;
|
||||
|
||||
public Material urpTreeBillboardMaterial;
|
||||
public Material urpGrassMaterial;
|
||||
public Material urpGrassBillboardMaterial;
|
||||
public Material urpGrassInteractiveMaterial;
|
||||
|
||||
public Texture2D windNoiseTexture;
|
||||
|
||||
public Mesh GetGrassMesh(GGrassShape shape)
|
||||
{
|
||||
if (shape == GGrassShape.Quad)
|
||||
return grassQuad;
|
||||
else if (shape == GGrassShape.Cross)
|
||||
return grassCross;
|
||||
else if (shape == GGrassShape.TriCross)
|
||||
return grassTriCross;
|
||||
else if (shape == GGrassShape.Clump)
|
||||
return grassClump;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class InternalShaderSettings
|
||||
{
|
||||
public Shader solidColorShader;
|
||||
public Shader copyTextureShader;
|
||||
public Shader subDivisionMapShader;
|
||||
public Shader blurShader;
|
||||
public Shader blurRadiusShader;
|
||||
public Shader elevationPainterShader;
|
||||
public Shader heightSamplingPainterShader;
|
||||
public Shader subdivPainterShader;
|
||||
public Shader painterCursorProjectorShader;
|
||||
public Shader albedoPainterShader;
|
||||
public Shader metallicPainterShader;
|
||||
public Shader smoothnessPainterShader;
|
||||
public Shader splatPainterShader;
|
||||
public Shader visibilityPainterShader;
|
||||
public Shader rampMakerShader;
|
||||
public Shader pathPainterAlbedoShader;
|
||||
public Shader pathPainterMetallicSmoothnessShader;
|
||||
public Shader pathPainterSplatShader;
|
||||
public Shader geometryLivePreviewShader;
|
||||
public Shader geometricalHeightMapShader;
|
||||
public Shader splineMaskShader;
|
||||
public Shader maskVisualizerShader;
|
||||
public Shader stamperShader;
|
||||
public Shader terrainNormalMapShader;
|
||||
public Shader terrainPerPixelNormalMapShader;
|
||||
public Shader textureStamperBrushShader;
|
||||
public Shader grassPreviewShader;
|
||||
public Shader navHelperDummyGameObjectShader;
|
||||
public Shader splatsToAlbedoShader;
|
||||
public Shader unlitChannelMaskShader;
|
||||
public Shader channelToGrayscaleShader;
|
||||
public Shader heightMapFromMeshShader;
|
||||
public Shader curveFilterShader;
|
||||
public Shader invertFilterShader;
|
||||
public Shader stepFilterShader;
|
||||
public Shader warpFilterShader;
|
||||
public Shader steepnessMapGeneratorShader;
|
||||
public Shader noiseMapGeneratorShader;
|
||||
public Shader blendMapGeneratorShader;
|
||||
public Shader distributionMapGeneratorShader;
|
||||
public Shader interactiveGrassVectorFieldShader;
|
||||
public Shader subdivLivePreviewShader;
|
||||
public Shader visibilityLivePreviewShader;
|
||||
public Shader terracePainterShader;
|
||||
public Shader remapPainterShader;
|
||||
public Shader noisePainterShader;
|
||||
public Shader heightmapConverterEncodeRGShader;
|
||||
public Shader heightmapDecodeGrayscaleShader;
|
||||
public Shader drawTex2DArraySliceShader;
|
||||
public Shader maskPainterShader;
|
||||
public Shader mask4ChannelsShader;
|
||||
public Shader fetchWorldDataShader;
|
||||
public Shader applyErosionShader;
|
||||
public Shader erosionTexturerShader;
|
||||
|
||||
public ComputeShader hydraulicErosionShader;
|
||||
public ComputeShader thermalErosionShader;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class DefaultTexturesSettings
|
||||
{
|
||||
public Texture2D redTexture;
|
||||
public Texture2D blackTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0adee3aa5bcf4ad459deda003f7c26af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 18e3e435c7dff9f4a8b77fcd02e98fd2, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,44 @@
|
||||
#if GRIFFIN
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
public struct GSelectionGridArgs
|
||||
{
|
||||
public ICollection collection;
|
||||
public int selectedIndex;
|
||||
public List<int> selectedIndices;
|
||||
public int itemPerRow;
|
||||
public Vector2 itemSize;
|
||||
public bool simpleMode;
|
||||
|
||||
public delegate void DrawHandler(Rect r, object o);
|
||||
public DrawHandler drawPreviewFunction;
|
||||
|
||||
public delegate void ItemHandler(Rect r, int index, ICollection collection);
|
||||
public ItemHandler contextClickFunction;
|
||||
}
|
||||
|
||||
public struct _GSelectionGridArgs
|
||||
{
|
||||
public ICollection collection;
|
||||
public int selectedIndex;
|
||||
public List<int> selectedIndices;
|
||||
public Vector2 tileSize;
|
||||
public float windowWidth;
|
||||
|
||||
public delegate void DrawHandler(Rect r, object o);
|
||||
public DrawHandler drawPreviewFunction;
|
||||
public DrawHandler drawLabelFunction;
|
||||
public DrawHandler customDrawFunction;
|
||||
|
||||
public delegate object CategorizeHandler(object o);
|
||||
public CategorizeHandler categorizeFunction;
|
||||
|
||||
public delegate string TooltipHandler(object o);
|
||||
public TooltipHandler tooltipFunction;
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15922952102050f4ca8749746dab17b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,120 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
public static class GSpawner
|
||||
{
|
||||
public static string GetPrototypeRootName(GameObject prototype)
|
||||
{
|
||||
return string.Format("~Root_{0}", prototype.name);
|
||||
}
|
||||
|
||||
public static GameObject Spawn(GStylizedTerrain terrain, GameObject prototype, Vector3 worldPos, Transform parent = null)
|
||||
{
|
||||
GameObject g = null;
|
||||
#if UNITY_EDITOR
|
||||
bool isPrefab = false;
|
||||
#if UNITY_2018_1 || UNITY_2018_2
|
||||
isPrefab = PrefabUtility.GetPrefabObject(prototype);
|
||||
#else
|
||||
isPrefab = PrefabUtility.IsPartOfPrefabAsset(prototype);
|
||||
#endif
|
||||
|
||||
if (isPrefab)
|
||||
{
|
||||
g = PrefabUtility.InstantiatePrefab(prototype) as GameObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
g = GameObject.Instantiate<GameObject>(prototype);
|
||||
}
|
||||
|
||||
string undoName = string.Format("Spawn {0}", prototype.name);
|
||||
Undo.RegisterCreatedObjectUndo(g, undoName);
|
||||
#else
|
||||
g = GameObject.Instantiate<GameObject>(prototype);
|
||||
#endif
|
||||
if (parent == null)
|
||||
{
|
||||
parent = GetRoot(terrain, prototype).transform;
|
||||
}
|
||||
g.transform.parent = parent;
|
||||
|
||||
g.transform.position = worldPos;
|
||||
g.transform.rotation = Quaternion.identity;
|
||||
g.transform.localScale = Vector3.one;
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
public static void DestroyIf(GStylizedTerrain terrain, GameObject prototype, System.Predicate<GameObject> condition)
|
||||
{
|
||||
Transform parent = GetRoot(terrain, prototype).transform;
|
||||
GameObject[] children = GUtilities.GetChildrenGameObjects(parent);
|
||||
for (int i = 0; i < children.Length; ++i)
|
||||
{
|
||||
if (condition.Invoke(children[i]))
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Undo.DestroyObjectImmediate(children[i]);
|
||||
#else
|
||||
GUtilities.DestroyGameobject(children[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void DestroyIf(GStylizedTerrain terrain, System.Predicate<GameObject> condition)
|
||||
{
|
||||
List<Transform> parents = new List<Transform>();
|
||||
foreach (Transform t in terrain.transform)
|
||||
{
|
||||
if (t.name.StartsWith("~Root"))
|
||||
{
|
||||
parents.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < parents.Count; ++i)
|
||||
{
|
||||
GameObject[] children = GUtilities.GetChildrenGameObjects(parents[i]);
|
||||
for (int j = 0; j < children.Length; ++j)
|
||||
{
|
||||
if (condition.Invoke(children[j]))
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Undo.DestroyObjectImmediate(children[j]);
|
||||
#else
|
||||
GUtilities.DestroyGameobject(children[j]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static GameObject GetRoot(GStylizedTerrain terrain, GameObject prototype)
|
||||
{
|
||||
Transform parent = terrain.transform;
|
||||
string name = GetPrototypeRootName(prototype);
|
||||
|
||||
Transform t = parent.Find(name);
|
||||
if (t == null)
|
||||
{
|
||||
GameObject g = new GameObject(name);
|
||||
g.transform.parent = parent;
|
||||
GUtilities.ResetTransform(g.transform, parent);
|
||||
t = g.transform;
|
||||
|
||||
GObjectHelper oh = g.AddComponent<GObjectHelper>();
|
||||
oh.Terrain = terrain;
|
||||
}
|
||||
return t.gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f8fc18bd68e0614d863368ba7090a0c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38fb23ea6da5d48458ecf0f8cb6362af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 0a8bc049445e99c4494f4fa2af77c8bb, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,274 @@
|
||||
#if GRIFFIN
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
public class GSubDivisionTree
|
||||
{
|
||||
public class Node
|
||||
{
|
||||
public int Level { get; private set; }
|
||||
|
||||
private Vector2 v0;
|
||||
public Vector2 V0
|
||||
{
|
||||
get
|
||||
{
|
||||
return v0;
|
||||
}
|
||||
set
|
||||
{
|
||||
v0 = new Vector2(
|
||||
(float)System.Math.Round(value.x, 3),
|
||||
(float)System.Math.Round(value.y, 3));
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 v1;
|
||||
public Vector2 V1
|
||||
{
|
||||
get
|
||||
{
|
||||
return v1;
|
||||
}
|
||||
set
|
||||
{
|
||||
v1 = new Vector2(
|
||||
(float)System.Math.Round(value.x, 3),
|
||||
(float)System.Math.Round(value.y, 3));
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 v2;
|
||||
public Vector2 V2
|
||||
{
|
||||
get
|
||||
{
|
||||
return v2;
|
||||
}
|
||||
set
|
||||
{
|
||||
v2 = new Vector2(
|
||||
(float)System.Math.Round(value.x, 3),
|
||||
(float)System.Math.Round(value.y, 3));
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 VC
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector2 v = (V0 + V1 + V2) / 3;
|
||||
return new Vector2(
|
||||
(float)System.Math.Round(v.x, 3),
|
||||
(float)System.Math.Round(v.y, 3));
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 V01
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector2 v = (V0 + V1) * 0.5f;
|
||||
return new Vector2(
|
||||
(float)System.Math.Round(v.x, 3),
|
||||
(float)System.Math.Round(v.y, 3));
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 V12
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector2 v = (V1 + V2) * 0.5f;
|
||||
return new Vector2(
|
||||
(float)System.Math.Round(v.x, 3),
|
||||
(float)System.Math.Round(v.y, 3));
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 V20
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector2 v = (V2 + V0) * 0.5f;
|
||||
return new Vector2(
|
||||
(float)System.Math.Round(v.x, 3),
|
||||
(float)System.Math.Round(v.y, 3));
|
||||
}
|
||||
}
|
||||
|
||||
private Node leftNode;
|
||||
public Node LeftNode
|
||||
{
|
||||
get
|
||||
{
|
||||
return leftNode;
|
||||
}
|
||||
set
|
||||
{
|
||||
leftNode = value;
|
||||
if (leftNode != null)
|
||||
leftNode.Level = Level + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private Node rightNode;
|
||||
public Node RightNode
|
||||
{
|
||||
get
|
||||
{
|
||||
return rightNode;
|
||||
}
|
||||
set
|
||||
{
|
||||
rightNode = value;
|
||||
if (rightNode != null)
|
||||
rightNode.Level = Level + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public Node()
|
||||
{
|
||||
this.Level = -1;
|
||||
this.V0 = Vector2.zero;
|
||||
this.V1 = Vector2.zero;
|
||||
this.V2 = Vector2.zero;
|
||||
}
|
||||
|
||||
public Node(Vector2 v0, Vector2 v1, Vector2 v2)
|
||||
{
|
||||
this.Level = -1;
|
||||
this.V0 = v0;
|
||||
this.V1 = v1;
|
||||
this.V2 = v2;
|
||||
}
|
||||
|
||||
public void Split()
|
||||
{
|
||||
Vector2 v12 = (V1 + V2) * 0.5f;
|
||||
Node n0 = new Node(v12, V0, V1);
|
||||
Node n1 = new Node(v12, V2, V0);
|
||||
LeftNode = n0;
|
||||
RightNode = n1;
|
||||
}
|
||||
|
||||
public Node Clone()
|
||||
{
|
||||
Node n = new Node(V0, V1, V2);
|
||||
n.Level = Level;
|
||||
if (LeftNode != null)
|
||||
n.LeftNode = LeftNode.Clone();
|
||||
if (RightNode != null)
|
||||
n.RightNode = RightNode.Clone();
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
public Node Root;
|
||||
private Stack<Node> st = new Stack<Node>(1000);
|
||||
|
||||
public GSubDivisionTree()
|
||||
{
|
||||
Root = new Node();
|
||||
Node left = new Node(
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 1),
|
||||
new Vector2(0, 0));
|
||||
Node right = new Node(
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, 0),
|
||||
new Vector2(1, 1));
|
||||
Root.LeftNode = left;
|
||||
Root.RightNode = right;
|
||||
}
|
||||
|
||||
public static GSubDivisionTree Rect(Rect r)
|
||||
{
|
||||
GSubDivisionTree tree = new GSubDivisionTree();
|
||||
tree.Root = new Node();
|
||||
|
||||
Vector2 bottomLeft = new Vector2(r.min.x, r.min.y);
|
||||
Vector2 topLeft = new Vector2(r.min.x, r.max.y);
|
||||
Vector2 topRight = new Vector2(r.max.x, r.max.y);
|
||||
Vector2 bottomRight = new Vector2(r.max.x, r.min.y);
|
||||
|
||||
Node left = new Node(
|
||||
topLeft,
|
||||
topRight,
|
||||
bottomLeft);
|
||||
Node right = new Node(
|
||||
bottomRight,
|
||||
bottomLeft,
|
||||
topRight);
|
||||
tree.Root.LeftNode = left;
|
||||
tree.Root.RightNode = right;
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
public void ForEachLeaf(Action<Node> action)
|
||||
{
|
||||
st.Clear();
|
||||
st.Push(Root.RightNode);
|
||||
st.Push(Root.LeftNode);
|
||||
|
||||
Node n;
|
||||
while (st.Count > 0)
|
||||
{
|
||||
n = st.Pop();
|
||||
if (n.LeftNode == null && n.RightNode == null)
|
||||
{
|
||||
action.Invoke(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
st.Push(n.RightNode);
|
||||
st.Push(n.LeftNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GSubDivisionTree Clone(int maxLevel)
|
||||
{
|
||||
GSubDivisionTree tree = new GSubDivisionTree();
|
||||
tree.Root = Root.Clone();
|
||||
|
||||
st.Clear();
|
||||
st.Push(tree.Root.RightNode);
|
||||
st.Push(tree.Root.LeftNode);
|
||||
Node n;
|
||||
while (st.Count > 0)
|
||||
{
|
||||
n = st.Pop();
|
||||
if (n.Level == maxLevel)
|
||||
{
|
||||
n.LeftNode = null;
|
||||
n.RightNode = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n.LeftNode != null)
|
||||
st.Push(n.LeftNode);
|
||||
if (n.RightNode != null)
|
||||
st.Push(n.RightNode);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
public int GetMaxLevel()
|
||||
{
|
||||
int max = -1;
|
||||
ForEachLeaf(n =>
|
||||
{
|
||||
if (n.Level > max)
|
||||
max = n.Level;
|
||||
});
|
||||
return max;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f270994961c3fd4bb73daffd125df91
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,78 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
public struct GSubdivNode
|
||||
{
|
||||
public Vector2 v0;
|
||||
public Vector2 v1;
|
||||
public Vector2 v2;
|
||||
|
||||
public Vector2 v01
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2()
|
||||
{
|
||||
x = (v0.x + v1.x) * 0.5f,
|
||||
y = (v0.y + v1.y) * 0.5f
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 v12
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2()
|
||||
{
|
||||
x = (v1.x + v2.x) * 0.5f,
|
||||
y = (v1.y + v2.y) * 0.5f
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 v20
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2()
|
||||
{
|
||||
x = (v2.x + v0.x) * 0.5f,
|
||||
y = (v2.y + v0.y) * 0.5f
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 vc
|
||||
{
|
||||
get
|
||||
{
|
||||
return (v0 + v1 + v2) / 3f;
|
||||
}
|
||||
}
|
||||
|
||||
public void Split(ref GSubdivNode leftNode, ref GSubdivNode rightNode)
|
||||
{
|
||||
Vector2 v12 = this.v12;
|
||||
|
||||
leftNode.v0 = v12;
|
||||
leftNode.v1 = this.v2;
|
||||
leftNode.v2 = this.v0;
|
||||
|
||||
rightNode.v0 = v12;
|
||||
rightNode.v1 = v0;
|
||||
rightNode.v2 = v1;
|
||||
}
|
||||
|
||||
//public override string ToString()
|
||||
//{
|
||||
// string s = string.Format("{0}; {1}; {2};", v0.ToString(), v1.ToString(), v2.ToString());
|
||||
// return s;
|
||||
//}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26a21f6f7edca374087db358e5295f19
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,769 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(MeshFilter))]
|
||||
[RequireComponent(typeof(MeshRenderer))]
|
||||
[RequireComponent(typeof(MeshCollider))]
|
||||
[RequireComponent(typeof(LODGroup))]
|
||||
public class GTerrainChunk : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private GStylizedTerrain terrain;
|
||||
public GStylizedTerrain Terrain
|
||||
{
|
||||
get
|
||||
{
|
||||
return terrain;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
terrain = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private MeshFilter meshFilterComponent;
|
||||
public MeshFilter MeshFilterComponent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (meshFilterComponent == null)
|
||||
{
|
||||
meshFilterComponent = GetComponent<MeshFilter>();
|
||||
}
|
||||
return meshFilterComponent;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private MeshRenderer meshRendererComponent;
|
||||
public MeshRenderer MeshRendererComponent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (meshRendererComponent == null)
|
||||
{
|
||||
meshRendererComponent = GetComponent<MeshRenderer>();
|
||||
}
|
||||
return meshRendererComponent;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private MeshCollider meshColliderComponent;
|
||||
public MeshCollider MeshColliderComponent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (meshColliderComponent == null)
|
||||
{
|
||||
meshColliderComponent = GetComponent<MeshCollider>();
|
||||
}
|
||||
return meshColliderComponent;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private LODGroup lodGroupComponent;
|
||||
public LODGroup LodGroupComponent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (lodGroupComponent == null)
|
||||
{
|
||||
lodGroupComponent = GetComponent<LODGroup>();
|
||||
}
|
||||
return lodGroupComponent;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Vector2 index;
|
||||
public Vector2 Index
|
||||
{
|
||||
get
|
||||
{
|
||||
return index;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
index = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private GTerrainChunkLOD[] chunkLowerLOD;
|
||||
private GTerrainChunkLOD[] ChunkLowerLOD
|
||||
{
|
||||
get
|
||||
{
|
||||
if (chunkLowerLOD == null || chunkLowerLOD.Length != Terrain.TerrainData.Geometry.LODCount - 1)
|
||||
{
|
||||
chunkLowerLOD = new GTerrainChunkLOD[Terrain.TerrainData.Geometry.LODCount - 1];
|
||||
GUtilities.ClearChildren(transform);
|
||||
}
|
||||
return chunkLowerLOD;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private GTerrainChunk[] neighborChunks;
|
||||
internal GTerrainChunk[] Internal_NeighborChunks
|
||||
{
|
||||
get
|
||||
{
|
||||
if (neighborChunks == null || neighborChunks.Length != 4)
|
||||
{
|
||||
neighborChunks = new GTerrainChunk[4];
|
||||
}
|
||||
return neighborChunks;
|
||||
}
|
||||
set
|
||||
{
|
||||
neighborChunks = value;
|
||||
}
|
||||
}
|
||||
|
||||
private System.DateTime lastUpdatedTime;
|
||||
public System.DateTime LastUpdatedTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return lastUpdatedTime;
|
||||
}
|
||||
private set
|
||||
{
|
||||
lastUpdatedTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix4x4 LocalToTerrainMatrix
|
||||
{
|
||||
get
|
||||
{
|
||||
return transform.localToWorldMatrix * Terrain.transform.worldToLocalMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
private NativeArray<GSubdivNode> subdivNodeNativeArray;
|
||||
private NativeArray<byte> subdivNodeCreationState;
|
||||
|
||||
private NativeArray<Vector3> vertexNativeArray;
|
||||
private Vector3[] vertexArray;
|
||||
|
||||
private NativeArray<Vector2> uvsNativeArray;
|
||||
private Vector2[] uvsArray;
|
||||
|
||||
private NativeArray<int> trianglesNativeArray;
|
||||
private int[] trianglesArray;
|
||||
|
||||
private NativeArray<Vector3> normalsNativeArray;
|
||||
private Vector3[] normalsArray;
|
||||
|
||||
private NativeArray<Color32> vertexColorsNativeArray;
|
||||
private Color32[] vertexColorsArray;
|
||||
|
||||
private NativeArray<bool> vertexMarkerNativeArray;
|
||||
private bool[] vertexMarker_Cache;
|
||||
|
||||
private NativeArray<int> generationMetadata;
|
||||
|
||||
private Mesh[] nonSerializedMeshes;
|
||||
private Mesh[] NonSerializedMeshes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (nonSerializedMeshes == null)
|
||||
{
|
||||
nonSerializedMeshes = new Mesh[GCommon.MAX_LOD_COUNT];
|
||||
}
|
||||
if (nonSerializedMeshes.Length != GCommon.MAX_LOD_COUNT)
|
||||
{
|
||||
CleanUpNonSerializedMeshes();
|
||||
nonSerializedMeshes = new Mesh[GCommon.MAX_LOD_COUNT];
|
||||
}
|
||||
return nonSerializedMeshes;
|
||||
}
|
||||
}
|
||||
|
||||
public Rect GetUvRange()
|
||||
{
|
||||
if (Terrain == null || Terrain.TerrainData == null)
|
||||
{
|
||||
return GCommon.UnitRect;
|
||||
}
|
||||
else
|
||||
{
|
||||
int gridSize = Terrain.TerrainData.Geometry.ChunkGridSize;
|
||||
Vector2 position = index / gridSize;
|
||||
Vector2 size = Vector2.one / gridSize;
|
||||
return new Rect(position, size);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CleanUpNonSerializedMeshes();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
//CleanUpNativeArrays(); //Already cleaned up after generation, will cause error at runtime
|
||||
}
|
||||
|
||||
private void RecalculateTangentIfNeeded(Mesh m)
|
||||
{
|
||||
if (m == null)
|
||||
return;
|
||||
if (Terrain.TerrainData.Shading.IsMaterialUseNormalMap())
|
||||
{
|
||||
m.RecalculateTangents();
|
||||
}
|
||||
else
|
||||
{
|
||||
m.tangents = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Internal_UpdateRenderer()
|
||||
{
|
||||
MeshRendererComponent.shadowCastingMode = Terrain.TerrainData.Rendering.CastShadow ?
|
||||
UnityEngine.Rendering.ShadowCastingMode.On :
|
||||
UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
MeshRendererComponent.receiveShadows = Terrain.TerrainData.Rendering.ReceiveShadow;
|
||||
|
||||
for (int i = 1; i < Terrain.TerrainData.Geometry.LODCount; ++i)
|
||||
{
|
||||
GTerrainChunkLOD chunkLod = GetChunkLOD(i);
|
||||
chunkLod.MeshRendererComponent.shadowCastingMode = MeshRendererComponent.shadowCastingMode;
|
||||
chunkLod.MeshRendererComponent.receiveShadows = MeshRendererComponent.receiveShadows;
|
||||
chunkLod.MeshRendererComponent.sharedMaterials = MeshRendererComponent.sharedMaterials;
|
||||
chunkLod.MeshFilterComponent.sharedMesh = GetMesh(i);
|
||||
}
|
||||
//SetLastUpdatedTimeNow();
|
||||
}
|
||||
|
||||
internal void Internal_UpdateMaterial()
|
||||
{
|
||||
MeshRendererComponent.sharedMaterials = new Material[] { Terrain.TerrainData.Shading.CustomMaterial };
|
||||
|
||||
for (int i = 1; i < Terrain.TerrainData.Geometry.LODCount; ++i)
|
||||
{
|
||||
GTerrainChunkLOD chunkLod = GetChunkLOD(i);
|
||||
chunkLod.MeshRendererComponent.sharedMaterials = MeshRendererComponent.sharedMaterials;
|
||||
}
|
||||
//SetLastUpdatedTimeNow();
|
||||
}
|
||||
|
||||
public void SetupLocalToTerrainMatrix(MaterialPropertyBlock props)
|
||||
{
|
||||
string localToTerrainPropName = "_LocalToTerrainMatrix";
|
||||
props.SetMatrix(localToTerrainPropName, LocalToTerrainMatrix);
|
||||
}
|
||||
|
||||
private GTerrainChunkLOD GetChunkLOD(int level)
|
||||
{
|
||||
if (level <= 0 || level >= Terrain.TerrainData.Geometry.LODCount)
|
||||
throw new System.IndexOutOfRangeException();
|
||||
GTerrainChunkLOD c = ChunkLowerLOD[level - 1];
|
||||
if (c == null)
|
||||
{
|
||||
Transform t = GUtilities.GetChildrenWithName(transform, name + "_LOD" + level);
|
||||
c = t.gameObject.AddComponent<GTerrainChunkLOD>();
|
||||
ChunkLowerLOD[level - 1] = c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public Mesh GetMesh(int lod)
|
||||
{
|
||||
int lodCount = Terrain.TerrainData.Geometry.LODCount;
|
||||
if (lod < 0 || lod >= lodCount)
|
||||
{
|
||||
throw new System.ArgumentOutOfRangeException("lod");
|
||||
}
|
||||
|
||||
GGeometry.GStorageMode mode = Terrain.TerrainData.Geometry.StorageMode;
|
||||
if (mode == GGeometry.GStorageMode.SaveToAsset)
|
||||
{
|
||||
Vector3Int key = GetChunkMeshKey(Index, lod);
|
||||
Mesh m = Terrain.TerrainData.GeometryData.GetMesh(key);
|
||||
if (m == null)
|
||||
{
|
||||
m = new Mesh();
|
||||
m.name = GetChunkMeshName(Index, lod);
|
||||
m.MarkDynamic();
|
||||
Terrain.TerrainData.GeometryData.SetMesh(key, m);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
else
|
||||
{
|
||||
string key = GetChunkMeshName(Index, lod);
|
||||
Mesh m = NonSerializedMeshes[lod];
|
||||
if (m == null)
|
||||
{
|
||||
m = new Mesh();
|
||||
m.name = string.Format("{0}_NonSerialized", key);
|
||||
m.MarkDynamic();
|
||||
NonSerializedMeshes[lod] = m;
|
||||
}
|
||||
m.hideFlags = HideFlags.DontSave;
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetChunkMeshName(Vector2 index, int lod)
|
||||
{
|
||||
return string.Format("{0}_{1}_{2}_{3}", GCommon.CHUNK_MESH_NAME_PREFIX, (int)index.x, (int)index.y, lod);
|
||||
}
|
||||
|
||||
public static Vector3Int GetChunkMeshKey(Vector2 index, int lod)
|
||||
{
|
||||
return new Vector3Int((int)index.x, (int)index.y, lod);
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
Mesh lod0 = GetMesh(0);
|
||||
MeshFilterComponent.sharedMesh = lod0;
|
||||
MeshColliderComponent.sharedMesh = lod0;
|
||||
|
||||
for (int i = 1; i < Terrain.TerrainData.Geometry.LODCount; ++i)
|
||||
{
|
||||
Mesh lodi = GetMesh(i);
|
||||
GTerrainChunkLOD chunkLodi = GetChunkLOD(i);
|
||||
chunkLodi.MeshFilterComponent.sharedMesh = lodi;
|
||||
}
|
||||
//SetLastUpdatedTimeNow();
|
||||
}
|
||||
|
||||
private void SetLastUpdatedTimeNow()
|
||||
{
|
||||
LastUpdatedTime = System.DateTime.Now;
|
||||
}
|
||||
|
||||
public bool Raycast(Ray ray, out RaycastHit hit, float distance)
|
||||
{
|
||||
if (MeshColliderComponent == null || MeshColliderComponent.sharedMesh == null)
|
||||
{
|
||||
hit = new RaycastHit();
|
||||
return false;
|
||||
}
|
||||
return MeshColliderComponent.Raycast(ray, out hit, distance);
|
||||
}
|
||||
|
||||
internal void InitSubdivTreeNativeContainers(int meshResolution)
|
||||
{
|
||||
int treeNodeCount = GetSubdivTreeNodeCount(meshResolution);
|
||||
subdivNodeNativeArray = new NativeArray<GSubdivNode>(treeNodeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
subdivNodeCreationState = new NativeArray<byte>(treeNodeCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
generationMetadata = new NativeArray<int>(GGeometryJobUtilities.METADATA_LENGTH, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
|
||||
int dimension = GGeometryJobUtilities.VERTEX_MARKER_DIMENSION;
|
||||
vertexMarkerNativeArray = new NativeArray<bool>(dimension * dimension, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
}
|
||||
|
||||
internal void InitMeshDataNativeContainers(GAlbedoToVertexColorMode albedoToVertexColor)
|
||||
{
|
||||
int vertexCount = generationMetadata[0] * 3;
|
||||
vertexNativeArray = new NativeArray<Vector3>(vertexCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
GUtilities.EnsureArrayLength(ref vertexArray, vertexCount);
|
||||
|
||||
uvsNativeArray = new NativeArray<Vector2>(vertexCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
GUtilities.EnsureArrayLength(ref uvsArray, vertexCount);
|
||||
|
||||
trianglesNativeArray = new NativeArray<int>(vertexCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
GUtilities.EnsureArrayLength(ref trianglesArray, vertexCount);
|
||||
|
||||
normalsNativeArray = new NativeArray<Vector3>(vertexCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
GUtilities.EnsureArrayLength(ref normalsArray, vertexCount);
|
||||
|
||||
if (albedoToVertexColor == GAlbedoToVertexColorMode.None)
|
||||
{
|
||||
vertexColorsNativeArray = new NativeArray<Color32>(1, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertexColorsNativeArray = new NativeArray<Color32>(vertexCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
|
||||
GUtilities.EnsureArrayLength(ref vertexColorsArray, vertexCount);
|
||||
}
|
||||
}
|
||||
|
||||
internal int GetSubdivTreeNodeCount(int meshResolution)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i <= meshResolution; ++i)
|
||||
{
|
||||
count += GetSubdivTreeNodeCountForLevel(i);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
internal int GetSubdivTreeNodeCountForLevel(int level)
|
||||
{
|
||||
return 2 * Mathf.FloorToInt(Mathf.Pow(2, level));
|
||||
}
|
||||
|
||||
internal void CleanUpNativeArrays()
|
||||
{
|
||||
GNativeArrayUtilities.Dispose(subdivNodeNativeArray);
|
||||
GNativeArrayUtilities.Dispose(subdivNodeCreationState);
|
||||
GNativeArrayUtilities.Dispose(vertexNativeArray);
|
||||
GNativeArrayUtilities.Dispose(uvsNativeArray);
|
||||
GNativeArrayUtilities.Dispose(normalsNativeArray);
|
||||
GNativeArrayUtilities.Dispose(trianglesNativeArray);
|
||||
GNativeArrayUtilities.Dispose(vertexColorsNativeArray);
|
||||
GNativeArrayUtilities.Dispose(generationMetadata);
|
||||
GNativeArrayUtilities.Dispose(vertexMarkerNativeArray);
|
||||
}
|
||||
|
||||
internal void CleanUpNonSerializedMeshes()
|
||||
{
|
||||
if (nonSerializedMeshes != null)
|
||||
{
|
||||
for (int i = 0; i < nonSerializedMeshes.Length; ++i)
|
||||
{
|
||||
Mesh m = nonSerializedMeshes[i];
|
||||
if (m != null)
|
||||
{
|
||||
GUtilities.DestroyObject(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal GCreateBaseTreeJob GetCreateBaseSubdivTreeJob(
|
||||
int meshBaseResolution,
|
||||
int meshResolution,
|
||||
int lod)
|
||||
{
|
||||
GCreateBaseTreeJob job = new GCreateBaseTreeJob()
|
||||
{
|
||||
nodes = subdivNodeNativeArray,
|
||||
creationState = subdivNodeCreationState,
|
||||
vertexMarker = vertexMarkerNativeArray,
|
||||
metadata = generationMetadata,
|
||||
baseResolution = meshBaseResolution,
|
||||
resolution = meshResolution,
|
||||
lod = lod
|
||||
};
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
internal GSplitBaseTreeForDynamicPolygonJob GetSplitBaseTreeForDynamicPolygonJob(
|
||||
int meshBaseResolution, int meshResolution, int lod,
|
||||
GTextureNativeDataDescriptor<Color32> subdivMap)
|
||||
{
|
||||
Rect uvRect = GetUvRange();
|
||||
GSplitBaseTreeForDynamicPolygonJob job = new GSplitBaseTreeForDynamicPolygonJob()
|
||||
{
|
||||
baseTree = subdivNodeNativeArray,
|
||||
creationState = subdivNodeCreationState,
|
||||
vertexMarker = vertexMarkerNativeArray,
|
||||
subdivMap = subdivMap,
|
||||
baseResolution = meshBaseResolution,
|
||||
resolution = meshResolution,
|
||||
lod = lod,
|
||||
uvRect = uvRect
|
||||
};
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
internal GStitchSeamJob GetStitchSeamJob(
|
||||
int meshBaseResolution,
|
||||
int meshResolution,
|
||||
bool hasLeftMarkers, NativeArray<bool> leftMarkers,
|
||||
bool hasTopMarkers, NativeArray<bool> topMarkers,
|
||||
bool hasRightMarkers, NativeArray<bool> rightMarkers,
|
||||
bool hasBottomMarkers, NativeArray<bool> bottomMarkers)
|
||||
{
|
||||
GStitchSeamJob job = new GStitchSeamJob()
|
||||
{
|
||||
nodes = subdivNodeNativeArray,
|
||||
creationState = subdivNodeCreationState,
|
||||
vertexMarker = vertexMarkerNativeArray,
|
||||
metadata = generationMetadata,
|
||||
meshBaseResolution = meshBaseResolution,
|
||||
meshResolution = meshResolution,
|
||||
|
||||
hasLeftMarker = hasLeftMarkers,
|
||||
vertexMarkerLeft = leftMarkers,
|
||||
|
||||
hasTopMarker = hasTopMarkers,
|
||||
vertexMarkerTop = topMarkers,
|
||||
|
||||
hasRightMarker = hasRightMarkers,
|
||||
vertexMarkerRight = rightMarkers,
|
||||
|
||||
hasBottomMarker = hasBottomMarkers,
|
||||
vertexMarkerBottom = bottomMarkers
|
||||
};
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
internal GStitchSeamLODJob GetStitchSeamLODJob(
|
||||
int meshBaseResolution,
|
||||
int meshResolution,
|
||||
int lod,
|
||||
NativeArray<bool> markerLOD0)
|
||||
{
|
||||
GStitchSeamLODJob job = new GStitchSeamLODJob()
|
||||
{
|
||||
nodes = subdivNodeNativeArray,
|
||||
creationState = subdivNodeCreationState,
|
||||
vertexMarker = vertexMarkerNativeArray,
|
||||
metadata = generationMetadata,
|
||||
meshBaseResolution = meshBaseResolution,
|
||||
meshResolution = meshResolution,
|
||||
lod = lod,
|
||||
vertexMarker_LOD0 = markerLOD0
|
||||
};
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
internal void CacheVertexMarker()
|
||||
{
|
||||
if (vertexMarkerNativeArray.IsCreated)
|
||||
{
|
||||
GUtilities.EnsureArrayLength(ref vertexMarker_Cache, vertexMarkerNativeArray.Length);
|
||||
vertexMarkerNativeArray.CopyTo(vertexMarker_Cache);
|
||||
}
|
||||
}
|
||||
|
||||
internal GCountLeafNodeJob GetCountLeafNodeJob(
|
||||
int meshBaseResolution,
|
||||
int meshResolution,
|
||||
int lod)
|
||||
{
|
||||
GCountLeafNodeJob job = new GCountLeafNodeJob()
|
||||
{
|
||||
creationState = subdivNodeCreationState,
|
||||
metadata = generationMetadata,
|
||||
baseResolution = meshBaseResolution,
|
||||
resolution = meshResolution,
|
||||
lod = lod
|
||||
};
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
internal GCreateVertexJob GetCreateVertexJob(
|
||||
int meshBaseResolution,
|
||||
int meshResolution,
|
||||
int lod,
|
||||
int displacementSeed,
|
||||
float displacementStrength,
|
||||
bool smoothNormal,
|
||||
bool useSmoothNormalMask,
|
||||
bool mergeUv,
|
||||
GTextureNativeDataDescriptor<Color32> maskMap,
|
||||
GAlbedoToVertexColorMode albedoToVertexColor,
|
||||
GTextureNativeDataDescriptor<Color32> albedoMap,
|
||||
GTextureNativeDataDescriptor<Color32>[] hm)
|
||||
{
|
||||
InitMeshDataNativeContainers(albedoToVertexColor);
|
||||
|
||||
Vector3 terrainSize = Terrain.TerrainData.Geometry.Size;
|
||||
Rect uvRect = GetUvRange();
|
||||
float texelSize = 1.0f / Terrain.TerrainData.Geometry.HeightMapResolution;
|
||||
GCreateVertexJob job = new GCreateVertexJob()
|
||||
{
|
||||
nodes = subdivNodeNativeArray,
|
||||
creationState = subdivNodeCreationState,
|
||||
|
||||
hmC = hm[4],
|
||||
hmL = hm[3],
|
||||
hmT = hm[7],
|
||||
hmR = hm[5],
|
||||
hmB = hm[1],
|
||||
hmBL = hm[0],
|
||||
hmTL = hm[6],
|
||||
hmTR = hm[8],
|
||||
hmBR = hm[2],
|
||||
|
||||
vertices = vertexNativeArray,
|
||||
uvs = uvsNativeArray,
|
||||
normals = normalsNativeArray,
|
||||
triangles = trianglesNativeArray,
|
||||
colors = vertexColorsNativeArray,
|
||||
metadata = generationMetadata,
|
||||
|
||||
meshBaseResolution = meshBaseResolution,
|
||||
meshResolution = meshResolution,
|
||||
lod = lod,
|
||||
displacementSeed = displacementSeed,
|
||||
displacementStrength = displacementStrength,
|
||||
smoothNormal = smoothNormal,
|
||||
useSmoothNormalMask = useSmoothNormalMask,
|
||||
mergeUV = mergeUv,
|
||||
|
||||
albedoToVertexColorMode = albedoToVertexColor,
|
||||
albedoMap = albedoMap,
|
||||
maskMap = maskMap,
|
||||
|
||||
terrainSize = terrainSize,
|
||||
chunkUvRect = uvRect,
|
||||
chunkLocalPosition = transform.localPosition,
|
||||
texelSize = texelSize
|
||||
};
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
internal void UpdateMesh(int lod, GAlbedoToVertexColorMode albedoToVertexColor)
|
||||
{
|
||||
Mesh m = GetMesh(lod);
|
||||
m.Clear();
|
||||
|
||||
int leafCount = generationMetadata[GGeometryJobUtilities.METADATA_LEAF_COUNT];
|
||||
int removedLeafCount = generationMetadata[GGeometryJobUtilities.METADATA_LEAF_REMOVED];
|
||||
|
||||
if (leafCount != removedLeafCount)
|
||||
{
|
||||
vertexNativeArray.CopyTo(vertexArray);
|
||||
uvsNativeArray.CopyTo(uvsArray);
|
||||
normalsNativeArray.CopyTo(normalsArray);
|
||||
trianglesNativeArray.CopyTo(trianglesArray);
|
||||
|
||||
m.vertices = vertexArray;
|
||||
m.uv = uvsArray;
|
||||
m.triangles = trianglesArray;
|
||||
m.normals = normalsArray;
|
||||
|
||||
if (albedoToVertexColor != GAlbedoToVertexColorMode.None)
|
||||
{
|
||||
vertexColorsNativeArray.CopyTo(vertexColorsArray);
|
||||
m.colors32 = vertexColorsArray;
|
||||
}
|
||||
|
||||
m.RecalculateBounds();
|
||||
RecalculateTangentIfNeeded(m);
|
||||
}
|
||||
|
||||
if (lod == 0)
|
||||
{
|
||||
MeshFilterComponent.sharedMesh = m;
|
||||
}
|
||||
else
|
||||
{
|
||||
GTerrainChunkLOD chunkLOD = GetChunkLOD(lod);
|
||||
chunkLOD.MeshFilterComponent.sharedMesh = m;
|
||||
}
|
||||
|
||||
SetLastUpdatedTimeNow();
|
||||
}
|
||||
|
||||
internal void UpdateCollisionMesh()
|
||||
{
|
||||
Mesh m = GetMesh(0);
|
||||
if (m != null)
|
||||
{
|
||||
MeshColliderComponent.sharedMesh = m;
|
||||
}
|
||||
}
|
||||
|
||||
internal NativeArray<bool> GetVertexMarkerFromMeshUV(int lod)
|
||||
{
|
||||
int dimension = GGeometryJobUtilities.VERTEX_MARKER_DIMENSION;
|
||||
NativeArray<bool> markers = new NativeArray<bool>(dimension * dimension, Allocator.TempJob);
|
||||
|
||||
Mesh m = GetMesh(lod);
|
||||
Vector2[] uvs = m.uv;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
Vector2 uv = Vector2.zero;
|
||||
for (int i = 0; i < uvs.Length; ++i)
|
||||
{
|
||||
uv = uvs[i];
|
||||
x = (int)(uv.x * (dimension - 1));
|
||||
y = (int)(uv.y * (dimension - 1));
|
||||
markers[GGeometryJobUtilities.To1DIndex(ref x, ref y, ref dimension)] = true;
|
||||
}
|
||||
|
||||
//GUtilities.EnsureArrayLength(ref vertexMarker_Cache, markers.Length);
|
||||
//markers.CopyTo(vertexMarker_Cache);
|
||||
|
||||
return markers;
|
||||
}
|
||||
|
||||
internal NativeArray<bool> GetVertexMarker()
|
||||
{
|
||||
//if (vertexMarkerNativeArray.IsCreated)
|
||||
//{
|
||||
// NativeArray<bool> markers = new NativeArray<bool>(vertexMarkerNativeArray, Allocator.TempJob);
|
||||
// return markers;
|
||||
//}
|
||||
int dimension = GGeometryJobUtilities.VERTEX_MARKER_DIMENSION;
|
||||
if (vertexMarker_Cache != null && vertexMarker_Cache.Length == dimension * dimension)
|
||||
{
|
||||
NativeArray<bool> markers = new NativeArray<bool>(vertexMarker_Cache, Allocator.TempJob);
|
||||
return markers;
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeArray<bool> markers = GetVertexMarkerFromMeshUV(0);
|
||||
return markers;
|
||||
}
|
||||
}
|
||||
|
||||
internal int GetGenerationMetadata(int channel)
|
||||
{
|
||||
return generationMetadata[channel];
|
||||
}
|
||||
|
||||
internal void SetupLODGroup(int lodCount)
|
||||
{
|
||||
float transitionStep = 1.0f / lodCount;
|
||||
LOD[] lods = new LOD[lodCount];
|
||||
lods[0] = new LOD(
|
||||
GRuntimeSettings.Instance.geometryGeneration.lodTransition.Evaluate(transitionStep),
|
||||
new Renderer[] { MeshRendererComponent });
|
||||
|
||||
for (int level = 1; level < lodCount; ++level)
|
||||
{
|
||||
int i = level;
|
||||
lods[i] = new LOD(
|
||||
GRuntimeSettings.Instance.geometryGeneration.lodTransition.Evaluate((i + 1) * transitionStep),
|
||||
new Renderer[] { GetChunkLOD(i).MeshRendererComponent });
|
||||
|
||||
GTerrainChunkLOD chunkLod = GetChunkLOD(i);
|
||||
chunkLod.MeshFilterComponent.sharedMesh = null;
|
||||
chunkLod.MeshRendererComponent.enabled = true;
|
||||
}
|
||||
|
||||
LodGroupComponent.SetLODs(lods);
|
||||
Internal_UpdateRenderer();
|
||||
|
||||
List<GameObject> childLod = new List<GameObject>();
|
||||
int maxIndex = transform.childCount - 1;
|
||||
for (int i = lodCount - 1; i <= maxIndex; ++i)
|
||||
{
|
||||
Transform child = transform.GetChild(i);
|
||||
if (child != null)
|
||||
{
|
||||
childLod.Add(transform.GetChild(i).gameObject);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < childLod.Count; ++i)
|
||||
{
|
||||
GUtilities.DestroyGameobject(childLod[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc03e06c54fe53c4c8f0306294414814
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,49 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
[System.Serializable]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(MeshFilter))]
|
||||
[RequireComponent(typeof(MeshRenderer))]
|
||||
public class GTerrainChunkLOD : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private MeshFilter meshFilterComponent;
|
||||
public MeshFilter MeshFilterComponent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (meshFilterComponent == null)
|
||||
{
|
||||
meshFilterComponent = GetComponent<MeshFilter>();
|
||||
if (meshFilterComponent == null)
|
||||
{
|
||||
meshFilterComponent = gameObject.AddComponent<MeshFilter>();
|
||||
}
|
||||
}
|
||||
return meshFilterComponent;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private MeshRenderer meshRendererComponent;
|
||||
public MeshRenderer MeshRendererComponent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (meshRendererComponent == null)
|
||||
{
|
||||
meshRendererComponent = GetComponent<MeshRenderer>();
|
||||
if (meshRendererComponent == null)
|
||||
{
|
||||
meshRendererComponent = gameObject.AddComponent<MeshRenderer>();
|
||||
}
|
||||
}
|
||||
return meshRendererComponent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ea53212566efad49ba506844b5af0a2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,47 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
public struct GVector2Byte
|
||||
{
|
||||
public static readonly GVector2Byte bottomLeft = new GVector2Byte(0, 0);
|
||||
public static readonly GVector2Byte topLeft = new GVector2Byte(0, 255);
|
||||
public static readonly GVector2Byte topRight = new GVector2Byte(255, 255);
|
||||
public static readonly GVector2Byte bottomRight = new GVector2Byte(255, 0);
|
||||
|
||||
public byte x;
|
||||
public byte y;
|
||||
|
||||
public float xFloat01
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)System.Math.Round(Mathf.InverseLerp(0, 255, x), 3);
|
||||
}
|
||||
}
|
||||
|
||||
public float yFloat01
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)System.Math.Round(Mathf.InverseLerp(0, 255, y), 3);
|
||||
}
|
||||
}
|
||||
|
||||
public GVector2Byte(byte x, byte y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string s = string.Format("({0}, {1})", xFloat01.ToString("0.00"), yFloat01.ToString("0.00"));
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3bf7d1e6b2bda7347beb70dfd6084147
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 33cf88d404de74c4eb8b58bc59ef578e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
public struct GBakeCollisionMeshJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly]
|
||||
public NativeArray<int> instanceIds;
|
||||
|
||||
public void Execute(int index)
|
||||
{
|
||||
Physics.BakeMesh(instanceIds[index], false);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 542a2fe26c3dfb947afd5eb27e809a5c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,63 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
#if GRIFFIN_BURST
|
||||
[BurstCompile(CompileSynchronously = false)]
|
||||
#endif
|
||||
public struct GCountLeafNodeJob : IJob
|
||||
{
|
||||
public NativeArray<byte> creationState;
|
||||
[WriteOnly]
|
||||
public NativeArray<int> metadata;
|
||||
|
||||
public int baseResolution;
|
||||
public int resolution;
|
||||
public int lod;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
int startIndex = 0;
|
||||
int endIndex = 0;
|
||||
int leftNodeIndex = 0;
|
||||
int rightNodeIndex = 0;
|
||||
int count = 0;
|
||||
int length = creationState.Length;
|
||||
|
||||
baseResolution = Mathf.Max(0, baseResolution - lod);
|
||||
|
||||
for (int res = baseResolution; res <= resolution; ++res)
|
||||
{
|
||||
startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
|
||||
endIndex = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
|
||||
for (int i = startIndex; i <= endIndex; ++i)
|
||||
{
|
||||
if (creationState[i] != GGeometryJobUtilities.STATE_CREATED)
|
||||
continue;
|
||||
GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);
|
||||
if (leftNodeIndex >= length || rightNodeIndex >= length)
|
||||
{
|
||||
creationState[i] = GGeometryJobUtilities.STATE_LEAF;
|
||||
count += 1;
|
||||
continue;
|
||||
}
|
||||
if (creationState[leftNodeIndex] == GGeometryJobUtilities.STATE_NOT_CREATED ||
|
||||
creationState[rightNodeIndex] == GGeometryJobUtilities.STATE_NOT_CREATED)
|
||||
{
|
||||
creationState[i] = GGeometryJobUtilities.STATE_LEAF;
|
||||
count += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
metadata[0] = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 027703dec96d8b645a33649b533b923b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,115 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
#if GRIFFIN_BURST
|
||||
[BurstCompile(CompileSynchronously = false)]
|
||||
#endif
|
||||
internal struct GCreateBaseTreeJob : IJob
|
||||
{
|
||||
public NativeArray<GSubdivNode> nodes;
|
||||
[WriteOnly]
|
||||
public NativeArray<byte> creationState;
|
||||
[WriteOnly]
|
||||
public NativeArray<bool> vertexMarker;
|
||||
|
||||
[WriteOnly]
|
||||
public NativeArray<int> metadata;
|
||||
|
||||
public int baseResolution;
|
||||
public int resolution;
|
||||
public int lod;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
ResetMetadata();
|
||||
ResetStates();
|
||||
ResetMarker();
|
||||
|
||||
GSubdivNode nodes0 = new GSubdivNode()
|
||||
{
|
||||
v0 = Vector2.up,
|
||||
v1 = Vector2.one,
|
||||
v2 = Vector2.zero
|
||||
};
|
||||
nodes[0] = nodes0;
|
||||
creationState[0] = GGeometryJobUtilities.STATE_CREATED;
|
||||
GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref nodes0);
|
||||
|
||||
GSubdivNode nodes1 = new GSubdivNode()
|
||||
{
|
||||
v0 = Vector2.right,
|
||||
v1 = Vector2.zero,
|
||||
v2 = Vector2.one
|
||||
};
|
||||
nodes[1] = nodes1;
|
||||
creationState[1] = GGeometryJobUtilities.STATE_CREATED;
|
||||
GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref nodes1);
|
||||
|
||||
int startIndex = 0;
|
||||
int endIndex = 0;
|
||||
int leftNodeIndex = 0;
|
||||
int rightNodeIndex = 0;
|
||||
GSubdivNode currentNode;
|
||||
GSubdivNode leftNode = new GSubdivNode();
|
||||
GSubdivNode rightNode = new GSubdivNode();
|
||||
|
||||
for (int res = 0; res < resolution; ++res)
|
||||
{
|
||||
startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
|
||||
endIndex = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
|
||||
for (int i = startIndex; i <= endIndex; ++i)
|
||||
{
|
||||
currentNode = nodes[i];
|
||||
currentNode.Split(ref leftNode, ref rightNode);
|
||||
GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);
|
||||
|
||||
nodes[leftNodeIndex] = leftNode;
|
||||
nodes[rightNodeIndex] = rightNode;
|
||||
}
|
||||
}
|
||||
|
||||
baseResolution = Mathf.Max(0, baseResolution - lod);
|
||||
for (int res = 0; res <= baseResolution; ++res)
|
||||
{
|
||||
startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
|
||||
endIndex = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
|
||||
for (int i = startIndex; i <= endIndex; ++i)
|
||||
{
|
||||
currentNode = nodes[i];
|
||||
creationState[i] = GGeometryJobUtilities.STATE_CREATED;
|
||||
GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref currentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetMetadata()
|
||||
{
|
||||
metadata[GGeometryJobUtilities.METADATA_LEAF_COUNT] = 0;
|
||||
metadata[GGeometryJobUtilities.METADATA_NEW_VERTEX_CREATED] = 0;
|
||||
}
|
||||
|
||||
private void ResetStates()
|
||||
{
|
||||
for (int i = 0; i < creationState.Length; ++i)
|
||||
{
|
||||
creationState[i] = GGeometryJobUtilities.STATE_NOT_CREATED;
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetMarker()
|
||||
{
|
||||
for (int i = 0; i < vertexMarker.Length; ++i)
|
||||
{
|
||||
vertexMarker[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a737aaad43220b4a9635c682c6a3814
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,472 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Jobs;
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Random = Unity.Mathematics.Random;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
#if GRIFFIN_BURST
|
||||
[BurstCompile(CompileSynchronously = false)]
|
||||
#endif
|
||||
public struct GCreateVertexJob : IJob
|
||||
{
|
||||
[ReadOnly]
|
||||
public NativeArray<GSubdivNode> nodes;
|
||||
[ReadOnly]
|
||||
public NativeArray<byte> creationState;
|
||||
|
||||
public GTextureNativeDataDescriptor<Color32> hmC;
|
||||
public GTextureNativeDataDescriptor<Color32> hmL;
|
||||
public GTextureNativeDataDescriptor<Color32> hmT;
|
||||
public GTextureNativeDataDescriptor<Color32> hmR;
|
||||
public GTextureNativeDataDescriptor<Color32> hmB;
|
||||
public GTextureNativeDataDescriptor<Color32> hmBL;
|
||||
public GTextureNativeDataDescriptor<Color32> hmTL;
|
||||
public GTextureNativeDataDescriptor<Color32> hmTR;
|
||||
public GTextureNativeDataDescriptor<Color32> hmBR;
|
||||
|
||||
public GTextureNativeDataDescriptor<Color32> maskMap;
|
||||
public GTextureNativeDataDescriptor<Color32> albedoMap;
|
||||
public GAlbedoToVertexColorMode albedoToVertexColorMode;
|
||||
|
||||
[WriteOnly]
|
||||
public NativeArray<Vector3> vertices;
|
||||
[WriteOnly]
|
||||
public NativeArray<Vector2> uvs;
|
||||
[WriteOnly]
|
||||
public NativeArray<int> triangles;
|
||||
[WriteOnly]
|
||||
public NativeArray<Vector3> normals;
|
||||
[WriteOnly]
|
||||
public NativeArray<Color32> colors;
|
||||
[WriteOnly]
|
||||
public NativeArray<int> metadata;
|
||||
|
||||
public int meshBaseResolution;
|
||||
public int meshResolution;
|
||||
public int lod;
|
||||
public int displacementSeed;
|
||||
public float displacementStrength;
|
||||
public bool smoothNormal;
|
||||
public bool useSmoothNormalMask;
|
||||
public bool mergeUV;
|
||||
|
||||
public Vector3 terrainSize;
|
||||
public Rect chunkUvRect;
|
||||
public Vector3 chunkLocalPosition;
|
||||
public float texelSize;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
GSubdivNode n;
|
||||
Vector3 v0 = Vector3.zero;
|
||||
Vector3 v1 = Vector3.zero;
|
||||
Vector3 v2 = Vector3.zero;
|
||||
|
||||
Vector2 uv0 = Vector2.zero;
|
||||
Vector2 uv1 = Vector2.zero;
|
||||
Vector2 uv2 = Vector2.zero;
|
||||
Vector2 uvc = Vector2.zero;
|
||||
|
||||
Vector3 normal = Vector3.zero;
|
||||
Color32 color = new Color32();
|
||||
|
||||
int i0 = 0;
|
||||
int i1 = 0;
|
||||
int i2 = 0;
|
||||
|
||||
Color hmData0 = Color.black;
|
||||
Color hmData1 = Color.black;
|
||||
Color hmData2 = Color.black;
|
||||
float heightSample = 0;
|
||||
|
||||
meshBaseResolution = Mathf.Max(0, meshBaseResolution - lod);
|
||||
|
||||
int length = nodes.Length;
|
||||
int leafIndex = 0;
|
||||
int startIndex = GGeometryJobUtilities.GetStartIndex(ref meshBaseResolution);
|
||||
int removedLeafCount = 0;
|
||||
|
||||
for (int i = startIndex; i < length; ++i)
|
||||
{
|
||||
if (creationState[i] != GGeometryJobUtilities.STATE_LEAF)
|
||||
continue;
|
||||
n = nodes[i];
|
||||
ProcessTriangle(
|
||||
ref n, ref leafIndex,
|
||||
ref uv0, ref uv1, ref uv2, ref uvc,
|
||||
ref v0, ref v1, ref v2,
|
||||
ref i0, ref i1, ref i2,
|
||||
ref normal, ref color,
|
||||
ref hmData0, ref hmData1, ref hmData2,
|
||||
ref heightSample, ref removedLeafCount);
|
||||
leafIndex += 1;
|
||||
}
|
||||
|
||||
metadata[GGeometryJobUtilities.METADATA_LEAF_REMOVED] = removedLeafCount;
|
||||
}
|
||||
|
||||
private void ProcessTriangle(
|
||||
ref GSubdivNode n, ref int leafIndex,
|
||||
ref Vector2 uv0, ref Vector2 uv1, ref Vector2 uv2, ref Vector2 uvc,
|
||||
ref Vector3 v0, ref Vector3 v1, ref Vector3 v2,
|
||||
ref int i0, ref int i1, ref int i2,
|
||||
ref Vector3 normal, ref Color32 color,
|
||||
ref Color hmData0, ref Color hmData1, ref Color hmData2,
|
||||
ref float heightSample, ref int removedLeafCount)
|
||||
{
|
||||
GGeometryJobUtilities.NormalizeToPoint(ref uv0, ref chunkUvRect, ref n.v0);
|
||||
GGeometryJobUtilities.NormalizeToPoint(ref uv1, ref chunkUvRect, ref n.v1);
|
||||
GGeometryJobUtilities.NormalizeToPoint(ref uv2, ref chunkUvRect, ref n.v2);
|
||||
|
||||
if (displacementStrength > 0)
|
||||
{
|
||||
DisplaceUV(ref uv0);
|
||||
DisplaceUV(ref uv1);
|
||||
DisplaceUV(ref uv2);
|
||||
}
|
||||
|
||||
GetHeightMapData(ref hmData0, ref uv0);
|
||||
GetHeightMapData(ref hmData1, ref uv1);
|
||||
GetHeightMapData(ref hmData2, ref uv2);
|
||||
|
||||
GetHeightSample(ref heightSample, ref hmData0);
|
||||
v0.Set(
|
||||
uv0.x * terrainSize.x - chunkLocalPosition.x,
|
||||
heightSample * terrainSize.y,
|
||||
uv0.y * terrainSize.z - chunkLocalPosition.z);
|
||||
|
||||
GetHeightSample(ref heightSample, ref hmData1);
|
||||
v1.Set(
|
||||
uv1.x * terrainSize.x - chunkLocalPosition.x,
|
||||
heightSample * terrainSize.y,
|
||||
uv1.y * terrainSize.z - chunkLocalPosition.z);
|
||||
|
||||
GetHeightSample(ref heightSample, ref hmData2);
|
||||
v2.Set(
|
||||
uv2.x * terrainSize.x - chunkLocalPosition.x,
|
||||
heightSample * terrainSize.y,
|
||||
uv2.y * terrainSize.z - chunkLocalPosition.z);
|
||||
|
||||
i0 = leafIndex * 3 + 0;
|
||||
i1 = leafIndex * 3 + 1;
|
||||
i2 = leafIndex * 3 + 2;
|
||||
|
||||
vertices[i0] = v0;
|
||||
vertices[i1] = v1;
|
||||
vertices[i2] = v2;
|
||||
|
||||
if (mergeUV)
|
||||
{
|
||||
Vector2 mergedUV = (uv0 + uv1 + uv2) / 3f;
|
||||
uvs[i0] = mergedUV;
|
||||
uvs[i1] = mergedUV;
|
||||
uvs[i2] = mergedUV;
|
||||
}
|
||||
else
|
||||
{
|
||||
uvs[i0] = uv0;
|
||||
uvs[i1] = uv1;
|
||||
uvs[i2] = uv2;
|
||||
}
|
||||
|
||||
if (!smoothNormal)
|
||||
{
|
||||
normal = Vector3.Cross(v1 - v0, v2 - v0).normalized;
|
||||
normals[i0] = normal;
|
||||
normals[i1] = normal;
|
||||
normals[i2] = normal;
|
||||
}
|
||||
else if (smoothNormal && !useSmoothNormalMask)
|
||||
{
|
||||
normals[i0] = GetSmoothNormal(ref uv0, ref v0).normalized;
|
||||
normals[i1] = GetSmoothNormal(ref uv1, ref v1).normalized;
|
||||
normals[i2] = GetSmoothNormal(ref uv2, ref v2).normalized;
|
||||
}
|
||||
else if (smoothNormal && useSmoothNormalMask)
|
||||
{
|
||||
normal = Vector3.Cross(v1 - v0, v2 - v0);
|
||||
Vector3 smoothNormal;
|
||||
float mask;
|
||||
|
||||
smoothNormal = GetSmoothNormal(ref uv0, ref v0);
|
||||
mask = GetSmoothNormalMask(ref uv0);
|
||||
normals[i0] = Vector3.Lerp(normal, smoothNormal, mask).normalized;
|
||||
|
||||
smoothNormal = GetSmoothNormal(ref uv1, ref v1);
|
||||
mask = GetSmoothNormalMask(ref uv1);
|
||||
normals[i1] = Vector3.Lerp(normal, smoothNormal, mask).normalized;
|
||||
|
||||
smoothNormal = GetSmoothNormal(ref uv2, ref v2);
|
||||
mask = GetSmoothNormalMask(ref uv2);
|
||||
normals[i2] = Vector3.Lerp(normal, smoothNormal, mask).normalized;
|
||||
}
|
||||
|
||||
if (hmData0.a >= 0.5 || hmData1.a >= 0.5 || hmData2.a >= 0.5)
|
||||
{
|
||||
triangles[i0] = i0;
|
||||
triangles[i1] = i0;
|
||||
triangles[i2] = i0;
|
||||
removedLeafCount += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
triangles[i0] = i0;
|
||||
triangles[i1] = i1;
|
||||
triangles[i2] = i2;
|
||||
}
|
||||
|
||||
if (albedoToVertexColorMode == GAlbedoToVertexColorMode.Sharp)
|
||||
{
|
||||
uvc = (uv0 + uv1 + uv2) / 3f;
|
||||
color = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uvc);
|
||||
colors[i0] = color;
|
||||
colors[i1] = color;
|
||||
colors[i2] = color;
|
||||
}
|
||||
else if (albedoToVertexColorMode == GAlbedoToVertexColorMode.Smooth)
|
||||
{
|
||||
colors[i0] = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uv0);
|
||||
colors[i1] = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uv1);
|
||||
colors[i2] = GGeometryJobUtilities.GetColorBilinear(albedoMap, ref uv2);
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplaceUV(ref Vector2 uv)
|
||||
{
|
||||
if (uv.x == 0 || uv.y == 0 || uv.x == 1 || uv.y == 1)
|
||||
return;
|
||||
|
||||
Random rnd = Random.CreateFromIndex((uint)(displacementSeed ^ (uint)(uv.x * 1000) ^ (uint)(uv.y * 1000)));
|
||||
float noise0 = rnd.NextFloat() - 0.5f;
|
||||
float noise1 = rnd.NextFloat() - 0.5f;
|
||||
|
||||
Vector2 v = new Vector2(noise0 * displacementStrength / terrainSize.x, noise1 * displacementStrength / terrainSize.z);
|
||||
uv.Set(
|
||||
Mathf.Clamp01(uv.x + v.x),
|
||||
Mathf.Clamp01(uv.y + v.y));
|
||||
}
|
||||
|
||||
private void GetHeightMapData(ref Color data, ref Vector2 uv)
|
||||
{
|
||||
Color sample = Vector4.zero;
|
||||
float sampleCount = 0f;
|
||||
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmC, ref uv);
|
||||
sampleCount += 1;
|
||||
|
||||
if (uv.x == 0 && uv.y == 0) //bottom left corner
|
||||
{
|
||||
if (hmB.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmB, Flip(ref uv, false, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
if (hmL.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmL, Flip(ref uv, true, false));
|
||||
sampleCount += 1;
|
||||
}
|
||||
if (hmBL.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmBL, Flip(ref uv, true, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
}
|
||||
else if (uv.x == 0 && uv.y == 1) //top left corner
|
||||
{
|
||||
if (hmT.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmT, Flip(ref uv, false, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
if (hmL.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmL, Flip(ref uv, true, false));
|
||||
sampleCount += 1;
|
||||
}
|
||||
if (hmTL.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmTL, Flip(ref uv, true, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
}
|
||||
else if (uv.x == 1 && uv.y == 1) //top right corner
|
||||
{
|
||||
if (hmT.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmT, Flip(ref uv, false, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
if (hmR.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmR, Flip(ref uv, true, false));
|
||||
sampleCount += 1;
|
||||
}
|
||||
if (hmTR.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmTR, Flip(ref uv, true, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
}
|
||||
else if (uv.x == 1 && uv.y == 0) //bottom right corner
|
||||
{
|
||||
if (hmB.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmB, Flip(ref uv, false, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
if (hmR.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmR, Flip(ref uv, true, false));
|
||||
sampleCount += 1;
|
||||
}
|
||||
if (hmBR.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmBR, Flip(ref uv, true, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
}
|
||||
else if (uv.x == 0) //left edge
|
||||
{
|
||||
if (hmL.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmL, Flip(ref uv, true, false));
|
||||
sampleCount += 1;
|
||||
}
|
||||
}
|
||||
else if (uv.y == 1) //top edge
|
||||
{
|
||||
if (hmT.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmT, Flip(ref uv, false, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
}
|
||||
else if (uv.x == 1) //right edge
|
||||
{
|
||||
if (hmR.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmR, Flip(ref uv, true, false));
|
||||
sampleCount += 1;
|
||||
}
|
||||
}
|
||||
else if (uv.y == 0) //bottom edge
|
||||
{
|
||||
if (hmB.IsValid)
|
||||
{
|
||||
sample += GGeometryJobUtilities.GetColorBilinear(hmB, Flip(ref uv, false, true));
|
||||
sampleCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
data = sample / sampleCount;
|
||||
}
|
||||
|
||||
private float DecodeFloatRG(ref Vector2 enc)
|
||||
{
|
||||
Vector2 kDecodeDot = new Vector2(1.0f, 1f / 255.0f);
|
||||
return Vector2.Dot(enc, kDecodeDot);
|
||||
}
|
||||
|
||||
private void GetHeightSample(ref float sample, ref Color data)
|
||||
{
|
||||
Vector2 enc = new Vector2(data.r, data.g);
|
||||
sample = DecodeFloatRG(ref enc);
|
||||
}
|
||||
|
||||
private Vector2 Flip(ref Vector2 uv, bool flipX, bool flipY)
|
||||
{
|
||||
Vector2 v = new Vector2(
|
||||
flipX ? 1 - uv.x : uv.x,
|
||||
flipY ? 1 - uv.y : uv.y);
|
||||
return v;
|
||||
}
|
||||
|
||||
private Vector3 GetSmoothNormal(ref Vector2 uv, ref Vector3 v)
|
||||
{
|
||||
Color hmData = Color.black;
|
||||
Vector2 sampleUV = Vector2.zero;
|
||||
|
||||
//bl
|
||||
sampleUV.Set(uv.x - texelSize, uv.y - texelSize);
|
||||
GetHeightMapData(ref hmData, ref sampleUV);
|
||||
float h0 = 0;
|
||||
GetHeightSample(ref h0, ref hmData);
|
||||
Vector3 v0 = new Vector3(sampleUV.x * terrainSize.x, h0 * terrainSize.y, sampleUV.y * terrainSize.z);
|
||||
|
||||
//l
|
||||
sampleUV.Set(uv.x - texelSize, uv.y);
|
||||
GetHeightMapData(ref hmData, ref sampleUV);
|
||||
float h1 = 0;
|
||||
GetHeightSample(ref h1, ref hmData);
|
||||
Vector3 v1 = new Vector3(sampleUV.x * terrainSize.x, h1 * terrainSize.y, sampleUV.y * terrainSize.z);
|
||||
|
||||
//tl
|
||||
sampleUV.Set(uv.x - texelSize, uv.y + texelSize);
|
||||
GetHeightMapData(ref hmData, ref sampleUV);
|
||||
float h2 = 0;
|
||||
GetHeightSample(ref h2, ref hmData);
|
||||
Vector3 v2 = new Vector3(sampleUV.x * terrainSize.x, h2 * terrainSize.y, sampleUV.y * terrainSize.z);
|
||||
|
||||
//t
|
||||
sampleUV.Set(uv.x, uv.y + texelSize);
|
||||
GetHeightMapData(ref hmData, ref sampleUV);
|
||||
float h3 = 0;
|
||||
GetHeightSample(ref h3, ref hmData);
|
||||
Vector3 v3 = new Vector3(sampleUV.x * terrainSize.x, h3 * terrainSize.y, sampleUV.y * terrainSize.z);
|
||||
|
||||
//tr
|
||||
sampleUV.Set(uv.x + texelSize, uv.y + texelSize);
|
||||
GetHeightMapData(ref hmData, ref sampleUV);
|
||||
float h4 = 0;
|
||||
GetHeightSample(ref h4, ref hmData);
|
||||
Vector3 v4 = new Vector3(sampleUV.x * terrainSize.x, h4 * terrainSize.y, sampleUV.y * terrainSize.z);
|
||||
|
||||
//r
|
||||
sampleUV.Set(uv.x + texelSize, uv.y);
|
||||
GetHeightMapData(ref hmData, ref sampleUV);
|
||||
float h5 = 0;
|
||||
GetHeightSample(ref h5, ref hmData);
|
||||
Vector3 v5 = new Vector3(sampleUV.x * terrainSize.x, h5 * terrainSize.y, sampleUV.y * terrainSize.z);
|
||||
|
||||
//br
|
||||
sampleUV.Set(uv.x + texelSize, uv.y - texelSize);
|
||||
GetHeightMapData(ref hmData, ref sampleUV);
|
||||
float h6 = 0;
|
||||
GetHeightSample(ref h6, ref hmData);
|
||||
Vector3 v6 = new Vector3(sampleUV.x * terrainSize.x, h6 * terrainSize.y, sampleUV.y * terrainSize.z);
|
||||
|
||||
//b
|
||||
sampleUV.Set(uv.x, uv.y - texelSize);
|
||||
GetHeightMapData(ref hmData, ref sampleUV);
|
||||
float h7 = 0;
|
||||
GetHeightSample(ref h7, ref hmData);
|
||||
Vector3 v7 = new Vector3(sampleUV.x * terrainSize.x, h7 * terrainSize.y, sampleUV.y * terrainSize.z);
|
||||
|
||||
Vector3 n0 = Vector3.Cross(v0 - v, v1 - v);
|
||||
Vector3 n1 = Vector3.Cross(v1 - v, v2 - v);
|
||||
Vector3 n2 = Vector3.Cross(v2 - v, v3 - v);
|
||||
Vector3 n3 = Vector3.Cross(v3 - v, v4 - v);
|
||||
Vector3 n4 = Vector3.Cross(v4 - v, v5 - v);
|
||||
Vector3 n5 = Vector3.Cross(v5 - v, v6 - v);
|
||||
Vector3 n6 = Vector3.Cross(v6 - v, v7 - v);
|
||||
Vector3 n7 = Vector3.Cross(v7 - v, v0 - v);
|
||||
|
||||
Vector3 n = (n0 + n1 + n2 + n3 + n4 + n5 + n6 + n7) / 8.0f;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
private float GetSmoothNormalMask(ref Vector2 uv)
|
||||
{
|
||||
return GGeometryJobUtilities.GetColorPoint(maskMap, uv).g;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2be7dce7f860fe945bceea6341579223
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,137 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
public struct GGeometryJobUtilities
|
||||
{
|
||||
public const float SUB_DIV_STEP = 0.1f;
|
||||
public const byte STATE_NOT_CREATED = 0;
|
||||
public const byte STATE_CREATED = 1;
|
||||
public const byte STATE_LEAF = 2;
|
||||
|
||||
public const int VERTEX_MARKER_DIMENSION = 256;
|
||||
|
||||
public const int METADATA_LEAF_COUNT = 0;
|
||||
public const int METADATA_LEAF_REMOVED = 1;
|
||||
public const int METADATA_NEW_VERTEX_CREATED = 2;
|
||||
public const int METADATA_LENGTH = 3;
|
||||
|
||||
public static int GetStartIndex(ref int resolution)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < resolution; ++i)
|
||||
{
|
||||
count += Mathf.FloorToInt(Mathf.Pow(2, i));
|
||||
}
|
||||
count *= 2;
|
||||
return count;
|
||||
}
|
||||
|
||||
public static Color GetColorBilinear(GTextureNativeDataDescriptor<Color32> tex, Vector2 uv)
|
||||
{
|
||||
return GetColorBilinear(tex, ref uv);
|
||||
}
|
||||
|
||||
public static Color GetColorBilinear(GTextureNativeDataDescriptor<Color32> tex, ref Vector2 uv)
|
||||
{
|
||||
Vector2 pixelCoord = new Vector2(
|
||||
Mathf.Lerp(0, tex.width - 1, uv.x),
|
||||
Mathf.Lerp(0, tex.height - 1, uv.y));
|
||||
//apply a bilinear filter
|
||||
int xFloor = Mathf.FloorToInt(pixelCoord.x);
|
||||
int xCeil = Mathf.CeilToInt(pixelCoord.x);
|
||||
int yFloor = Mathf.FloorToInt(pixelCoord.y);
|
||||
int yCeil = Mathf.CeilToInt(pixelCoord.y);
|
||||
|
||||
Color f00 = tex.data[To1DIndex(ref xFloor, ref yFloor, ref tex.width)];
|
||||
Color f01 = tex.data[To1DIndex(ref xFloor, ref yCeil, ref tex.width)];
|
||||
Color f10 = tex.data[To1DIndex(ref xCeil, ref yFloor, ref tex.width)];
|
||||
Color f11 = tex.data[To1DIndex(ref xCeil, ref yCeil, ref tex.width)];
|
||||
|
||||
Vector2 unitCoord = new Vector2(
|
||||
pixelCoord.x - xFloor,
|
||||
pixelCoord.y - yFloor);
|
||||
|
||||
Color color =
|
||||
f00 * (1 - unitCoord.x) * (1 - unitCoord.y) +
|
||||
f01 * (1 - unitCoord.x) * unitCoord.y +
|
||||
f10 * unitCoord.x * (1 - unitCoord.y) +
|
||||
f11 * unitCoord.x * unitCoord.y;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
public static Color GetColorPoint(GTextureNativeDataDescriptor<Color32> tex, Vector2 uv)
|
||||
{
|
||||
Vector2 pixelCoord = new Vector2(
|
||||
Mathf.Lerp(0, tex.width - 1, uv.x),
|
||||
Mathf.Lerp(0, tex.height - 1, uv.y));
|
||||
|
||||
int xFloor = Mathf.FloorToInt(pixelCoord.x);
|
||||
int yFloor = Mathf.FloorToInt(pixelCoord.y);
|
||||
return tex.data[To1DIndex(ref xFloor, ref yFloor, ref tex.width)];
|
||||
}
|
||||
|
||||
public static int To1DIndex(ref int x, ref int y, ref int width)
|
||||
{
|
||||
return y * width + x;
|
||||
}
|
||||
|
||||
public static void GetChildrenNodeIndex(ref int index, ref int leftIndex, ref int rightIndex)
|
||||
{
|
||||
leftIndex = (index + 1) * 2;
|
||||
rightIndex = (index + 1) * 2 + 1;
|
||||
}
|
||||
|
||||
public static int GetElementCountForSubdivLevel(ref int level)
|
||||
{
|
||||
return 2 * Mathf.FloorToInt(Mathf.Pow(2, level));
|
||||
}
|
||||
|
||||
public static void NormalizeToPoint(ref Vector2 uv, ref Rect uvRect, ref Vector2 nodeVertex)
|
||||
{
|
||||
uv.x = Mathf.Lerp(uvRect.min.x, uvRect.max.x, nodeVertex.x);
|
||||
uv.y = Mathf.Lerp(uvRect.min.y, uvRect.max.y, nodeVertex.y);
|
||||
}
|
||||
|
||||
public static void MarkVertex(ref NativeArray<bool> markerArray, ref Vector2 p)
|
||||
{
|
||||
int dimension = VERTEX_MARKER_DIMENSION;
|
||||
int x = (int)(p.x * (dimension - 1));
|
||||
int y = (int)(p.y * (dimension - 1));
|
||||
markerArray[GGeometryJobUtilities.To1DIndex(ref x, ref y, ref dimension)] = true;
|
||||
}
|
||||
|
||||
public static void MarkVertices(ref NativeArray<bool> markerArray, ref GSubdivNode n)
|
||||
{
|
||||
MarkVertex(ref markerArray, ref n.v0);
|
||||
MarkVertex(ref markerArray, ref n.v1);
|
||||
MarkVertex(ref markerArray, ref n.v2);
|
||||
}
|
||||
|
||||
public static bool GetVertexMark(NativeArray<bool> markers, Vector2 p, bool flipX = false, bool flipY = false)
|
||||
{
|
||||
if (flipX)
|
||||
{
|
||||
p.x = 1 - p.x;
|
||||
}
|
||||
if (flipY)
|
||||
{
|
||||
p.y = 1 - p.y;
|
||||
}
|
||||
|
||||
int dimension = VERTEX_MARKER_DIMENSION;
|
||||
int x = (int)(p.x * (dimension - 1));
|
||||
int y = (int)(p.y * (dimension - 1));
|
||||
//mark = markerArray[GGeometryJobUtilities.To1DIndex(ref x, ref y, ref dimension)];
|
||||
return markers[GGeometryJobUtilities.To1DIndex(ref x, ref y, ref dimension)];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 523c64d82f44f7b44acb4b567828e540
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,97 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
#if GRIFFIN_BURST
|
||||
[BurstCompile(CompileSynchronously = false)]
|
||||
#endif
|
||||
public struct GSplitBaseTreeForDynamicPolygonJob : IJob
|
||||
{
|
||||
[ReadOnly]
|
||||
public GTextureNativeDataDescriptor<Color32> subdivMap;
|
||||
|
||||
public NativeArray<GSubdivNode> baseTree;
|
||||
[WriteOnly]
|
||||
public NativeArray<bool> vertexMarker;
|
||||
public NativeArray<byte> creationState;
|
||||
|
||||
public int baseResolution;
|
||||
public int resolution;
|
||||
public int lod;
|
||||
public Rect uvRect;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
int startIndex = 0;
|
||||
int endIndex = 0;
|
||||
int leftNodeIndex = 0;
|
||||
int rightNodeIndex = 0;
|
||||
|
||||
GSubdivNode currentNode;
|
||||
GSubdivNode leftNode = new GSubdivNode();
|
||||
GSubdivNode rightNode = new GSubdivNode();
|
||||
|
||||
Vector2 uv0 = Vector2.zero;
|
||||
Vector2 uv1 = Vector2.zero;
|
||||
Vector2 uv2 = Vector2.zero;
|
||||
Vector2 uvc = Vector2.zero;
|
||||
|
||||
float r0 = 0;
|
||||
float r1 = 0;
|
||||
float r2 = 0;
|
||||
float rc = 0;
|
||||
float rMax = 0;
|
||||
int subDivLevel = 0;
|
||||
|
||||
baseResolution = Mathf.Max(0, baseResolution - lod);
|
||||
resolution = Mathf.Max(0, resolution - lod);
|
||||
|
||||
int maxLevel = baseResolution + Mathf.Min(Mathf.FloorToInt(1f / GGeometryJobUtilities.SUB_DIV_STEP), resolution - baseResolution);
|
||||
|
||||
for (int res = baseResolution; res < maxLevel; ++res)
|
||||
{
|
||||
startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
|
||||
endIndex = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
|
||||
for (int i = startIndex; i <= endIndex; ++i)
|
||||
{
|
||||
if (creationState[i] != GGeometryJobUtilities.STATE_CREATED)
|
||||
continue;
|
||||
currentNode = baseTree[i];
|
||||
GGeometryJobUtilities.NormalizeToPoint(ref uv0, ref uvRect, ref currentNode.v0);
|
||||
GGeometryJobUtilities.NormalizeToPoint(ref uv1, ref uvRect, ref currentNode.v1);
|
||||
GGeometryJobUtilities.NormalizeToPoint(ref uv2, ref uvRect, ref currentNode.v2);
|
||||
uvc = (uv0 + uv1 + uv2) / 3;
|
||||
|
||||
r0 = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uv0).r;
|
||||
r1 = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uv1).r;
|
||||
r2 = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uv2).r;
|
||||
rc = GGeometryJobUtilities.GetColorBilinear(subdivMap, ref uvc).r;
|
||||
|
||||
rMax = Mathf.Max(Mathf.Max(r0, r1), Mathf.Max(r2, rc));
|
||||
|
||||
subDivLevel = baseResolution + (int)(rMax / GGeometryJobUtilities.SUB_DIV_STEP);
|
||||
if (subDivLevel <= res)
|
||||
continue;
|
||||
|
||||
GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);
|
||||
currentNode.Split(ref leftNode, ref rightNode);
|
||||
|
||||
baseTree[leftNodeIndex] = leftNode;
|
||||
creationState[leftNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
|
||||
GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref leftNode);
|
||||
|
||||
baseTree[rightNodeIndex] = rightNode;
|
||||
creationState[rightNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
|
||||
GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref rightNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0ef3bb199eac274f954074ecc25cbfe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,157 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Jobs;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
#if GRIFFIN_BURST
|
||||
[BurstCompile(CompileSynchronously = false)]
|
||||
#endif
|
||||
public struct GStitchSeamJob : IJob
|
||||
{
|
||||
public NativeArray<GSubdivNode> nodes;
|
||||
public NativeArray<byte> creationState;
|
||||
public NativeArray<int> metadata;
|
||||
|
||||
public NativeArray<bool> vertexMarker;
|
||||
|
||||
[ReadOnly]
|
||||
public NativeArray<bool> vertexMarkerLeft;
|
||||
public bool hasLeftMarker;
|
||||
|
||||
[ReadOnly]
|
||||
public NativeArray<bool> vertexMarkerTop;
|
||||
public bool hasTopMarker;
|
||||
|
||||
[ReadOnly]
|
||||
public NativeArray<bool> vertexMarkerRight;
|
||||
public bool hasRightMarker;
|
||||
|
||||
[ReadOnly]
|
||||
public NativeArray<bool> vertexMarkerBottom;
|
||||
public bool hasBottomMarker;
|
||||
|
||||
public int meshBaseResolution;
|
||||
public int meshResolution;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
int startIndex = 0;
|
||||
int endIndex = 0;
|
||||
int leftNodeIndex = 0;
|
||||
int rightNodeIndex = 0;
|
||||
bool mark0 = false;
|
||||
bool mark1 = false;
|
||||
bool mark2 = false;
|
||||
bool mark3 = false;
|
||||
bool mark4 = false;
|
||||
bool mark5 = false;
|
||||
Vector2 v12 = Vector2.zero;
|
||||
|
||||
GSubdivNode currentNode;
|
||||
GSubdivNode leftNode = new GSubdivNode();
|
||||
GSubdivNode rightNode = new GSubdivNode();
|
||||
|
||||
metadata[GGeometryJobUtilities.METADATA_NEW_VERTEX_CREATED] = 0;
|
||||
for (int res = meshBaseResolution; res < meshResolution; ++res)
|
||||
{
|
||||
startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
|
||||
endIndex = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
|
||||
for (int i = startIndex; i <= endIndex; ++i)
|
||||
{
|
||||
GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);
|
||||
if (creationState[leftNodeIndex] != GGeometryJobUtilities.STATE_NOT_CREATED ||
|
||||
creationState[rightNodeIndex] != GGeometryJobUtilities.STATE_NOT_CREATED)
|
||||
continue;
|
||||
currentNode = nodes[i];
|
||||
mark0 = GGeometryJobUtilities.GetVertexMark(vertexMarker, currentNode.v01);
|
||||
mark1 = GGeometryJobUtilities.GetVertexMark(vertexMarker, currentNode.v12);
|
||||
mark2 = GGeometryJobUtilities.GetVertexMark(vertexMarker, currentNode.v20);
|
||||
mark3 = CheckMarkNeighbor(currentNode.v01);
|
||||
mark4 = CheckMarkNeighbor(currentNode.v12);
|
||||
mark5 = CheckMarkNeighbor(currentNode.v20);
|
||||
|
||||
if (mark0 || mark1 || mark2 ||
|
||||
mark3 || mark4 || mark5)
|
||||
{
|
||||
currentNode.Split(ref leftNode, ref rightNode);
|
||||
nodes[leftNodeIndex] = leftNode;
|
||||
nodes[rightNodeIndex] = rightNode;
|
||||
creationState[leftNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
|
||||
creationState[rightNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
|
||||
GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref leftNode);
|
||||
GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref rightNode);
|
||||
|
||||
metadata[GGeometryJobUtilities.METADATA_NEW_VERTEX_CREATED] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckMarkNeighbor(Vector2 p)
|
||||
{
|
||||
if (p.x > 0 && p.x < 1 &&
|
||||
p.y > 0 && p.y < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p.x == 0)
|
||||
{
|
||||
if (hasLeftMarker)
|
||||
{
|
||||
return GGeometryJobUtilities.GetVertexMark(vertexMarkerLeft, p, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (p.x == 1)
|
||||
{
|
||||
if (hasRightMarker)
|
||||
{
|
||||
return GGeometryJobUtilities.GetVertexMark(vertexMarkerRight, p, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (p.y == 0)
|
||||
{
|
||||
if (hasBottomMarker)
|
||||
{
|
||||
return GGeometryJobUtilities.GetVertexMark(vertexMarkerBottom, p, false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (p.y == 1)
|
||||
{
|
||||
if (hasTopMarker)
|
||||
{
|
||||
return GGeometryJobUtilities.GetVertexMark(vertexMarkerTop, p, false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 150b0c4580f6072408eadaad47f49f5c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,98 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
#if GRIFFIN_BURST
|
||||
[BurstCompile(CompileSynchronously = false)]
|
||||
#endif
|
||||
public struct GStitchSeamLODJob : IJob
|
||||
{
|
||||
public NativeArray<GSubdivNode> nodes;
|
||||
public NativeArray<byte> creationState;
|
||||
public NativeArray<int> metadata;
|
||||
|
||||
public NativeArray<bool> vertexMarker;
|
||||
|
||||
[ReadOnly]
|
||||
public NativeArray<bool> vertexMarker_LOD0;
|
||||
|
||||
public int meshBaseResolution;
|
||||
public int meshResolution;
|
||||
public int lod;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
int startIndex = 0;
|
||||
int endIndex = 0;
|
||||
int leftNodeIndex = 0;
|
||||
int rightNodeIndex = 0;
|
||||
bool mark0 = false;
|
||||
bool mark1 = false;
|
||||
bool mark2 = false;
|
||||
bool mark3 = false;
|
||||
bool mark4 = false;
|
||||
bool mark5 = false;
|
||||
Vector2 v12 = Vector2.zero;
|
||||
|
||||
GSubdivNode currentNode;
|
||||
GSubdivNode leftNode = new GSubdivNode();
|
||||
GSubdivNode rightNode = new GSubdivNode();
|
||||
|
||||
meshBaseResolution = Mathf.Max(0, meshBaseResolution - lod);
|
||||
|
||||
metadata[GGeometryJobUtilities.METADATA_NEW_VERTEX_CREATED] = 0;
|
||||
for (int res = meshBaseResolution; res < meshResolution; ++res)
|
||||
{
|
||||
startIndex = GGeometryJobUtilities.GetStartIndex(ref res);
|
||||
endIndex = startIndex + GGeometryJobUtilities.GetElementCountForSubdivLevel(ref res) - 1;
|
||||
for (int i = startIndex; i <= endIndex; ++i)
|
||||
{
|
||||
GGeometryJobUtilities.GetChildrenNodeIndex(ref i, ref leftNodeIndex, ref rightNodeIndex);
|
||||
if (creationState[leftNodeIndex] != GGeometryJobUtilities.STATE_NOT_CREATED ||
|
||||
creationState[rightNodeIndex] != GGeometryJobUtilities.STATE_NOT_CREATED)
|
||||
continue;
|
||||
currentNode = nodes[i];
|
||||
mark0 = GGeometryJobUtilities.GetVertexMark(vertexMarker, currentNode.v01);
|
||||
mark1 = GGeometryJobUtilities.GetVertexMark(vertexMarker, currentNode.v12);
|
||||
mark2 = GGeometryJobUtilities.GetVertexMark(vertexMarker, currentNode.v20);
|
||||
mark3 = CheckMarkLOD0(currentNode.v01);
|
||||
mark4 = CheckMarkLOD0(currentNode.v12);
|
||||
mark5 = CheckMarkLOD0(currentNode.v20);
|
||||
|
||||
if (mark0 || mark1 || mark2 ||
|
||||
mark3 || mark4 || mark5)
|
||||
{
|
||||
currentNode.Split(ref leftNode, ref rightNode);
|
||||
nodes[leftNodeIndex] = leftNode;
|
||||
nodes[rightNodeIndex] = rightNode;
|
||||
creationState[leftNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
|
||||
creationState[rightNodeIndex] = GGeometryJobUtilities.STATE_CREATED;
|
||||
GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref leftNode);
|
||||
GGeometryJobUtilities.MarkVertices(ref vertexMarker, ref rightNode);
|
||||
|
||||
metadata[GGeometryJobUtilities.METADATA_NEW_VERTEX_CREATED] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckMarkLOD0(Vector2 p)
|
||||
{
|
||||
if (p.x > 0 && p.x < 1 && p.y > 0 && p.y < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GGeometryJobUtilities.GetVertexMark(vertexMarker_LOD0, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 993121c278eabad4287b1f30014b3561
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5147b374a7868594d8247ce15fb892f4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,45 @@
|
||||
#if GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Pinwheel.Griffin
|
||||
{
|
||||
#if GRIFFIN_BURST
|
||||
[BurstCompile(CompileSynchronously = false)]
|
||||
#endif
|
||||
public struct GBuildRaycastCommandJob : IJobParallelFor
|
||||
{
|
||||
[ReadOnly]
|
||||
public NativeArray<Rect> dirtyRects;
|
||||
[ReadOnly]
|
||||
public NativeArray<Vector2> positions;
|
||||
|
||||
[WriteOnly]
|
||||
public NativeArray<RaycastCommand> commands;
|
||||
|
||||
public int mask;
|
||||
public int maxHit;
|
||||
public Vector3 terrainPosition;
|
||||
public Vector3 terrainSize;
|
||||
|
||||
public void Execute(int index)
|
||||
{
|
||||
Vector2 pos = positions[index];
|
||||
|
||||
Vector3 from = new Vector3(terrainPosition.x + pos.x * terrainSize.x, 10000, terrainPosition.z + pos.y * terrainSize.z);
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
QueryParameters q = new QueryParameters(mask, false, QueryTriggerInteraction.Ignore, false);
|
||||
RaycastCommand cmd = new RaycastCommand(from, Vector3.down, q, float.MaxValue);
|
||||
#else
|
||||
RaycastCommand cmd = new RaycastCommand(from, Vector3.down, float.MaxValue, mask, 1);
|
||||
#endif
|
||||
|
||||
commands[index] = cmd;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0dbd4a26d6cf63419cb54a389bbb5a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user