This commit is contained in:
CortexCore
2025-03-14 21:04:19 +08:00
parent ff8670c453
commit 757ffe79ee
1282 changed files with 104378 additions and 3 deletions

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5dc35b67709ef0c40b43db9e53709643
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fa9a62b0cdcbde94bbc2ef579b40b66e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 048c6de9bdbf90449b521a95d0bdd8c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7a08652ec214402438899dc29d8a96cd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8e54b1d91fbf090499aa1e288f351c90
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 15922952102050f4ca8749746dab17b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8f8fc18bd68e0614d863368ba7090a0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f270994961c3fd4bb73daffd125df91
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26a21f6f7edca374087db358e5295f19
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc03e06c54fe53c4c8f0306294414814
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ea53212566efad49ba506844b5af0a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3bf7d1e6b2bda7347beb70dfd6084147
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 33cf88d404de74c4eb8b58bc59ef578e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 542a2fe26c3dfb947afd5eb27e809a5c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 027703dec96d8b645a33649b533b923b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8a737aaad43220b4a9635c682c6a3814
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2be7dce7f860fe945bceea6341579223
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 523c64d82f44f7b44acb4b567828e540
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e0ef3bb199eac274f954074ecc25cbfe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 150b0c4580f6072408eadaad47f49f5c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 993121c278eabad4287b1f30014b3561
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5147b374a7868594d8247ce15fb892f4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e0dbd4a26d6cf63419cb54a389bbb5a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: