removed OBJ-IO
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4de3d2c20fafa4cb5a4d9fa9ff529971
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,50 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using UnityExtension;
|
||||
|
||||
public class OBJWindow : EditorWindow
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private MeshFilter m_MeshFilter = null;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
[MenuItem("OBJ-IO/OBJ Mesh Exporter")]
|
||||
public static void Execute()
|
||||
{
|
||||
OBJWindow.GetWindow<OBJWindow>();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private void OnGUI()
|
||||
{
|
||||
m_MeshFilter = (MeshFilter)EditorGUILayout.ObjectField("MeshFilter", m_MeshFilter, typeof(MeshFilter), true);
|
||||
|
||||
if (m_MeshFilter != null)
|
||||
{
|
||||
if (GUILayout.Button("Export OBJ"))
|
||||
{
|
||||
var lOutputPath = EditorUtility.SaveFilePanel("Save Mesh as OBJ", "", m_MeshFilter.name + ".obj", "obj");
|
||||
|
||||
if (File.Exists(lOutputPath))
|
||||
{
|
||||
File.Delete(lOutputPath);
|
||||
}
|
||||
|
||||
var lStream = new FileStream(lOutputPath, FileMode.Create);
|
||||
var lOBJData = m_MeshFilter.sharedMesh.EncodeOBJ();
|
||||
OBJLoader.ExportOBJ(lOBJData, lStream);
|
||||
lStream.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("Please provide a MeshFilter");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5cb377fb273c8634296cc421905b1d34
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85a0cef7e364f48d881582114249bfd1
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1cec0b7c513af4f2985399042ae83c15
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2f76706cb1d54b54801e02c996080eb
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591253
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9962569753c3d46ef836238f2aa6b33b
|
||||
timeCreated: 1465591475
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de5cfcc17119041818768dc28e0c3e4b
|
||||
timeCreated: 1465591253
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c4a7e93244894f7ea111b89b950bb85
|
||||
timeCreated: 1465591814
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53158f4ed39ed53448df438bc212f7e8
|
||||
ModelImporter:
|
||||
serializedVersion: 19
|
||||
fileIDToRecycleName:
|
||||
100000: //RootNode
|
||||
100002: Teapot001
|
||||
400000: //RootNode
|
||||
400002: Teapot001
|
||||
2300000: Teapot001
|
||||
3300000: Teapot001
|
||||
4300000: Teapot001
|
||||
9500000: //RootNode
|
||||
materials:
|
||||
importMaterials: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleRotations: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 0.1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
importBlendShapes: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 0
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 1
|
||||
tangentImportMode: 4
|
||||
importAnimation: 1
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 0
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,83 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dacaee67ec5e14226b9ec02527c457b5
|
||||
timeCreated: 1465591475
|
||||
licenseType: Free
|
||||
ModelImporter:
|
||||
serializedVersion: 19
|
||||
fileIDToRecycleName:
|
||||
100000: Cube_Instance_0
|
||||
100002: //RootNode
|
||||
100004: Teapot001_Instance_0
|
||||
400000: Cube_Instance_0
|
||||
400002: //RootNode
|
||||
400004: Teapot001_Instance_0
|
||||
2300000: Cube_Instance_0
|
||||
2300002: Teapot001_Instance_0
|
||||
3300000: Cube_Instance_0
|
||||
3300002: Teapot001_Instance_0
|
||||
4300000: Cube_Instance_0
|
||||
4300002: Teapot001_Instance_0
|
||||
materials:
|
||||
importMaterials: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleRotations: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
importBlendShapes: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
importAnimation: 1
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 0
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de90c25035683439686941d132beb13c
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,6 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8573b7b1c7256de4896b3054d17de1b7
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 960be3fc0da534863bcaece34b55fe5b
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,52 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
using UnityExtension;
|
||||
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
[RequireComponent(typeof(MeshFilter))]
|
||||
public class Example : MonoBehaviour
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private const string INPUT_PATH = @"Assets/OBJ-IO/Examples/Meshes/Teapot.obj";
|
||||
private const string OUTPUT_PATH = @"Assets/OBJ-IO/Examples/Meshes/Teapot_Modified.obj";
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private void Start()
|
||||
{
|
||||
// Load the OBJ in
|
||||
var lStream = new FileStream(INPUT_PATH, FileMode.Open);
|
||||
var lOBJData = OBJLoader.LoadOBJ(lStream);
|
||||
var lMeshFilter = GetComponent<MeshFilter>();
|
||||
lMeshFilter.mesh.LoadOBJ(lOBJData);
|
||||
lStream.Close();
|
||||
|
||||
lStream = null;
|
||||
lOBJData = null;
|
||||
|
||||
// Wiggle Vertices in Mesh
|
||||
/*
|
||||
var lVertices = lMeshFilter.mesh.vertices;
|
||||
for (int lCount = 0; lCount < lVertices.Length; ++lCount)
|
||||
{
|
||||
lVertices[lCount] = lVertices[lCount] + Vector3.up * Mathf.Sin(lVertices[lCount].x) * 4f;
|
||||
}
|
||||
lMeshFilter.mesh.vertices = lVertices;
|
||||
*/
|
||||
// Export the new Wiggled Mesh
|
||||
if (File.Exists(OUTPUT_PATH))
|
||||
{
|
||||
File.Delete(OUTPUT_PATH);
|
||||
}
|
||||
lStream = new FileStream(OUTPUT_PATH, FileMode.Create);
|
||||
lOBJData = lMeshFilter.mesh.EncodeOBJ();
|
||||
OBJLoader.ExportOBJ(lOBJData, lStream);
|
||||
lStream.Close();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3ab7cfdf40b84b41a7adc35c545c226
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a34eacd8a28f549b4afede06cd79972e
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 222144ab5ea5b4732b84d8eff5735d91
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,112 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExtension
|
||||
{
|
||||
public static class GameObjectExt
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static T GetOrAddComponent<T>(this GameObject lGo) where T : Component
|
||||
{
|
||||
T lComponent = lGo.GetComponent<T>();
|
||||
if (lComponent == null)
|
||||
{
|
||||
lComponent = lGo.gameObject.AddComponent<T>();
|
||||
}
|
||||
return lComponent;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static T GetComponentOfChild<T>(this GameObject lGo, string lName) where T : Component
|
||||
{
|
||||
T lComponent = null;
|
||||
Transform lTransform = lGo.transform.FindChild(lName);
|
||||
if (lTransform != null)
|
||||
{
|
||||
lComponent = lTransform.GetComponent<T>();
|
||||
}
|
||||
return lComponent;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static T[] GetComponentsOfChild<T>(this GameObject lGo, string lName) where T : Component
|
||||
{
|
||||
T[] lComponent = null;
|
||||
Transform lTransform = lGo.transform.FindChild(lName);
|
||||
if (lTransform != null)
|
||||
{
|
||||
lComponent = lTransform.GetComponents<T>();
|
||||
}
|
||||
return lComponent;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static GameObject InstantiateAsChild(this GameObject lGo, GameObject lObject)
|
||||
{
|
||||
GameObject lNewGo = lObject != null ? (GameObject)GameObject.Instantiate(lObject) : new GameObject();
|
||||
lNewGo.transform.parent = lGo.transform;
|
||||
lNewGo.transform.localPosition = Vector3.zero;
|
||||
lNewGo.transform.localRotation = Quaternion.identity;
|
||||
lNewGo.transform.localScale = Vector3.one;
|
||||
return lNewGo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static bool DestroyChildIfExists(this GameObject lGo, string lName)
|
||||
{
|
||||
Transform lTransform = lGo.transform.FindChild(lName);
|
||||
if (lTransform != null)
|
||||
{
|
||||
GameObject.Destroy(lTransform.gameObject);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static bool ContainsChildren(this GameObject lGo, params string[] lPaths)
|
||||
{
|
||||
for (int lCount = 0; lCount < lPaths.Length; ++lCount)
|
||||
{
|
||||
if (lGo.transform.FindChild(lPaths[lCount]) == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static bool IsChildOf(this GameObject lGo, GameObject lParent)
|
||||
{
|
||||
Transform lTransform = lGo.transform;
|
||||
while (lTransform.parent != null)
|
||||
{
|
||||
if (lTransform == lParent.transform)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
lTransform = lTransform.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void SetLayerRecursively(this GameObject lGo, int lLayer)
|
||||
{
|
||||
lGo.layer = lLayer;
|
||||
foreach (Transform lTransform in lGo.transform)
|
||||
{
|
||||
lTransform.gameObject.SetLayerRecursively(lLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35b132c59c7910c4b99e560a0f9baf95
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,627 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExtension
|
||||
{
|
||||
public static class MeshExt
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void RecalculateTangents(this Mesh lMesh)
|
||||
{
|
||||
//speed up math by copying the mesh arrays
|
||||
int[] triangles = lMesh.triangles;
|
||||
Vector3[] vertices = lMesh.vertices;
|
||||
Vector2[] uv = lMesh.uv;
|
||||
Vector3[] normals = lMesh.normals;
|
||||
|
||||
//variable definitions
|
||||
int triangleCount = triangles.Length;
|
||||
int vertexCount = vertices.Length;
|
||||
|
||||
Vector3[] tan1 = new Vector3[vertexCount];
|
||||
Vector3[] tan2 = new Vector3[vertexCount];
|
||||
|
||||
Vector4[] tangents = new Vector4[vertexCount];
|
||||
|
||||
for (long a = 0; a < triangleCount; a += 3)
|
||||
{
|
||||
long i1 = triangles[a + 0];
|
||||
long i2 = triangles[a + 1];
|
||||
long i3 = triangles[a + 2];
|
||||
|
||||
Vector3 v1 = vertices[i1];
|
||||
Vector3 v2 = vertices[i2];
|
||||
Vector3 v3 = vertices[i3];
|
||||
|
||||
Vector2 w1 = uv[i1];
|
||||
Vector2 w2 = uv[i2];
|
||||
Vector2 w3 = uv[i3];
|
||||
|
||||
float x1 = v2.x - v1.x;
|
||||
float x2 = v3.x - v1.x;
|
||||
float y1 = v2.y - v1.y;
|
||||
float y2 = v3.y - v1.y;
|
||||
float z1 = v2.z - v1.z;
|
||||
float z2 = v3.z - v1.z;
|
||||
|
||||
float s1 = w2.x - w1.x;
|
||||
float s2 = w3.x - w1.x;
|
||||
float t1 = w2.y - w1.y;
|
||||
float t2 = w3.y - w1.y;
|
||||
|
||||
float r = 1.0f / (s1 * t2 - s2 * t1);
|
||||
|
||||
Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
|
||||
Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
|
||||
|
||||
tan1[i1] += sdir;
|
||||
tan1[i2] += sdir;
|
||||
tan1[i3] += sdir;
|
||||
|
||||
tan2[i1] += tdir;
|
||||
tan2[i2] += tdir;
|
||||
tan2[i3] += tdir;
|
||||
}
|
||||
|
||||
|
||||
for (long a = 0; a < vertexCount; ++a)
|
||||
{
|
||||
Vector3 n = normals[a];
|
||||
Vector3 t = tan1[a];
|
||||
|
||||
//Vector3 tmp = (t - n * Vector3.Dot(n, t)).normalized;
|
||||
//tangents[a] = new Vector4(tmp.x, tmp.y, tmp.z);
|
||||
Vector3.OrthoNormalize(ref n, ref t);
|
||||
tangents[a].x = t.x;
|
||||
tangents[a].y = t.y;
|
||||
tangents[a].z = t.z;
|
||||
|
||||
tangents[a].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
|
||||
}
|
||||
|
||||
lMesh.tangents = tangents;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void LoadOBJ(this Mesh lMesh, OBJData lData)
|
||||
{
|
||||
List<Vector3> lVertices = new List<Vector3>();
|
||||
List<Vector3> lNormals = new List<Vector3>();
|
||||
List<Vector2> lUVs = new List<Vector2>();
|
||||
List<int>[] lIndices = new List<int>[lData.m_Groups.Count];
|
||||
Dictionary<OBJFaceVertex, int> lVertexIndexRemap = new Dictionary<OBJFaceVertex, int>();
|
||||
bool lHasNormals = lData.m_Normals.Count > 0;
|
||||
bool lHasUVs = lData.m_UVs.Count > 0;
|
||||
|
||||
lMesh.subMeshCount = lData.m_Groups.Count;
|
||||
for (int lGCount = 0; lGCount < lData.m_Groups.Count; ++lGCount)
|
||||
{
|
||||
OBJGroup lGroup = lData.m_Groups[lGCount];
|
||||
lIndices[lGCount] = new List<int>();
|
||||
|
||||
for (int lFCount = 0; lFCount < lGroup.Faces.Count; ++lFCount)
|
||||
{
|
||||
OBJFace lFace = lGroup.Faces[lFCount];
|
||||
|
||||
// Unity3d doesn't support non-triangle faces
|
||||
// so we do simple fan triangulation
|
||||
for (int lVCount = 1; lVCount < lFace.Count - 1; ++lVCount)
|
||||
{
|
||||
foreach (int i in new int[]{0, lVCount, lVCount + 1})
|
||||
{
|
||||
OBJFaceVertex lFaceVertex = lFace[i];
|
||||
int lVertexIndex = -1;
|
||||
|
||||
if (!lVertexIndexRemap.TryGetValue(lFaceVertex, out lVertexIndex)) {
|
||||
lVertexIndexRemap[lFaceVertex] = lVertices.Count;
|
||||
lVertexIndex = lVertices.Count;
|
||||
|
||||
lVertices.Add(lData.m_Vertices[lFaceVertex.m_VertexIndex]);
|
||||
if (lHasUVs)
|
||||
{
|
||||
lUVs.Add(lData.m_UVs[lFaceVertex.m_UVIndex]);
|
||||
}
|
||||
if (lHasNormals)
|
||||
{
|
||||
lNormals.Add(lData.m_Normals[lFaceVertex.m_NormalIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
lIndices[lGCount].Add(lVertexIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lMesh.triangles = new int[]{ };
|
||||
lMesh.vertices = lVertices.ToArray();
|
||||
lMesh.uv = lUVs.ToArray();
|
||||
lMesh.normals = lNormals.ToArray();
|
||||
if (!lHasNormals)
|
||||
{
|
||||
lMesh.RecalculateNormals();
|
||||
}
|
||||
|
||||
lMesh.RecalculateTangents();
|
||||
|
||||
for (int lGCount = 0; lGCount < lData.m_Groups.Count; ++lGCount)
|
||||
{
|
||||
lMesh.SetTriangles(lIndices[lGCount].ToArray(), lGCount);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static OBJData EncodeOBJ(this Mesh lMesh)
|
||||
{
|
||||
OBJData lData = new OBJData
|
||||
{
|
||||
m_Vertices = new List<Vector3>(lMesh.vertices),
|
||||
m_UVs = new List<Vector2>(lMesh.uv),
|
||||
m_Normals = new List<Vector3>(lMesh.normals),
|
||||
m_UV2s = new List<Vector2>(lMesh.uv2),
|
||||
m_Colors = new List<Color>(lMesh.colors)
|
||||
};
|
||||
|
||||
int[] lIndices = null;
|
||||
OBJGroup lGroup = null;
|
||||
OBJFace lFace = null;
|
||||
OBJFaceVertex lFaceVertex = null;
|
||||
|
||||
for (int lMCount = 0; lMCount < lMesh.subMeshCount; ++lMCount)
|
||||
{
|
||||
lIndices = lMesh.GetTriangles(lMCount);
|
||||
lGroup = new OBJGroup(lMesh.name + "_" + lMCount.ToString());
|
||||
|
||||
for (int lCount = 0; lCount < lIndices.Length; lCount += 3)
|
||||
{
|
||||
lFace = new OBJFace();
|
||||
|
||||
lFaceVertex = new OBJFaceVertex();
|
||||
lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount] : -1;
|
||||
lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount] : -1;
|
||||
lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount] : -1;
|
||||
lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount] : -1;
|
||||
lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount] : -1;
|
||||
lFace.AddVertex(lFaceVertex);
|
||||
|
||||
lFaceVertex = new OBJFaceVertex();
|
||||
lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 1] : -1;
|
||||
lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount + 1] : -1;
|
||||
lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 1] : -1;
|
||||
lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount + 1] : -1;
|
||||
lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount + 1] : -1;
|
||||
lFace.AddVertex(lFaceVertex);
|
||||
|
||||
lFaceVertex = new OBJFaceVertex();
|
||||
lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 2] : -1;
|
||||
lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount + 2] : -1;
|
||||
lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 2] : -1;
|
||||
lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount + 2] : -1;
|
||||
lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount + 2] : -1;
|
||||
lFace.AddVertex(lFaceVertex);
|
||||
|
||||
lGroup.AddFace(lFace);
|
||||
}
|
||||
|
||||
lData.m_Groups.Add(lGroup);
|
||||
}
|
||||
|
||||
return lData;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
internal const int MESH_BINARY_HEADER_SIZE = 20;
|
||||
internal const short MESH_BINARY_SIGNATURE = 0xF5;
|
||||
internal const short MESH_BINARY_VERSION = 1;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static bool LoadBinary(this Mesh lMesh, byte[] lData)
|
||||
{
|
||||
int lSizeOfVector2 = Marshal.SizeOf(typeof(Vector2));
|
||||
int lSizeOfVector3 = Marshal.SizeOf(typeof(Vector3));
|
||||
int lSizeOfVector4 = Marshal.SizeOf(typeof(Vector4));
|
||||
int lSizeOfMatrix4x4 = Marshal.SizeOf(typeof(Matrix4x4));
|
||||
int lSizeOfBoneWeight = Marshal.SizeOf(typeof(BoneWeight));
|
||||
int lSizeOfColor = Marshal.SizeOf(typeof(Color));
|
||||
|
||||
int lDataOffset = MESH_BINARY_HEADER_SIZE;
|
||||
int lDeltaOffset = 0;
|
||||
|
||||
if (lData == null ||
|
||||
lData.Length < MESH_BINARY_HEADER_SIZE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Header
|
||||
short lSignature = BitConverter.ToInt16(lData, 0);
|
||||
short lVersion = BitConverter.ToInt16(lData, 2);
|
||||
|
||||
if (lSignature != MESH_BINARY_SIGNATURE ||
|
||||
lVersion != MESH_BINARY_VERSION)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
lMesh.Clear();
|
||||
|
||||
int lVertexCount = BitConverter.ToInt32(lData, 4);
|
||||
int lIndexCount = BitConverter.ToInt32(lData, 8);
|
||||
int lSubMeshCount = BitConverter.ToInt32(lData, 12);
|
||||
|
||||
byte lFlags = lData[16];
|
||||
|
||||
bool lUVFlag = (lFlags & 1) > 0;
|
||||
bool lUV1Flag = (lFlags & 2) > 0;
|
||||
bool lUV2Flag = (lFlags & 4) > 0;
|
||||
bool lNormalFlag = (lFlags & 8) > 0;
|
||||
bool lTangentFlag = (lFlags & 16) > 0;
|
||||
bool lColorFlag = (lFlags & 32) > 0;
|
||||
bool lBindPoseFlag = (lFlags & 64) > 0;
|
||||
bool lBoneWeightFlag = (lFlags & 128) > 0;
|
||||
|
||||
// Vertices
|
||||
Vector3[] lVertices = new Vector3[lVertexCount];
|
||||
lDeltaOffset = lVertices.Length * lSizeOfVector3;
|
||||
GCHandle lHandle = GCHandle.Alloc(lVertices, GCHandleType.Pinned);
|
||||
Marshal.Copy(lData, lDataOffset, lHandle.AddrOfPinnedObject(), lDeltaOffset);
|
||||
lHandle.Free();
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.vertices = lVertices;
|
||||
lVertices = null;
|
||||
|
||||
// UV Channel 0
|
||||
Vector2[] lUVs = null;
|
||||
if (lUVFlag == true)
|
||||
{
|
||||
lUVs = new Vector2[lVertexCount];
|
||||
lDeltaOffset = lUVs.Length * lSizeOfVector2;
|
||||
lHandle = GCHandle.Alloc(lUVs, GCHandleType.Pinned);
|
||||
Marshal.Copy(lData, lDataOffset, lHandle.AddrOfPinnedObject(), lDeltaOffset);
|
||||
lHandle.Free();
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.uv = lUVs;
|
||||
Debug.Log("UV Count : " + lUVs.Length);
|
||||
lUVs = null;
|
||||
}
|
||||
|
||||
// UV Channel 1
|
||||
if (lUV1Flag == true)
|
||||
{
|
||||
lUVs = new Vector2[lVertexCount];
|
||||
lDeltaOffset = lUVs.Length * lSizeOfVector2;
|
||||
lHandle = GCHandle.Alloc(lUVs, GCHandleType.Pinned);
|
||||
Marshal.Copy(lData, lDataOffset, lHandle.AddrOfPinnedObject(), lDeltaOffset);
|
||||
lHandle.Free();
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.uv2 = lUVs;
|
||||
Debug.Log("UV1 Count : " + lUVs.Length);
|
||||
lUVs = null;
|
||||
}
|
||||
|
||||
// UV Channel 2
|
||||
if (lUV2Flag == true)
|
||||
{
|
||||
lUVs = new Vector2[lVertexCount];
|
||||
lDeltaOffset = lUVs.Length * lSizeOfVector2;
|
||||
lHandle = GCHandle.Alloc(lUVs, GCHandleType.Pinned);
|
||||
Marshal.Copy(lData, lDataOffset, lHandle.AddrOfPinnedObject(), lDeltaOffset);
|
||||
lHandle.Free();
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.uv2 = lUVs;
|
||||
Debug.Log("UV2 Count : " + lUVs.Length);
|
||||
lUVs = null;
|
||||
}
|
||||
|
||||
// Normals
|
||||
if (lNormalFlag == true)
|
||||
{
|
||||
Vector3[] lNormals = new Vector3[lVertexCount];
|
||||
lDeltaOffset = lNormals.Length * lSizeOfVector3;
|
||||
lHandle = GCHandle.Alloc(lNormals, GCHandleType.Pinned);
|
||||
Marshal.Copy(lData, lDataOffset, lHandle.AddrOfPinnedObject(), lDeltaOffset);
|
||||
lHandle.Free();
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.normals = lNormals;
|
||||
Debug.Log("Normal Count : " + lNormals.Length);
|
||||
lNormals = null;
|
||||
}
|
||||
|
||||
// Tangents
|
||||
if (lTangentFlag == true)
|
||||
{
|
||||
Vector4[] lTangents = new Vector4[lVertexCount];
|
||||
lDeltaOffset = lTangents.Length * lSizeOfVector4;
|
||||
lHandle = GCHandle.Alloc(lTangents, GCHandleType.Pinned);
|
||||
Marshal.Copy(lData, lDataOffset, lHandle.AddrOfPinnedObject(), lDeltaOffset);
|
||||
lHandle.Free();
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.tangents = lTangents;
|
||||
Debug.Log("Tangents Count : " + lTangents.Length);
|
||||
lTangents = null;
|
||||
}
|
||||
|
||||
// Colors
|
||||
if (lColorFlag == true)
|
||||
{
|
||||
Color[] lColors = new Color[lVertexCount];
|
||||
lDeltaOffset = lColors.Length * lSizeOfColor;
|
||||
lHandle = GCHandle.Alloc(lColors, GCHandleType.Pinned);
|
||||
Marshal.Copy(lData, lDataOffset, lHandle.AddrOfPinnedObject(), lDeltaOffset);
|
||||
lHandle.Free();
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.colors = lColors;
|
||||
lColors = null;
|
||||
}
|
||||
|
||||
// Bind Poses
|
||||
if (lBindPoseFlag == true)
|
||||
{
|
||||
Matrix4x4[] lBindPoses = new Matrix4x4[lVertexCount];
|
||||
lDeltaOffset = lBindPoses.Length * lSizeOfMatrix4x4;
|
||||
lHandle = GCHandle.Alloc(lBindPoses, GCHandleType.Pinned);
|
||||
Marshal.Copy(lData, lDataOffset, lHandle.AddrOfPinnedObject(), lDeltaOffset);
|
||||
lHandle.Free();
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.bindposes = lBindPoses;
|
||||
lBindPoses = null;
|
||||
}
|
||||
|
||||
// Bone Weights
|
||||
if (lBoneWeightFlag == true)
|
||||
{
|
||||
BoneWeight[] lBoneWeight = new BoneWeight[lVertexCount];
|
||||
lDeltaOffset = lBoneWeight.Length * lSizeOfBoneWeight;
|
||||
lHandle = GCHandle.Alloc(lBoneWeight, GCHandleType.Pinned);
|
||||
Marshal.Copy(lData, lDataOffset, lHandle.AddrOfPinnedObject(), lDeltaOffset);
|
||||
lHandle.Free();
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.boneWeights = lBoneWeight;
|
||||
lBoneWeight = null;
|
||||
}
|
||||
|
||||
// Indices
|
||||
int[] lIndices = new int[lIndexCount];
|
||||
lDeltaOffset = lIndices.Length * sizeof(int);
|
||||
Buffer.BlockCopy(lData, lDataOffset, lIndices, 0, lDeltaOffset);
|
||||
lDataOffset += lDeltaOffset;
|
||||
lMesh.triangles = lIndices;
|
||||
lIndices = null;
|
||||
|
||||
// SubMesh Indices
|
||||
for (int lSubMeshIndex = 0; lSubMeshIndex < lSubMeshCount; ++lSubMeshIndex)
|
||||
{
|
||||
int lSubMeshIndexCount = BitConverter.ToInt32(lData, lDataOffset);
|
||||
lDataOffset += sizeof(int);
|
||||
|
||||
lIndices = new int[lSubMeshIndexCount];
|
||||
lDeltaOffset = lIndices.Length * sizeof(int);
|
||||
Buffer.BlockCopy(lData, lDataOffset, lIndices, 0, lDeltaOffset);
|
||||
lDataOffset += lDeltaOffset;
|
||||
|
||||
if (lIndices.Length > 0 &&
|
||||
lIndices.Length % 3 == 0)
|
||||
{
|
||||
lMesh.SetTriangles(lIndices, lSubMeshIndex);
|
||||
}
|
||||
|
||||
lIndices = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static byte[] EncodeBinary(this Mesh lMesh)
|
||||
{
|
||||
// Currently no support for BlendShape
|
||||
|
||||
int lSizeOfVector2 = Marshal.SizeOf(typeof(Vector2));
|
||||
int lSizeOfVector3 = Marshal.SizeOf(typeof(Vector3));
|
||||
int lSizeOfVector4 = Marshal.SizeOf(typeof(Vector4));
|
||||
int lSizeOfMatrix4x4 = Marshal.SizeOf(typeof(Matrix4x4));
|
||||
int lSizeOfBoneWeight = Marshal.SizeOf(typeof(BoneWeight));
|
||||
int lSizeOfColor = Marshal.SizeOf(typeof(Color));
|
||||
|
||||
int lDataSize = MESH_BINARY_HEADER_SIZE;
|
||||
int lDeltaSize = 0;
|
||||
|
||||
bool lUVFlag = false, lUV1Flag = false, lUV2Flag = false,
|
||||
lNormalFlag = false, lTangentFlag = false, lColorFlag = false,
|
||||
lBindPoseFlag = false, lBoneWeightFlag = false;
|
||||
|
||||
byte[] lData = new byte[lDataSize];
|
||||
|
||||
// Vertices
|
||||
Vector3[] lVertices = lMesh.vertices;
|
||||
Int32Converter lVertexCount = lVertices.Length;
|
||||
lDeltaSize = lVertices.Length * lSizeOfVector3;
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
GCHandle lHandle = GCHandle.Alloc(lVertices, GCHandleType.Pinned);
|
||||
Marshal.Copy(lHandle.AddrOfPinnedObject(), lData, lDataSize, lDeltaSize);
|
||||
lHandle.Free();
|
||||
lDataSize += lDeltaSize;
|
||||
lVertices = null;
|
||||
|
||||
// UV Channel 0
|
||||
Vector2[] lUVs = lMesh.uv;
|
||||
if (lUVs.Length > 0)
|
||||
{
|
||||
lUVFlag = true;
|
||||
lDeltaSize = lUVs.Length * lSizeOfVector2;
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
lHandle = GCHandle.Alloc(lUVs, GCHandleType.Pinned);
|
||||
Marshal.Copy(lHandle.AddrOfPinnedObject(), lData, lDataSize, lDeltaSize);
|
||||
lHandle.Free();
|
||||
lDataSize += lDeltaSize;
|
||||
}
|
||||
lUVs = null;
|
||||
|
||||
// UV Channel 1
|
||||
lUVs = lMesh.uv2;
|
||||
if (lUVs.Length > 0)
|
||||
{
|
||||
lUV1Flag = true;
|
||||
lDeltaSize = lUVs.Length * lSizeOfVector2;
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
lHandle = GCHandle.Alloc(lUVs, GCHandleType.Pinned);
|
||||
Marshal.Copy(lHandle.AddrOfPinnedObject(), lData, lDataSize, lDeltaSize);
|
||||
lHandle.Free();
|
||||
lDataSize += lDeltaSize;
|
||||
}
|
||||
lUVs = null;
|
||||
|
||||
// UV Channel 2
|
||||
lUVs = lMesh.uv2;
|
||||
if (lUVs.Length > 0)
|
||||
{
|
||||
lUV2Flag = true;
|
||||
lDeltaSize = lUVs.Length * lSizeOfVector2;
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
lHandle = GCHandle.Alloc(lUVs, GCHandleType.Pinned);
|
||||
Marshal.Copy(lHandle.AddrOfPinnedObject(), lData, lDataSize, lDeltaSize);
|
||||
lHandle.Free();
|
||||
lDataSize += lDeltaSize;
|
||||
}
|
||||
lUVs = null;
|
||||
|
||||
// Normals
|
||||
Vector3[] lNormals = lMesh.normals;
|
||||
if (lNormals.Length > 0)
|
||||
{
|
||||
lNormalFlag = true;
|
||||
lDeltaSize = lNormals.Length * lSizeOfVector3;
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
lHandle = GCHandle.Alloc(lNormals, GCHandleType.Pinned);
|
||||
Marshal.Copy(lHandle.AddrOfPinnedObject(), lData, lDataSize, lDeltaSize);
|
||||
lHandle.Free();
|
||||
lDataSize += lDeltaSize;
|
||||
}
|
||||
lNormals = null;
|
||||
|
||||
// Tangents
|
||||
Vector4[] lTangents = lMesh.tangents;
|
||||
if (lTangents.Length > 0)
|
||||
{
|
||||
lTangentFlag = true;
|
||||
lDeltaSize = lTangents.Length * lSizeOfVector4;
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
lHandle = GCHandle.Alloc(lTangents, GCHandleType.Pinned);
|
||||
Marshal.Copy(lHandle.AddrOfPinnedObject(), lData, lDataSize, lDeltaSize);
|
||||
lHandle.Free();
|
||||
lDataSize += lDeltaSize;
|
||||
}
|
||||
lTangents = null;
|
||||
|
||||
// Colors
|
||||
Color[] lColors = lMesh.colors;
|
||||
if (lColors.Length > 0)
|
||||
{
|
||||
lColorFlag = true;
|
||||
lDeltaSize = lColors.Length * lSizeOfColor;
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
lHandle = GCHandle.Alloc(lColors, GCHandleType.Pinned);
|
||||
Marshal.Copy(lHandle.AddrOfPinnedObject(), lData, lDataSize, lDeltaSize);
|
||||
lHandle.Free();
|
||||
lDataSize += lDeltaSize;
|
||||
}
|
||||
lColors = null;
|
||||
|
||||
// BindPoses
|
||||
Matrix4x4[] lBindPoses = lMesh.bindposes;
|
||||
if (lBindPoses.Length > 0)
|
||||
{
|
||||
lBindPoseFlag = true;
|
||||
lDeltaSize = lBindPoses.Length * lSizeOfMatrix4x4;
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
lHandle = GCHandle.Alloc(lBindPoses, GCHandleType.Pinned);
|
||||
Marshal.Copy(lHandle.AddrOfPinnedObject(), lData, lDataSize, lDeltaSize);
|
||||
lHandle.Free();
|
||||
lDataSize += lDeltaSize;
|
||||
}
|
||||
lBindPoses = null;
|
||||
|
||||
// BoneWeight
|
||||
BoneWeight[] lBoneWeight = lMesh.boneWeights;
|
||||
if (lBoneWeight.Length > 0)
|
||||
{
|
||||
lBoneWeightFlag = true;
|
||||
lDeltaSize = lBoneWeight.Length * lSizeOfBoneWeight;
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
lHandle = GCHandle.Alloc(lBoneWeight, GCHandleType.Pinned);
|
||||
Marshal.Copy(lHandle.AddrOfPinnedObject(), lData, lDataSize, lDeltaSize);
|
||||
lHandle.Free();
|
||||
lDataSize += lDeltaSize;
|
||||
}
|
||||
lBoneWeight = null;
|
||||
|
||||
// Indices
|
||||
int[] lIndices = lMesh.triangles;
|
||||
Int32Converter lIndexCount = lIndices.Length;
|
||||
lDeltaSize = lIndices.Length * sizeof(int);
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
Buffer.BlockCopy(lIndices, 0, lData, lDataSize, lDeltaSize);
|
||||
lDataSize += lDeltaSize;
|
||||
lIndices = null;
|
||||
|
||||
// SubMesh Indices
|
||||
Int32Converter lSubMeshCount = lMesh.subMeshCount;
|
||||
for (int lSubMeshIndex = 0; lSubMeshIndex < lSubMeshCount; ++lSubMeshIndex)
|
||||
{
|
||||
lIndices = lMesh.GetTriangles(lSubMeshIndex);
|
||||
|
||||
Int32Converter lSubMeshIndexCount = lIndices.Length;
|
||||
|
||||
lDeltaSize = sizeof(int) + (lIndices.Length * sizeof(int));
|
||||
Array.Resize(ref lData, lDataSize + lDeltaSize);
|
||||
|
||||
lData[lDataSize + 0] = lSubMeshIndexCount.Byte1;
|
||||
lData[lDataSize + 1] = lSubMeshIndexCount.Byte2;
|
||||
lData[lDataSize + 2] = lSubMeshIndexCount.Byte3;
|
||||
lData[lDataSize + 3] = lSubMeshIndexCount.Byte4;
|
||||
|
||||
Buffer.BlockCopy(lIndices, 0, lData, lDataSize, lDeltaSize - sizeof(int));
|
||||
lDataSize += lDeltaSize;
|
||||
}
|
||||
|
||||
// Header
|
||||
lData[0] = (byte)(MESH_BINARY_SIGNATURE & 0xFF);
|
||||
lData[1] = (byte)((MESH_BINARY_SIGNATURE >> 8) & 0xFF);
|
||||
|
||||
lData[2] = (byte)(MESH_BINARY_VERSION & 0xFF);
|
||||
lData[3] = (byte)((MESH_BINARY_VERSION >> 8) & 0xFF);
|
||||
|
||||
lData[4] = lVertexCount.Byte1;
|
||||
lData[5] = lVertexCount.Byte2;
|
||||
lData[6] = lVertexCount.Byte3;
|
||||
lData[7] = lVertexCount.Byte4;
|
||||
|
||||
lData[8] = lIndexCount.Byte1;
|
||||
lData[9] = lIndexCount.Byte2;
|
||||
lData[10] = lIndexCount.Byte3;
|
||||
lData[11] = lIndexCount.Byte4;
|
||||
|
||||
lData[12] = lSubMeshCount.Byte1;
|
||||
lData[13] = lSubMeshCount.Byte2;
|
||||
lData[14] = lSubMeshCount.Byte3;
|
||||
lData[15] = lSubMeshCount.Byte4;
|
||||
|
||||
lData[16] = (byte)(
|
||||
(lUVFlag ? 1 : 0) |
|
||||
(lUV1Flag ? 2 : 0) |
|
||||
(lUV2Flag ? 4 : 0) |
|
||||
(lNormalFlag ? 8 : 0) |
|
||||
(lTangentFlag ? 16 : 0) |
|
||||
(lColorFlag ? 32 : 0) |
|
||||
(lBindPoseFlag ? 64 : 0) |
|
||||
(lBoneWeightFlag ? 128 : 0));
|
||||
|
||||
return lData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a643d266ae55c8845ac48528640b7e8e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
public static class StringExt
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static float ParseInvariantFloat(this string floatString)
|
||||
{
|
||||
return float.Parse(floatString, CultureInfo.InvariantCulture.NumberFormat);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static int ParseInvariantInt(this string intString)
|
||||
{
|
||||
return int.Parse(intString, CultureInfo.InvariantCulture.NumberFormat);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static bool EqualsInvariantCultureIgnoreCase(this string str, string s)
|
||||
{
|
||||
return str.Equals(s, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static bool IsNullOrEmpty(this string str)
|
||||
{
|
||||
return string.IsNullOrEmpty(str);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static bool IsNullOrWhiteSpace(string value)
|
||||
{
|
||||
if (value == null)
|
||||
return true;
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
{
|
||||
if (!char.IsWhiteSpace(value[index]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5403d11ff2ec0124a9a20522559dfcfa
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,55 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExtension
|
||||
{
|
||||
public static class Texture2DExt
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static byte[] EncodeToTGA(this Texture2D lTexture)
|
||||
{
|
||||
MemoryStream lDataStream = new MemoryStream(18 + (lTexture.width * lTexture.height * 3));
|
||||
BinaryWriter lDataWriter = new BinaryWriter(lDataStream);
|
||||
|
||||
if (lDataWriter != null)
|
||||
{
|
||||
lDataWriter.Write((short)0);
|
||||
lDataWriter.Write((byte)2);
|
||||
lDataWriter.Write((int)0);
|
||||
lDataWriter.Write((int)0);
|
||||
lDataWriter.Write((byte)0);
|
||||
lDataWriter.Write((short)lTexture.width);
|
||||
lDataWriter.Write((short)lTexture.height);
|
||||
lDataWriter.Write((byte)24);
|
||||
lDataWriter.Write((byte)0);
|
||||
|
||||
Color32[] lPixelData = lTexture.GetPixels32();
|
||||
for (int lCount = 0; lCount < lPixelData.Length; ++lCount)
|
||||
{
|
||||
lDataWriter.Write(lPixelData[lCount].b);
|
||||
lDataWriter.Write(lPixelData[lCount].g);
|
||||
lDataWriter.Write(lPixelData[lCount].r);
|
||||
}
|
||||
}
|
||||
|
||||
return lDataStream.GetBuffer();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void ConvertLightmapToMobile(this Texture2D lTexture)
|
||||
{
|
||||
Color[] lColorData = lTexture.GetPixels();
|
||||
for (int lCount = 0; lCount < lColorData.Length; ++lCount)
|
||||
{
|
||||
lColorData[lCount] = (lColorData[lCount] * (8f * lColorData[lCount].a)) * 0.5f;
|
||||
}
|
||||
lTexture.SetPixels(lColorData);
|
||||
lTexture.Apply();
|
||||
lColorData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9260066d99f960241b2a222401bcb685
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,28 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExtension
|
||||
{
|
||||
public static class TransformExt
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void LocalReset(this Transform lTransform)
|
||||
{
|
||||
lTransform.localPosition = Vector3.zero;
|
||||
lTransform.localRotation = Quaternion.identity;
|
||||
lTransform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void Align(this Transform lTransform, Transform lTarget)
|
||||
{
|
||||
lTransform.position = lTarget.position;
|
||||
lTransform.rotation = lTarget.rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8e76b9c1894ec743ae076720e775f49
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,239 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExtension
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static class Utils
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static bool HasKeys(Dictionary<string, object> lData, params string[] lKeys)
|
||||
{
|
||||
if (lKeys != null)
|
||||
{
|
||||
for (int lCount = 0; lCount < lKeys.Length; ++lCount)
|
||||
{
|
||||
if (!lData.ContainsKey(lKeys[lCount]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void ClearChildren(GameObject lGo, string lTarget)
|
||||
{
|
||||
if (lGo != null)
|
||||
{
|
||||
Transform lTransform = null;
|
||||
for (int lCount = lGo.transform.childCount - 1; lCount > -1; --lCount)
|
||||
{
|
||||
lTransform = lGo.transform.GetChild(lCount);
|
||||
if (lTransform.name.Contains(lTarget))
|
||||
{
|
||||
lTransform.parent = null;
|
||||
GameObject.Destroy(lTransform.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void ClearChildrenRegex(GameObject lGo, string lPattern)
|
||||
{
|
||||
if (lGo != null)
|
||||
{
|
||||
Transform lTransform = null;
|
||||
Regex lRegex = new Regex(lPattern);
|
||||
for (int lCount = lGo.transform.childCount - 1; lCount > -1; --lCount)
|
||||
{
|
||||
lTransform = lGo.transform.GetChild(lCount);
|
||||
if (lRegex.IsMatch(lTransform.name))
|
||||
{
|
||||
lTransform.parent = null;
|
||||
GameObject.Destroy(lTransform.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void VerifyObjects(string lMsg, params object[] lObjects)
|
||||
{
|
||||
for (int lCount = 0; lCount < lObjects.Length; ++lCount)
|
||||
{
|
||||
if (lObjects[lCount] == null)
|
||||
{
|
||||
Debug.LogError(lMsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static bool JSONCheck(string lText)
|
||||
{
|
||||
return !string.IsNullOrEmpty(lText) && lText[0] == '{';
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static Vector3 ParseVector3Json(string lJsonData)
|
||||
{
|
||||
string[] lVector3Array = lJsonData.Replace("(", "").Replace(")", "").Replace(" ", "").Split(',');
|
||||
Vector3 lVector3 = Vector3.zero;
|
||||
|
||||
if (float.TryParse(lVector3Array[0], out lVector3.x) == false)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
if (float.TryParse(lVector3Array[1], out lVector3.y) == false)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
if (float.TryParse(lVector3Array[2], out lVector3.z) == false)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
return lVector3;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static Vector4 ParseVector4Json(string lJsonData)
|
||||
{
|
||||
string[] lVector4Array = lJsonData.Replace("(", "").Replace(")", "").Replace(" ", "").Split(',');
|
||||
Vector4 lVector4 = Vector4.zero;
|
||||
|
||||
if (float.TryParse(lVector4Array[0], out lVector4.x) == false)
|
||||
{
|
||||
return Vector4.zero;
|
||||
}
|
||||
if (float.TryParse(lVector4Array[1], out lVector4.y) == false)
|
||||
{
|
||||
return Vector4.zero;
|
||||
}
|
||||
if (float.TryParse(lVector4Array[2], out lVector4.z) == false)
|
||||
{
|
||||
return Vector4.zero;
|
||||
}
|
||||
if (float.TryParse(lVector4Array[3], out lVector4.w) == false)
|
||||
{
|
||||
return Vector4.zero;
|
||||
}
|
||||
|
||||
return lVector4;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static Vector2 ParseVector2String(string lData, char lSeperator = ' ')
|
||||
{
|
||||
string[] lParts = lData.Split(new char[] { lSeperator }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
float lX = lParts[0].ParseInvariantFloat();
|
||||
float lY = lParts[1].ParseInvariantFloat();
|
||||
|
||||
return new Vector2(lX, lY);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static Vector3 ParseVector3String(string lData, char lSeperator = ' ')
|
||||
{
|
||||
string[] lParts = lData.Split(new char[] { lSeperator }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
float lX = lParts[0].ParseInvariantFloat();
|
||||
float lY = lParts[1].ParseInvariantFloat();
|
||||
float lZ = lParts[2].ParseInvariantFloat();
|
||||
|
||||
return new Vector3(lX, lY, lZ);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static Vector4 ParseVector4String(string lData, char lSeperator = ' ')
|
||||
{
|
||||
string[] lParts = lData.Split(new char[] { lSeperator }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
float lX = lParts[0].ParseInvariantFloat();
|
||||
float lY = lParts[1].ParseInvariantFloat();
|
||||
float lZ = lParts[2].ParseInvariantFloat();
|
||||
float lW = lParts[3].ParseInvariantFloat();
|
||||
|
||||
return new Vector4(lX, lY, lZ, lW);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static Quaternion ParseQuaternion(string lJsonData)
|
||||
{
|
||||
string[] lQuaternionArray = lJsonData.Replace("(", "").Replace(")", "").Replace(" ", "").Split(',');
|
||||
Quaternion lQuaternion = Quaternion.identity;
|
||||
|
||||
if (float.TryParse(lQuaternionArray[0], out lQuaternion.x) == false)
|
||||
{
|
||||
return Quaternion.identity;
|
||||
}
|
||||
if (float.TryParse(lQuaternionArray[1], out lQuaternion.y) == false)
|
||||
{
|
||||
return Quaternion.identity;
|
||||
}
|
||||
if (float.TryParse(lQuaternionArray[2], out lQuaternion.z) == false)
|
||||
{
|
||||
return Quaternion.identity;
|
||||
}
|
||||
if (float.TryParse(lQuaternionArray[3], out lQuaternion.w) == false)
|
||||
{
|
||||
return Quaternion.identity;
|
||||
}
|
||||
|
||||
return lQuaternion;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static string Vector3String(Vector3 lVector3)
|
||||
{
|
||||
return "(" +
|
||||
lVector3.x.ToString("f3") + "," +
|
||||
lVector3.y.ToString("f3") + "," +
|
||||
lVector3.z.ToString("f3") +
|
||||
")";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static string Vector4String(Vector4 lVector4)
|
||||
{
|
||||
return "(" +
|
||||
lVector4.x.ToString("f3") + "," +
|
||||
lVector4.y.ToString("f3") + "," +
|
||||
lVector4.z.ToString("f3") + "," +
|
||||
lVector4.w.ToString("f3") +
|
||||
")";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static string QuaternionString(Quaternion lQuaternion)
|
||||
{
|
||||
return "(" +
|
||||
lQuaternion.x.ToString("f3") + "," +
|
||||
lQuaternion.y.ToString("f3") + "," +
|
||||
lQuaternion.z.ToString("f3") + "," +
|
||||
lQuaternion.w.ToString("f3") +
|
||||
")";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static int FirstInt(string lJsonData)
|
||||
{
|
||||
string lDigits = "";
|
||||
for (int lCount = 0; lCount < lJsonData.Length && Char.IsDigit(lJsonData[lCount]); ++lCount)
|
||||
{
|
||||
lDigits += lJsonData[lCount];
|
||||
}
|
||||
return int.Parse(lDigits);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 06a010ef6a1e94840a51827a2a02badc
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExtension
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static class Vector3Ext
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static readonly Vector3 IgnoreX = new Vector3(0f, 1f, 1f);
|
||||
public static readonly Vector3 IgnoreY = new Vector3(1f, 0f, 1f);
|
||||
public static readonly Vector3 IgnoreZ = new Vector3(1f, 1f, 0f);
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static Color ToColor(this Vector3 lVector)
|
||||
{
|
||||
return new Color(lVector.x, lVector.y, lVector.z);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static class Vector4Ext
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static Color ToColor(this Vector4 lVector)
|
||||
{
|
||||
return new Color(lVector.x, lVector.y, lVector.z, lVector.w);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18a26dda21abdf5468d5731a6dbd26c4
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 398bd6d854d804239926cbd17c9ee93c
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8700a9474fed74e75b15b31742f639e2
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
public class OBJData
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public List<Vector3> m_Vertices = new List<Vector3>();
|
||||
public List<Vector3> m_Normals = new List<Vector3>();
|
||||
public List<Vector2> m_UVs = new List<Vector2>();
|
||||
public List<Vector2> m_UV2s = new List<Vector2>();
|
||||
public List<Color> m_Colors = new List<Color>();
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public List<OBJMaterial> m_Materials = new List<OBJMaterial>();
|
||||
public List<OBJGroup> m_Groups = new List<OBJGroup>();
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c57f7fdab36a3f4d9d97f4785a884f6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,101 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
using UnityExtension;
|
||||
|
||||
public class OBJFace
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private readonly List<OBJFaceVertex> m_Vertices = new List<OBJFaceVertex>();
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public void AddVertex(OBJFaceVertex lVertex)
|
||||
{
|
||||
m_Vertices.Add(lVertex);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public void ParseVertex(string lVertexString)
|
||||
{
|
||||
var fields = lVertexString.Split(new[] { '/' }, StringSplitOptions.None);
|
||||
|
||||
var lIndex = fields[0].ParseInvariantInt();
|
||||
var faceVertex = new OBJFaceVertex
|
||||
{
|
||||
m_VertexIndex = lIndex - 1
|
||||
};
|
||||
|
||||
if (fields.Length > 1)
|
||||
{
|
||||
lIndex = fields[1].Length == 0 ? 0 : fields[1].ParseInvariantInt();
|
||||
faceVertex.m_UVIndex = lIndex - 1;
|
||||
}
|
||||
|
||||
if (fields.Length > 2)
|
||||
{
|
||||
lIndex = fields[2].Length == 0 ? 0 : fields[2].ParseInvariantInt();
|
||||
faceVertex.m_NormalIndex = lIndex - 1;
|
||||
}
|
||||
|
||||
if (fields.Length > 3)
|
||||
{
|
||||
lIndex = fields[3].Length == 0 ? 0 : fields[3].ParseInvariantInt();
|
||||
faceVertex.m_UV2Index = lIndex - 1;
|
||||
}
|
||||
|
||||
if (fields.Length > 4)
|
||||
{
|
||||
lIndex = fields[4].Length == 0 ? 0 : fields[4].ParseInvariantInt();
|
||||
faceVertex.m_ColorIndex = lIndex - 1;
|
||||
}
|
||||
|
||||
AddVertex(faceVertex);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public string ToString(int lIndex)
|
||||
{
|
||||
OBJFaceVertex lFaceVertex = m_Vertices[lIndex];
|
||||
|
||||
string lOutput = (lFaceVertex.m_VertexIndex + 1).ToString();
|
||||
|
||||
if (lFaceVertex.m_UVIndex > -1)
|
||||
{
|
||||
lOutput += string.Format("/{0}", (lFaceVertex.m_UVIndex + 1).ToString());
|
||||
}
|
||||
|
||||
if (lFaceVertex.m_NormalIndex > -1)
|
||||
{
|
||||
lOutput += string.Format("/{0}", (lFaceVertex.m_NormalIndex + 1).ToString());
|
||||
}
|
||||
|
||||
if (lFaceVertex.m_UV2Index > -1)
|
||||
{
|
||||
lOutput += string.Format("/{0}", (lFaceVertex.m_UV2Index + 1).ToString());
|
||||
}
|
||||
|
||||
if (lFaceVertex.m_ColorIndex > -1)
|
||||
{
|
||||
lOutput += string.Format("/{0}", (lFaceVertex.m_ColorIndex + 1).ToString());
|
||||
}
|
||||
|
||||
return lOutput;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public OBJFaceVertex this[int i]
|
||||
{
|
||||
get { return m_Vertices[i]; }
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public int Count
|
||||
{
|
||||
get { return m_Vertices.Count; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07402f6cbfe2d0e40ab4d7363cb0ed64
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
public class OBJFaceVertex
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public int m_VertexIndex = -1;
|
||||
public int m_UVIndex = -1;
|
||||
public int m_UV2Index = -1;
|
||||
public int m_NormalIndex = -1;
|
||||
public int m_ColorIndex = -1;
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_VertexIndex ^ m_UVIndex ^ m_UV2Index ^ m_NormalIndex ^ m_ColorIndex;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
OBJFaceVertex faceVertex = (OBJFaceVertex)obj;
|
||||
return m_VertexIndex == faceVertex.m_VertexIndex
|
||||
&& m_UVIndex == faceVertex.m_UVIndex
|
||||
&& m_UV2Index == faceVertex.m_UV2Index
|
||||
&& m_NormalIndex == faceVertex.m_NormalIndex
|
||||
&& m_ColorIndex == m_ColorIndex;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f5cff977d3365a4f9f33933bb603037
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class OBJGroup
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private readonly List<OBJFace> m_Faces = new List<OBJFace>();
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public OBJGroup(string lName)
|
||||
{
|
||||
m_Name = lName;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public string m_Name { get; private set; }
|
||||
public OBJMaterial m_Material { get; set; }
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public IList<OBJFace> Faces { get { return m_Faces; } }
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public void AddFace(OBJFace lFace)
|
||||
{
|
||||
m_Faces.Add(lFace);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8508b6de42212c84ebaec559aed6c7b6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,219 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
using UnityExtension;
|
||||
|
||||
/*
|
||||
* Currently only supports Triangluar Meshes
|
||||
*/
|
||||
|
||||
public class OBJLoader
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private static OBJData m_OBJData = null;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private static OBJMaterial m_CurrentMaterial = null;
|
||||
private static OBJGroup m_CurrentGroup = null;
|
||||
|
||||
#region PROCESSORS
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private static readonly Dictionary<string, Action<string>> m_ParseOBJActionDictionary = new Dictionary<string, Action<string>>
|
||||
{
|
||||
{ "mtllib", (lEntry) => { /*Load MTL*/ } },
|
||||
{ "usemtl", (lEntry) => { PushOBJGroupIfNeeded(); m_CurrentGroup.m_Material = m_OBJData.m_Materials.SingleOrDefault((lX) => { return lX.m_Name.EqualsInvariantCultureIgnoreCase(lEntry); }); } },
|
||||
{ "v", (lEntry) => { m_OBJData.m_Vertices.Add(Utils.ParseVector3String(lEntry)); } },
|
||||
{ "vn", (lEntry) => { m_OBJData.m_Normals.Add(Utils.ParseVector3String(lEntry)); } },
|
||||
{ "vt", (lEntry) => { m_OBJData.m_UVs.Add(Utils.ParseVector2String(lEntry)); } },
|
||||
{ "vt2", (lEntry) => { m_OBJData.m_UV2s.Add(Utils.ParseVector2String(lEntry)); } },
|
||||
{ "vc", (lEntry) => { m_OBJData.m_Colors.Add(Utils.ParseVector4String(lEntry).ToColor()); } },
|
||||
{ "f", PushOBJFace },
|
||||
{ "g", PushOBJGroup },
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private static readonly Dictionary<string, Action<string>> m_ParseMTLActionDictionary = new Dictionary<string, Action<string>>
|
||||
{
|
||||
{ "newmtl", PushOBJMaterial },
|
||||
{ "Ka", (lEntry) => { m_CurrentMaterial.m_AmbientColor = Utils.ParseVector3String(lEntry).ToColor(); } },
|
||||
{ "Kd", (lEntry) => { m_CurrentMaterial.m_DiffuseColor = Utils.ParseVector3String(lEntry).ToColor(); } },
|
||||
{ "Ks", (lEntry) => { m_CurrentMaterial.m_SpecularColor = Utils.ParseVector3String(lEntry).ToColor(); } },
|
||||
{ "Ns", (lEntry) => { m_CurrentMaterial.m_SpecularCoefficient = lEntry.ParseInvariantFloat(); } },
|
||||
{ "d", (lEntry) => { m_CurrentMaterial.m_Transparency = lEntry.ParseInvariantFloat(); } },
|
||||
{ "Tr", (lEntry) => { m_CurrentMaterial.m_Transparency = lEntry.ParseInvariantFloat(); } },
|
||||
{ "illum", (lEntry) => { m_CurrentMaterial.m_IlluminationModel = lEntry.ParseInvariantInt(); } },
|
||||
{ "map_Ka", (lEntry) => { m_CurrentMaterial.m_AmbientTextureMap = lEntry; } },
|
||||
{ "map_Kd", (lEntry) => { m_CurrentMaterial.m_DiffuseTextureMap = lEntry; } },
|
||||
{ "map_Ks", (lEntry) => { m_CurrentMaterial.m_SpecularTextureMap = lEntry; } },
|
||||
{ "map_Ns", (lEntry) => { m_CurrentMaterial.m_SpecularHighlightTextureMap = lEntry; } },
|
||||
{ "map_d", (lEntry) => { m_CurrentMaterial.m_AlphaTextureMap = lEntry; } },
|
||||
{ "map_bump", (lEntry) => { m_CurrentMaterial.m_BumpMap = lEntry; } },
|
||||
{ "bump", (lEntry) => { m_CurrentMaterial.m_BumpMap = lEntry; } },
|
||||
{ "disp", (lEntry) => { m_CurrentMaterial.m_DisplacementMap = lEntry; } },
|
||||
{ "decal",(lEntry) => { m_CurrentMaterial.m_StencilDecalMap = lEntry; } },
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region PUBLIC_INTERFACE
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static OBJData LoadOBJ(Stream lStream)
|
||||
{
|
||||
m_OBJData = new OBJData();
|
||||
|
||||
m_CurrentMaterial = null;
|
||||
m_CurrentGroup = null;
|
||||
|
||||
StreamReader lLineStreamReader = new StreamReader(lStream);
|
||||
|
||||
Action<string> lAction = null;
|
||||
string lCurrentLine = null;
|
||||
string[] lFields = null;
|
||||
string lKeyword = null;
|
||||
string lData = null;
|
||||
|
||||
while (!lLineStreamReader.EndOfStream)
|
||||
{
|
||||
lCurrentLine = lLineStreamReader.ReadLine();
|
||||
|
||||
if (StringExt.IsNullOrWhiteSpace(lCurrentLine)
|
||||
|| lCurrentLine[0] == '#')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
lFields = lCurrentLine.Trim().Split(null, 2);
|
||||
if (lFields.Length < 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
lKeyword = lFields[0].Trim();
|
||||
lData = lFields[1].Trim();
|
||||
|
||||
lAction = null;
|
||||
m_ParseOBJActionDictionary.TryGetValue(lKeyword.ToLowerInvariant(), out lAction);
|
||||
|
||||
if (lAction != null)
|
||||
{
|
||||
lAction(lData);
|
||||
}
|
||||
}
|
||||
|
||||
var lOBJData = m_OBJData;
|
||||
m_OBJData = null;
|
||||
|
||||
return lOBJData;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static void ExportOBJ(OBJData lData, Stream lStream)
|
||||
{
|
||||
StreamWriter lLineStreamWriter = new StreamWriter(lStream);
|
||||
|
||||
lLineStreamWriter.WriteLine(string.Format("# File exported by Unity3D version {0}", Application.unityVersion));
|
||||
|
||||
for (int lCount = 0; lCount < lData.m_Vertices.Count; ++lCount)
|
||||
{
|
||||
lLineStreamWriter.WriteLine(string.Format("v {0} {1} {2}",
|
||||
lData.m_Vertices[lCount].x.ToString("n8"),
|
||||
lData.m_Vertices[lCount].y.ToString("n8"),
|
||||
lData.m_Vertices[lCount].z.ToString("n8")));
|
||||
}
|
||||
|
||||
for (int lCount = 0; lCount < lData.m_UVs.Count; ++lCount)
|
||||
{
|
||||
lLineStreamWriter.WriteLine(string.Format("vt {0} {1}",
|
||||
lData.m_UVs[lCount].x.ToString("n5"),
|
||||
lData.m_UVs[lCount].y.ToString("n5")));
|
||||
}
|
||||
|
||||
for (int lCount = 0; lCount < lData.m_UV2s.Count; ++lCount)
|
||||
{
|
||||
lLineStreamWriter.WriteLine(string.Format("vt2 {0} {1}",
|
||||
lData.m_UVs[lCount].x.ToString("n5"),
|
||||
lData.m_UVs[lCount].y.ToString("n5")));
|
||||
}
|
||||
|
||||
for (int lCount = 0; lCount < lData.m_Normals.Count; ++lCount)
|
||||
{
|
||||
lLineStreamWriter.WriteLine(string.Format("vn {0} {1} {2}",
|
||||
lData.m_Normals[lCount].x.ToString("n8"),
|
||||
lData.m_Normals[lCount].y.ToString("n8"),
|
||||
lData.m_Normals[lCount].z.ToString("n8")));
|
||||
}
|
||||
|
||||
for (int lCount = 0; lCount < lData.m_Colors.Count; ++lCount)
|
||||
{
|
||||
lLineStreamWriter.WriteLine(string.Format("vc {0} {1} {2} {3}",
|
||||
lData.m_Colors[lCount].r.ToString("n8"),
|
||||
lData.m_Colors[lCount].g.ToString("n8"),
|
||||
lData.m_Colors[lCount].b.ToString("n8"),
|
||||
lData.m_Colors[lCount].a.ToString("n8")));
|
||||
}
|
||||
|
||||
for (int lGroup = 0; lGroup < lData.m_Groups.Count; ++lGroup)
|
||||
{
|
||||
lLineStreamWriter.WriteLine(string.Format("g {0}", lData.m_Groups[lGroup].m_Name));
|
||||
|
||||
for (int lFace = 0; lFace < lData.m_Groups[lGroup].Faces.Count; ++lFace)
|
||||
{
|
||||
lLineStreamWriter.WriteLine(string.Format("f {0} {1} {2}",
|
||||
lData.m_Groups[lGroup].Faces[lFace].ToString(0),
|
||||
lData.m_Groups[lGroup].Faces[lFace].ToString(1),
|
||||
lData.m_Groups[lGroup].Faces[lFace].ToString(2)));
|
||||
}
|
||||
}
|
||||
|
||||
lLineStreamWriter.Flush();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private static void PushOBJMaterial(string lMaterialName)
|
||||
{
|
||||
m_CurrentMaterial = new OBJMaterial(lMaterialName);
|
||||
m_OBJData.m_Materials.Add(m_CurrentMaterial);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private static void PushOBJGroup(string lGroupName)
|
||||
{
|
||||
m_CurrentGroup = new OBJGroup(lGroupName);
|
||||
m_OBJData.m_Groups.Add(m_CurrentGroup);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private static void PushOBJGroupIfNeeded()
|
||||
{
|
||||
if (m_CurrentGroup == null)
|
||||
{
|
||||
PushOBJGroup("default");
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
private static void PushOBJFace(string lFaceLine)
|
||||
{
|
||||
PushOBJGroupIfNeeded();
|
||||
|
||||
var vertices = lFaceLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
var face = new OBJFace();
|
||||
|
||||
foreach (var vertexString in vertices)
|
||||
{
|
||||
face.ParseVertex(vertexString);
|
||||
}
|
||||
|
||||
m_CurrentGroup.AddFace(face);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bda02739f6fbaeb4c8c3da925164b8cf
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
public class OBJMaterial
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public OBJMaterial(string lMaterialName)
|
||||
{
|
||||
m_Name = lMaterialName;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public string m_Name;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public Color m_AmbientColor;
|
||||
public Color m_DiffuseColor;
|
||||
public Color m_SpecularColor;
|
||||
public float m_SpecularCoefficient;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public float m_Transparency;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public int m_IlluminationModel;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public string m_AmbientTextureMap;
|
||||
public string m_DiffuseTextureMap;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public string m_SpecularTextureMap;
|
||||
public string m_SpecularHighlightTextureMap;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public string m_BumpMap;
|
||||
public string m_DisplacementMap;
|
||||
public string m_StencilDecalMap;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public string m_AlphaTextureMap;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ceb2526c78b78c04592f312a4e65ec95
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32ca95fc59e8743b3b0033ddfb038e11
|
||||
folderAsset: yes
|
||||
timeCreated: 1465591252
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct Int32Converter
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
[FieldOffset(0)]
|
||||
public int Value;
|
||||
[FieldOffset(0)]
|
||||
public byte Byte1;
|
||||
[FieldOffset(1)]
|
||||
public byte Byte2;
|
||||
[FieldOffset(2)]
|
||||
public byte Byte3;
|
||||
[FieldOffset(3)]
|
||||
public byte Byte4;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public Int32Converter(int value)
|
||||
{
|
||||
Byte1 = Byte2 = Byte3 = Byte4 = 0;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static implicit operator Int32(Int32Converter value)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
public static implicit operator Int32Converter(int value)
|
||||
{
|
||||
return new Int32Converter(value);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2980235c1e3576a4ab7dca278af19308
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,36 +0,0 @@
|
||||
|
||||
/* * * * * * * * * * * * Author's note * * * * * * * * * * * * * *\
|
||||
* *
|
||||
* ZZ$$Z$$$$Z$$$ *
|
||||
* ZZZZZZZZZZZZZ *
|
||||
* ZZZZZZZZZZZZZ *
|
||||
* $ZZZZZZZZZZZZ *
|
||||
* $ZZZZZZZZZZZZ *
|
||||
* ZZ7=$OOO$?$ZO *
|
||||
* Z7 $OZ IO *
|
||||
* ZZZZZZZZOOOZOOOOOZZ8OZZZZZZZZZ *
|
||||
* NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO *
|
||||
* NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO *
|
||||
* 8O8OOOOO8 88O88O8888888 D88888888 *
|
||||
* 8OOOOOOO8 8OOON OO88 DO8888888 *
|
||||
* DDDDDDDDD DDDD DDDD NDDDDDDDD *
|
||||
* *
|
||||
* http://octo-dev.co.uk *
|
||||
* *
|
||||
* OBJ-IO *
|
||||
* *
|
||||
* Copyright (c) Octo-Dev *
|
||||
* *
|
||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
The scripts for this plugin are in [OBJ-IO/Plugins/OBJ]
|
||||
and [OBJ-IO/Plugins/Extension].
|
||||
|
||||
There is an Example scene that Imports the Teapot OBJ at runtime,
|
||||
distorts the vertexs and exports it again. The Export and Import
|
||||
functions take System.IO.Stream as a parameter so this can be adapted
|
||||
for your needs.
|
||||
|
||||
The System Current only supports geometry.
|
||||
|
||||
If there is any issue or bugs please contact : tim.leader.octo@gmail.com
|
||||
@@ -1,6 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1f277bf041647445ac3bf5b643a46fe
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user