Initial Commit

This commit is contained in:
2025-07-04 20:33:06 +03:00
commit 8f09347ae0
9219 changed files with 2447903 additions and 0 deletions
@@ -0,0 +1,98 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Laplacian smoothens an input unity Mesh providing
/// an output one
/// </summary>
public class LaplaceSmoothEditor : EditorWindow
{
public int numIterations = 20;
public double relaxationFactor = 0.01;
public double convergence = 0.0;
public double featureAngle = 45.0;
public double edgeAngle = 15.0;
public bool featureEdgeSmoothing = false;
public bool boundarySmoothing = true;
public Mesh inputMesh = null;
public Mesh outputMesh = null;
public static void Init(Mesh inputMesh, Mesh outputMesh)
{
LaplaceSmoothEditor window = GetWindow(typeof(LaplaceSmoothEditor)) as LaplaceSmoothEditor;
window.inputMesh = inputMesh;
window.outputMesh = outputMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
inputMesh = EditorGUILayout.ObjectField("Input Mesh: ", inputMesh, typeof(Mesh), true) as Mesh;
int tNumIterations = EditorGUILayout.IntField("Number Of Smoothing Iterations: ", numIterations);
double tRelaxationFactor = EditorGUILayout.DoubleField("Relaxation Factor: ", relaxationFactor);
double tConvergence = EditorGUILayout.DoubleField("Convergence: ", convergence);
double tFeatureAngle = EditorGUILayout.DoubleField("Feature Angle: ", featureAngle);
double tEdgeAngle = EditorGUILayout.DoubleField("Edge Angle: ", edgeAngle);
bool tFeatureEdgeSmoothing = EditorGUILayout.Toggle("Use Feature Edge Smoothing: ", featureEdgeSmoothing);
bool tBoundarySmoothing = EditorGUILayout.Toggle("Use Boundary Smoothing: ", boundarySmoothing);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
numIterations = MathUtil.Max(tNumIterations, 1);
relaxationFactor = MathUtil.Max(tRelaxationFactor, 0.0);
convergence = MathUtil.Max(tConvergence, 0.0);
featureAngle = MathUtil.Max(tFeatureAngle, 0.0);
edgeAngle = MathUtil.Max(tEdgeAngle, 0.0);
featureEdgeSmoothing = tFeatureEdgeSmoothing;
boundarySmoothing = tBoundarySmoothing;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
Imstk.SurfaceMesh surfMesh = inputMesh.ToImstkGeometry() as Imstk.SurfaceMesh;
Imstk.SurfaceMeshSmoothen smoothen = new Imstk.SurfaceMeshSmoothen();
smoothen.setInputMesh(surfMesh);
smoothen.setNumberOfIterations(numIterations);
smoothen.setRelaxationFactor(relaxationFactor);
smoothen.setConvergence(convergence);
smoothen.setFeatureAngle(featureAngle);
smoothen.setEdgeAngle(edgeAngle);
smoothen.setFeatureEdgeSmoothing(featureEdgeSmoothing);
smoothen.setBoundarySmoothing(boundarySmoothing);
smoothen.update();
Imstk.SurfaceMesh outputSurfMesh = Imstk.Utils.CastTo<Imstk.SurfaceMesh>(smoothen.getOutput());
GeomUtil.CopyMesh(outputSurfMesh.ToMesh(), outputMesh);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5ea044bfac569c644b427c75bffa1bd8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,102 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Generates a plane mesh for MeshFilter
/// </summary>
public class LineMeshEditor : EditorWindow
{
public Vector3 start = Vector3.zero;
public Vector3 direction = new Vector3(1.0f, 0.0f, 0.0f);
public int divisions = 10;
public double length = 1.0;
public Mesh outputMesh = null;
public static void Init(Mesh outputMesh)
{
LineMeshEditor window = GetWindow(typeof(LineMeshEditor)) as LineMeshEditor;
window.outputMesh = outputMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
outputMesh = EditorGUILayout.ObjectField("Input Mesh: ", outputMesh, typeof(Mesh), true) as Mesh;
Vector3 tStart = EditorGUILayout.Vector3Field("Start", start);
Vector3 tDirection = EditorGUILayout.Vector3Field("Direction", direction);
int tDivisions = EditorGUILayout.IntField("Divisions", divisions);
double tLength = EditorGUILayout.DoubleField("Length", length);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
start = tStart;
direction = tDirection;
if (direction == Vector3.zero)
{
direction = new Vector3(1.0f, 0.0f, 0.0f);
}
divisions = Mathf.Max(tDivisions, 1);
length = MathUtil.Max(tLength, 0.0);
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
int numVerts = divisions + 1;
int numCells = divisions;
Vector3[] vertices = new Vector3[numVerts];
int[] indices = new int[numCells * 2];
direction = direction.normalized;
for (int i = 0; i < numVerts; i++)
{
float t = (float)i / (numVerts - 1); // 0-1
vertices[i] = start + direction * t * (float)length;
}
for (int i = 0; i < numCells; i++)
{
indices[i * 2] = i;
indices[i * 2 + 1] = i + 1;
}
outputMesh.triangles = null;
outputMesh.normals = null;
outputMesh.tangents = null;
outputMesh.vertices = vertices;
outputMesh.SetIndices(indices, MeshTopology.Lines, 0);
outputMesh.RecalculateBounds();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 33c64bf93157c484abdc881055be248f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,73 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Generates a plane mesh for MeshFilter
/// </summary>
public class PlaneMeshEditor : EditorWindow
{
//public Vector3 size = new Vector3(1.0f, 0.25f, 1.0f);
public Vector2Int dim = new Vector2Int(8, 8);
//public Vector3 center = new Vector3(0.0f, 0.0f, 0.0f);
public Mesh outputMesh = null;
public static void Init(Mesh outputMesh)
{
PlaneMeshEditor window = GetWindow(typeof(PlaneMeshEditor)) as PlaneMeshEditor;
window.outputMesh = outputMesh;
if (outputMesh.name.Length == 0) outputMesh.name = "plane mesh";
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
outputMesh = EditorGUILayout.ObjectField("Input Mesh: ", outputMesh, typeof(Mesh), true) as Mesh;
name = EditorGUILayout.TextField("Name: ", outputMesh.name);
//Vector3 tSize = EditorGUILayout.Vector3Field("Size: ", size);
Vector2Int tDim = EditorGUILayout.Vector2IntField("Grid Dimensions: ", dim);
//Vector3 tCenter = EditorGUILayout.Vector3Field("Center: ", center);
// \todo: How to get undo to also call UpdateInputObj?
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
//size = tSize.cwiseMax(new Vector3(0.0f, 0.0f, 0.0f));
dim = tDim.cwiseMax(new Vector2Int(2, 2));
//center = tCenter;
outputMesh.name = name;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
ImstkMesh planeMesh = Utility.GetXYPlane(dim.x, dim.y);
GeomUtil.CopyMesh(planeMesh.ToMesh(), outputMesh);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fe3bffa442f54d04ea8dcec7b28e5535
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,86 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
public enum SubdivideMeshType
{
Linear,
Loop,
Butterfly
}
/// <summary>
/// Laplacian smoothens an input unity Mesh providing
/// an output one
/// </summary>
public class SubdivideMeshEditor : EditorWindow
{
public int numSubdivisions = 1;
public Imstk.SurfaceMeshSubdivide.Type subdivType = Imstk.SurfaceMeshSubdivide.Type.LINEAR;
public Mesh inputMesh = null;
public Mesh outputMesh = null;
public static void Init(Mesh inputMesh, Mesh outputMesh)
{
SubdivideMeshEditor window = GetWindow(typeof(SubdivideMeshEditor)) as SubdivideMeshEditor;
window.inputMesh = inputMesh;
window.outputMesh = outputMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
inputMesh = EditorGUILayout.ObjectField("Input Mesh: ", inputMesh, typeof(Mesh), true) as Mesh;
int tNumSubdivisions = EditorGUILayout.IntField("Number Of Subdivisions: ", numSubdivisions);
Imstk.SurfaceMeshSubdivide.Type tSubdivType =
(Imstk.SurfaceMeshSubdivide.Type)EditorGUILayout.EnumPopup("Subdivision Type: ", subdivType);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
numSubdivisions = MathUtil.Max(tNumSubdivisions, 0);
subdivType = tSubdivType;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
Imstk.SurfaceMesh surfMesh = inputMesh.ToImstkGeometry() as Imstk.SurfaceMesh;
Imstk.SurfaceMeshSubdivide subdiv = new Imstk.SurfaceMeshSubdivide();
subdiv.setInputMesh(surfMesh);
subdiv.setNumberOfSubdivisions(numSubdivisions);
subdiv.setSubdivisionType(subdivType);
subdiv.update();
Imstk.SurfaceMesh outputSurfMesh = Imstk.Utils.CastTo<Imstk.SurfaceMesh>(subdiv.getOutput());
GeomUtil.CopyMesh(outputSurfMesh.ToMesh(), outputMesh);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3b8962d5e32621842895493399fea036
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,80 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Generates a tetrahedral mesh PhysicsGeometry
/// </summary>
public class TetrahedralGridEditor : EditorWindow
{
public Vector3 size = new Vector3(1.0f, 0.25f, 1.0f);
public Vector3Int dim = new Vector3Int(8, 4, 8);
public Vector3 center = new Vector3(0.0f, 0.0f, 0.0f);
public Mesh outputSurfMesh = null;
public ImstkMesh outputTetMesh = null;
public static void Init(
Mesh outputSurfMesh,
ImstkMesh outputTetMesh)
{
TetrahedralGridEditor window = GetWindow(typeof(TetrahedralGridEditor)) as TetrahedralGridEditor;
window.outputSurfMesh = outputSurfMesh;
window.outputTetMesh = outputTetMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
outputSurfMesh = EditorGUILayout.ObjectField("Input Surface MeshFilter: ", outputSurfMesh, typeof(Mesh), true) as Mesh;
outputTetMesh = EditorGUILayout.ObjectField("Input Tet GeometryFilter: ", outputTetMesh, typeof(ImstkMesh), true) as ImstkMesh;
Vector3 tSize = EditorGUILayout.Vector3Field("Size: ", size);
Vector3Int tDim = EditorGUILayout.Vector3IntField("Grid Dimensions: ", dim);
Vector3 tCenter = EditorGUILayout.Vector3Field("Center: ", center);
// \todo: How to get undo to also call UpdateInputObj?
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
size = tSize.cwiseMax(new Vector3(0.0f, 0.0f, 0.0f));
dim = tDim.cwiseMax(new Vector3Int(2, 2, 2));
center = tCenter;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
ImstkMesh tetMesh = Utility.GetTetGridMesh(size, dim, center);
GeomUtil.CopyMesh(tetMesh, outputTetMesh);
Imstk.TetrahedralMesh imstkTetMesh = Imstk.Utils.CastTo<Imstk.TetrahedralMesh>(tetMesh.ToImstkGeometry());
Imstk.SurfaceMesh surfMesh = imstkTetMesh.extractSurfaceMesh();
GeomUtil.CopyMesh(surfMesh.ToMesh(), outputSurfMesh);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8f18b03d2fbaf8448913420009e4e51e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,132 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
public enum UVPlaneOptions
{
XY,
YZ,
XZ,
Custom
}
/// <summary>
/// Generates UV plane coords
/// </summary>
public class UVPlaneProjectEditor : EditorWindow
{
public Vector3 planeNormal = new Vector3(0.0f, 1.0f, 0.0f);
public UVPlaneOptions planeOption = UVPlaneOptions.XZ;
public Vector2 uvScale = new Vector2(1.0f, 1.0f);
public Vector2 uvShift = Vector2.zero;
public Mesh inputMesh = null;
public Mesh outputMesh = null;
public static void Init(Mesh inputMesh, Mesh outputMesh)
{
UVPlaneProjectEditor window = GetWindow(typeof(UVPlaneProjectEditor)) as UVPlaneProjectEditor;
window.inputMesh = inputMesh;
window.outputMesh = outputMesh;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
inputMesh = EditorGUILayout.ObjectField("Input Mesh: ", inputMesh, typeof(Mesh), true) as Mesh;
Vector3 tPlaneNormal = EditorGUILayout.Vector3Field("Plane Normal: ", planeNormal);
UVPlaneOptions tPlaneOption = (UVPlaneOptions)EditorGUILayout.EnumPopup("Plane: ", planeOption);
Vector2 tUvScale = EditorGUILayout.Vector2Field("UV Scale", uvScale);
Vector2 tUvShift = EditorGUILayout.Vector2Field("UV Shift", uvShift);
// \todo: How to get undo to also call UpdateInputObj?
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
// IF the plane normal was changed
if (tPlaneNormal != planeNormal)
{
if (tPlaneNormal == new Vector3(0.0f, 1.0f, 0.0f))
{
tPlaneOption = UVPlaneOptions.XZ;
}
else if (tPlaneNormal == new Vector3(1.0f, 0.0f, 0.0f))
{
tPlaneOption = UVPlaneOptions.YZ;
}
else if (tPlaneNormal == new Vector3(0.0f, 0.0f, 1.0f))
{
tPlaneOption = UVPlaneOptions.XY;
}
else
{
tPlaneOption = UVPlaneOptions.Custom;
}
}
if (tPlaneOption != planeOption)
{
if (tPlaneOption == UVPlaneOptions.XY)
{
tPlaneNormal = new Vector3(0.0f, 0.0f, 1.0f);
}
else if (tPlaneOption == UVPlaneOptions.XZ)
{
tPlaneNormal = new Vector3(0.0f, 1.0f, 0.0f);
}
else if (tPlaneOption == UVPlaneOptions.YZ)
{
tPlaneNormal = new Vector3(1.0f, 0.0f, 0.0f);
}
}
planeNormal = tPlaneNormal;
planeOption = tPlaneOption;
uvScale = tUvScale;
uvShift = tUvShift;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
GeomUtil.CopyMesh(inputMesh, outputMesh);
Bounds bounds = outputMesh.bounds;
Vector3 size = bounds.size;
Vector3[] vertices = outputMesh.vertices;
Vector2[] uvs = new Vector2[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
uvs[i] = new Vector2(vertices[i].x / size.x, vertices[i].z / size.z) * uvScale + uvShift;
}
outputMesh.SetUVs(0, uvs);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9deef960c4623f0438f908d9a5841cfa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,88 @@
/*=========================================================================
Library: iMSTK-Unity
Copyright (c) Kitware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
using ImstkUnity;
using UnityEngine;
using UnityEditor;
namespace ImstkEditor
{
/// <summary>
/// Generates UV sphere tcoords via imgui
/// </summary>
public class UVSphereProjectEditor : EditorWindow
{
public float radius = 1.0f;
public float uvScale = 2.0f;
public Vector3 center = new Vector3(0.0f, 0.0f, 0.0f);
public Mesh inputMesh = null;
public Mesh outputMesh = null;
public static void Init(Mesh inputMesh, Mesh outputMesh)
{
UVSphereProjectEditor window = GetWindow(typeof(UVSphereProjectEditor)) as UVSphereProjectEditor;
window.inputMesh = inputMesh;
window.outputMesh = outputMesh;
// Initialize to the bounds of the input mesh
window.center = inputMesh.bounds.center;
window.radius = inputMesh.bounds.size.magnitude * 0.5f;
window.UpdateEditorResults();
window.Show();
}
void OnGUI()
{
EditorGUI.BeginChangeCheck();
inputMesh = EditorGUILayout.ObjectField("Input Mesh: ", inputMesh, typeof(Mesh), true) as Mesh;
Vector3 tCenter = EditorGUILayout.Vector3Field("Center: ", center);
float tRadius = EditorGUILayout.FloatField("Radius: ", radius);
float tUvScale = EditorGUILayout.FloatField("UV Scale: ", uvScale);
// \todo: How to get undo to also call UpdateInputObj?
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(this, "Change of Parameters");
radius = Mathf.Max(tRadius, 0.0f);
uvScale = tUvScale;
center = tCenter;
UpdateEditorResults();
}
}
private void UpdateEditorResults()
{
GeomUtil.CopyMesh(inputMesh, outputMesh);
Vector3[] vertices = outputMesh.vertices;
Vector2[] uvs = new Vector2[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
Vector3 diff = vertices[i] - center;
// Compute phi and theta on the sphere
float theta = Mathf.Asin(diff.x / radius);
float phi = Mathf.Atan2(diff.y, diff.z);
uvs[i] = new Vector2(phi / (Mathf.PI * 2.0f) + 0.5f, theta / (Mathf.PI * 2.0f) + 0.5f) * uvScale;
}
outputMesh.SetUVs(0, uvs);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 29dbcb8127ce46e40a5aedbf66f68d77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 936dbb32eb653d84a9bcbe9caad48547, type: 3}
userData:
assetBundleName:
assetBundleVariant: