diff --git a/Distribution/Restock/GameData/ReStock/Plugins/Restock.dll b/Distribution/Restock/GameData/ReStock/Plugins/Restock.dll index 63670a46..12e00d2c 100644 Binary files a/Distribution/Restock/GameData/ReStock/Plugins/Restock.dll and b/Distribution/Restock/GameData/ReStock/Plugins/Restock.dll differ diff --git a/Source/Restock/LaunchClampGirderFactory.cs b/Source/Restock/LaunchClampGirderFactory.cs new file mode 100644 index 00000000..b99f0d69 --- /dev/null +++ b/Source/Restock/LaunchClampGirderFactory.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace Restock +{ + public class LaunchClampGirderFactory : ScriptableObject + { + public Mesh girderSegmentMesh; + + [SerializeField] private Mesh[] _girderMeshCache; + [SerializeField] private int _maxLength; + + private float _girderSegmentHeight; + private bool _girderHasTangents; + private bool _girderHasColors; + private int _girderVertCount; + private int _girderTriCount; + + private int _girderSegments; + private List _girderVerts; + private List _girderUVs; + private List _girderNormals; + private List _girderTangents; + private List _girderColors; + private List _girderTris; + + public void Initialize(Mesh girderSegmentMesh, float girderSegmentHeight, int maxLength = 100) + { + this.girderSegmentMesh = girderSegmentMesh; + + _girderSegmentHeight = girderSegmentHeight; + _maxLength = maxLength; + _girderMeshCache = new Mesh[maxLength]; + + _girderMeshCache[0] = new Mesh(); + _girderMeshCache[1] = girderSegmentMesh; + + _girderVertCount = girderSegmentMesh.vertexCount; + _girderTriCount = girderSegmentMesh.triangles.Length; + + _girderVerts = new List(girderSegmentMesh.vertices); + _girderUVs = new List(girderSegmentMesh.uv); + _girderNormals = new List(girderSegmentMesh.normals); + if (girderSegmentMesh.tangents.Length > 0) + { + _girderHasTangents = true; + _girderTangents = new List(girderSegmentMesh.tangents); + } + + if (girderSegmentMesh.colors32.Length > 0) + { + _girderHasColors = true; + _girderColors = new List(girderSegmentMesh.colors32); + } + + _girderTris = new List(girderSegmentMesh.triangles); + _girderSegments = 1; + } + public Mesh makeGirder(int length) + { + if (length < 0) length = 0; + if (length > _maxLength) length = _maxLength; + + if (_girderMeshCache[length] == null) + { + Debug.Log("Girder mesh not generated, making it now..."); + var girderMesh = makeGirderMesh(length); + _girderMeshCache[length] = girderMesh; + } + + return _girderMeshCache[length]; + } + + private Mesh makeGirderMesh(int length) + { + if (length < 1) + { + return new Mesh(); + } + var girderMesh = new Mesh(); + if (length > _girderSegments) + { + for (int i = _girderSegments; i < length ; i++) + { + var offset = Vector3.down * _girderSegmentHeight * i; + var indexOffset = _girderVertCount * i; + for (int v = 0; v < _girderVertCount; v++) + { + _girderVerts.Add(girderSegmentMesh.vertices[v] + offset); + } + + _girderNormals.AddRange(girderSegmentMesh.normals); + _girderUVs.AddRange(girderSegmentMesh.uv); + + if (_girderHasTangents) _girderTangents.AddRange(girderSegmentMesh.tangents); + if (_girderHasColors) _girderColors.AddRange(girderSegmentMesh.colors32); + + for (int t = 0; t < _girderTriCount; t++) + { + _girderTris.Add(girderSegmentMesh.triangles[t] + indexOffset); + } + } + } + else if (length < _girderSegments) + { + var startIndex = length * _girderVertCount; + var count = (_girderSegments - length) * _girderVertCount; + _girderVerts.RemoveRange(startIndex, count); + _girderNormals.RemoveRange(startIndex, count); + _girderUVs.RemoveRange(startIndex, count); + if (_girderHasTangents) _girderTangents.RemoveRange(startIndex, count); + if (_girderHasColors) _girderColors.RemoveRange(startIndex, count); + + _girderTris.RemoveRange(length * _girderTriCount, + (_girderSegments - length) * _girderTriCount); + } + + girderMesh.SetVertices(_girderVerts); + girderMesh.SetNormals(_girderNormals); + girderMesh.SetUVs(0, _girderUVs); + if (_girderHasTangents) girderMesh.SetTangents(_girderTangents); + if (_girderHasColors) girderMesh.SetColors(_girderColors); + girderMesh.SetTriangles(_girderTris, 0); + + girderMesh.RecalculateBounds(); + _girderSegments = length; + + return girderMesh; + } + } +} \ No newline at end of file diff --git a/Source/Restock/ModuleRestockLaunchClamp.cs b/Source/Restock/ModuleRestockLaunchClamp.cs index 130a91a8..cb07678b 100644 --- a/Source/Restock/ModuleRestockLaunchClamp.cs +++ b/Source/Restock/ModuleRestockLaunchClamp.cs @@ -17,46 +17,54 @@ namespace Restock [KSPField] public string trf_towerYoke_name = ""; [KSPField] public Mesh girderMesh; + [KSPField] public MeshFilter girderMeshFilter; + [KSPField] public float girderSegmentHeight; + public LaunchClampGirderFactory girderFactory; + + private int _girderSegments; private Material _girderMaterial; private Matrix4x4[] _girderMatrices; - - //used by non-instanced fallback girder implementation - [KSPField] public bool instancingEnabled = true; - [KSPField] public Mesh girderSegmentMesh; - - private List _girderVerts; - private List _girderUVs; - private List _girderNormals; - private List _girderTangents; - private List _girderColors; - private List _girderTris; - private bool _girderFlightUpdated = false; - private bool _girderHasTangents = false; - private bool _girderHasColors = false; - private int _girderVertCount; - private int _girderTriCount; - private int _girderSegments; + [KSPField] public bool instancingEnabled = true; public override void OnLoad(ConfigNode node) { - towerPivot = part.FindModelTransform(trf_towerPivot_name); - towerYoke = part.FindModelTransform(trf_towerYoke_name); - towerAnchor = part.FindModelTransform(trf_anchor_name); - towerGirder = part.FindModelTransform(trf_towerGirder_name); - towerStretch = part.FindModelTransform(trf_towerStretch_name); - if (!SystemInfo.supportsInstancing) + if (!HighLogic.LoadedSceneIsGame) { - this.LogWarning("You are using a computer which does not support instancing, " + - "falling back to a slower launch clamp implementation"); - instancingEnabled = false; + towerPivot = part.FindModelTransform(trf_towerPivot_name); + towerYoke = part.FindModelTransform(trf_towerYoke_name); + towerAnchor = part.FindModelTransform(trf_anchor_name); + towerGirder = part.FindModelTransform(trf_towerGirder_name); + towerStretch = part.FindModelTransform(trf_towerStretch_name); + + girderMeshFilter = towerGirder.GetComponent(); + girderMesh = girderMeshFilter.mesh; + + if (!SystemInfo.supportsInstancing) + { + this.LogWarning("You are using a computer which does not support instancing, " + + "falling back to a slower launch clamp implementation in the editor"); + instancingEnabled = false; + } + + if (girderFactory == null) + { + //Debug.Log("Making new girder factory..."); + girderSegmentHeight = Vector3.Distance(towerAnchor.position, towerStretch.position); + if (float.IsInfinity(girderSegmentHeight)) + { + girderSegmentHeight = -1f; + } + + girderFactory = ScriptableObject.CreateInstance(); + girderFactory.Initialize(girderMesh, girderSegmentHeight, maxSegments); + } } - girderMesh = towerGirder.GetComponent().mesh; - girderSegmentMesh = Instantiate(girderMesh); + _girderSegments = 1; base.OnLoad(node); } @@ -77,29 +85,6 @@ namespace Restock _girderMaterial = girderRenderer.material; _girderMaterial.enableInstancing = true; } - else - { - _girderVertCount = girderSegmentMesh.vertexCount; - _girderTriCount = girderSegmentMesh.triangles.Length; - - _girderVerts = new List(girderSegmentMesh.vertices); - _girderUVs = new List(girderSegmentMesh.uv); - _girderNormals = new List(girderSegmentMesh.normals); - if (girderSegmentMesh.tangents.Length > 0) - { - _girderHasTangents = true; - _girderTangents = new List(girderSegmentMesh.tangents); - } - - if (girderSegmentMesh.colors32.Length > 0) - { - _girderHasColors = true; - _girderColors = new List(girderSegmentMesh.colors32); - } - - _girderTris = new List(girderSegmentMesh.triangles); - _girderSegments = 1; - } } public void LateUpdate() @@ -117,26 +102,27 @@ namespace Restock girderSegments = Math.Min(girderSegments, maxSegments); girderSegments = Math.Max(girderSegments, 0); - if (HighLogic.LoadedSceneIsEditor){ + if (HighLogic.LoadedSceneIsEditor) + { if (instancingEnabled) { - UpdateGirder(girderSegments); + UpdateGirderInstanced(girderSegments); } else { - UpdateGirderFallback(girderSegments); + UpdateGirderMesh(girderSegments); } } else { if (_girderFlightUpdated) return; - - UpdateGirderFallback(girderSegments); + + UpdateGirderMesh(girderSegments); _girderFlightUpdated = true; } } - private void UpdateGirder(int girderSegments) + private void UpdateGirderInstanced(int girderSegments) { var matrix = towerGirder.localToWorldMatrix; var offset = Matrix4x4.Translate(towerGirder.TransformVector(Vector3.down * initialHeight)); @@ -151,58 +137,11 @@ namespace Restock UnityEngine.Rendering.ShadowCastingMode.On, true, towerGirder.gameObject.layer); } - private void UpdateGirderFallback(int newGirderSegments) + private void UpdateGirderMesh(int girderSegments) { - if (newGirderSegments == _girderSegments) return; - - if (newGirderSegments > _girderSegments) - { - for (int i = _girderSegments; i < newGirderSegments; i++) - { - var offset = Vector3.down * base.initialHeight * i; - var indexOffset = _girderVertCount * i; - for (int v = 0; v < _girderVertCount; v++) - { - _girderVerts.Add(girderSegmentMesh.vertices[v] + offset); - } - - _girderNormals.AddRange(girderSegmentMesh.normals); - _girderUVs.AddRange(girderSegmentMesh.uv); - - if (_girderHasTangents) _girderTangents.AddRange(girderSegmentMesh.tangents); - if (_girderHasColors) _girderColors.AddRange(girderSegmentMesh.colors32); - - for (int t = 0; t < _girderTriCount; t++) - { - _girderTris.Add(girderSegmentMesh.triangles[t] + indexOffset); - } - } - } - else if (newGirderSegments < _girderSegments) - { - var startIndex = newGirderSegments * _girderVertCount; - var count = (_girderSegments - newGirderSegments) * _girderVertCount; - _girderVerts.RemoveRange(startIndex, count); - _girderNormals.RemoveRange(startIndex, count); - _girderUVs.RemoveRange(startIndex, count); - if (_girderHasTangents) _girderTangents.RemoveRange(startIndex, count); - if (_girderHasColors) _girderColors.RemoveRange(startIndex, count); - - _girderTris.RemoveRange(newGirderSegments * _girderTriCount, - (_girderSegments - newGirderSegments) * _girderTriCount); - } - - girderMesh.Clear(); - - girderMesh.SetVertices(_girderVerts); - girderMesh.SetNormals(_girderNormals); - girderMesh.SetUVs(0, _girderUVs); - if (_girderHasTangents) girderMesh.SetTangents(_girderTangents); - if (_girderHasColors) girderMesh.SetColors(_girderColors); - girderMesh.SetTriangles(_girderTris, 0); + if (girderSegments == _girderSegments) return; - girderMesh.RecalculateBounds(); - _girderSegments = newGirderSegments; + girderMeshFilter.mesh = girderFactory.makeGirder(girderSegments); } } } \ No newline at end of file diff --git a/Source/Restock/Restock.csproj b/Source/Restock/Restock.csproj index 8c469675..0af3b1f7 100644 --- a/Source/Restock/Restock.csproj +++ b/Source/Restock/Restock.csproj @@ -49,6 +49,7 @@ +