sp 导出unity哪个_GitHub上发现的一个导出Unity3D场景数据的工具

1、源地址

2、导出脚本

脚本名:Unity3DExporter.cs

```C#

using UnityEditor;

using UnityEngine;

using System;

using System.Collections.Generic;

using System.Linq;

using System.IO;

public class Unity3DExporter : EditorWindow

{

private static bool mIsWindowOpen;

private bool mExportXmlOnly;

private bool mIgnoreUnderscore;

private bool mShowAdvancedSettings;

private bool mExportStateMaterial = true;

private bool mDontGenerateMipmapsForLightmaps = true;

private bool mDiscardTexturesOnBind = true;

private bool mWriteDataAsBigEndian = true;

private bool mCombineStaticMeshes = true;

private bool mWriteColorsAs32Bit = true;

private bool mWriteNormalmaps = false;

private string mPath;

private bool mDebugPushLightsToLeaf = false;

private List mMeshAssetsProcessed;

private Dictionary mMeshAssetNameToMeshName;

private Dictionary mMeshNameToCount;

private Dictionary mTextureToName;

private Dictionary mTextureNameToCount;

private List mMaterialAssetsProcessed;

private Dictionary mMaterialAssetNameToMaterialName;

private Dictionary mMaterialNameToCount;

private Dictionary mLightToName;

private Dictionary mLightNameToCount;

private struct Statistics

{

public int LightmapsCount;

public int LightmapsTotalSizeOnDisk;

public int LightmapsTotalSizeInRam;

public int TexturesCount;

public int TexturesTotalSizeOnDisk;

public int TexturesTotalSizeInRam;

public void Print()

{

Debug.Log("---> Export Statistics

Debug.Log("Textures: " + TexturesCount + " (Lightmaps: " + LightmapsCount + ")\n");

Debug.Log("Textures total size in RAM: " + (TexturesTotalSizeInRam / (1024.0f * 1024.0f)).ToString("F2") + " MB (Lightmaps: " + (LightmapsTotalSizeInRam / (1024.0f * 1024.0f)).ToString("F2") + " MB)\n");

Debug.Log("Textures total size on disk: " + (TexturesTotalSizeOnDisk / (1024.0f * 1024.0f)).ToString("F2") + " MB (Lightmaps: " + (LightmapsTotalSizeOnDisk / (1024.0f * 1024.0f)).ToString("F2") + " MB)\n");

}

}

private Statistics mStatistics;

[MenuItem("Wire3D/Exporter")]

protected static void CreateWizard ()

{

if (!mIsWindowOpen) {

mIsWindowOpen = true;

Unity3DExporter editor = GetWindow ((typeof(Unity3DExporter))) as Unity3DExporter;

if (editor) {

editor.autoRepaintOnSceneChange = true;

}

}

}

private static List GetRootTransforms()

{

List allTransforms = new List (FindObjectsOfType (typeof(Transform)) as Transform[]);

List rootTransforms = allTransforms.Where (t => t.parent == null).ToList ();

return (from s in rootTransforms orderby s.name select s).ToList ();

}

private static bool HasRenderObject (Transform transform)

{

GameObject gameObject = transform.gameObject;

MeshFilter meshFilter = gameObject.GetComponent ();

MeshRenderer meshRenderer = gameObject.GetComponent ();

return (meshFilter != null && meshFilter.sharedMesh != null) &&

(meshRenderer != null && meshRenderer.enabled);

}

protected void OnDestroy()

{

mIsWindowOpen = false;

if (mTextureToName != null)

{

mTextureToName.Clear();

}

if (mLightToName != null)

{

mLightToName.Clear();

}

}

protected virtual void OnGUI()

{

ShowSaveDialog();

GUILayout.Space(10);

ShowSettingsDialog();

GUILayout.Space(10);

ShowAdvancedSettingsDialog();

GUILayout.Space(20);

ShowExportDialog();

}

private void ShowSaveDialog()

{

EditorGUILayout.BeginHorizontal();

EditorGUIUtility.LookLikeControls();

mPath = EditorGUILayout.TextField("Save to directory:", mPath ?? string.Empty);

EditorGUILayout.EndHorizontal();

if (string.IsNullOrEmpty(mPath) || !Directory.Exists(mPath))

{

Color c = GUI.contentColor;

GUI.contentColor = new Color(1, 1, 0.1f);

if (string.IsNullOrEmpty(mPath))

{

GUILayout.Label("Enter a destination path for saving the exported data.");

}

else

{

GUILayout.Label("Specified path '" + mPath + "' does not exist.");

}

GUI.contentColor = c;

}

}

private void ShowSettingsDialog()

{

mExportXmlOnly = GUILayout.Toggle(mExportXmlOnly, new GUIContent("Export scene XML file only", "Textures, meshes, etc. will not be exported."));

mIgnoreUnderscore = GUILayout.Toggle(mIgnoreUnderscore, "Ignore GameObjects starting with '_'");

}

private void ShowAdvancedSettingsDialog()

{

mShowAdvancedSettings = EditorGUILayout.Foldout(mShowAdvancedSettings, "Advanced Settings");

if (!mShowAdvancedSettings)

{

return;

}

mCombineStaticMeshes = GUILayout.Toggle(mCombineStaticMeshes, new GUIContent(

"Combine static meshes",

"Prepares static meshes for drawcall batching."));

mExportStateMaterial = GUILayout.Toggle(mExportStateMaterial, new GUIContent(

"Try to export StateMaterial from shader",

"The 'Main Color', 'Tint Color' or 'Tint' (if available) of a shader will be exported as the StateMaterial's ambient color."));

mDontGenerateMipmapsForLightmaps = GUILayout.Toggle(mDontGenerateMipmapsForLightmaps, new GUIContent(

"Do not generate mipmaps for lightmaps",

"Reduces size of lightmaps by 33%"));

mDiscardTexturesOnBind = GUILayout.Toggle(mDiscardTexturesOnBind, new GUIContent(

"Flag textures as 'discard on bind'",

"Textures that are not discarded at bind time can be bound multiple times, but at the cost of double ram usage per texture."));

mWriteDataAsBigEndian = GUILayout.Toggle(mWriteDataAsBigEndian, new GUIContent(

"Write data as big endian",

"PC uses little endian. Wii uses big endian. Byte order will be rearranged by the Importer if necessary. Thus favoring a particular order gives a slight speedup when importing data on that particular platform."));

mWriteColorsAs32Bit = GUILayout.Toggle(mWriteColorsAs32Bit, new GUIContent(

"Write vertex colors as 32bit",

"Write vertex colors of meshes as 32 bit values instead of 4 floats"));

mWriteNormalmaps = GUILayout.Toggle(mWriteNormalmaps, new GUIContent(

"Write normal maps"));

}

private void ShowExportDialog()

{

if ((Directory.Exists(mPath) && !string.IsNullOrEmpty(mPath)) == false)

{

return;

}

if (GUILayout.Button("Export"))

{

if (mPath[mPath.Length - 1] != '/' && mPath[mPath.Length - 1] != '\\')

{

mPath = mPath + '/';

}

mMeshAssetsProcessed = new List();

mMeshAssetNameToMeshName = new Dictionary();

mMeshNameToCount = new Dictionary();

mTextureToName = new Dictionary();

mTextureNameToCount = new Dictionary();

mMaterialAssetsProcessed = new List();

mMaterialAssetNameToMaterialName = new Dictionary();

mMaterialNameToCount = new Dictionary();

mLightToName = new Dictionary();

mLightNameToCount = new Dictionary();

mStatistics = new Statistics();

Dictionary backupMeshFilterToMesh = null;

if (mCombineStaticMeshes)

{

CombineStaticMeshes(out backupMeshFilterToMesh);

}

Export();

if (mCombineStaticMeshes)

{

UncombineStaticMeshes(backupMeshFilterToMesh);

}

if (!mExportXmlOnly)

{

mStatistics.Print();

}

}

}

private static void CombineStaticMeshes(out Dictionary backupMeshFilterToMesh)

{

backupMeshFilterToMesh = new Dictionary();

List roots = GetRootTransforms();

foreach (Transform root in roots)

{

Stack stack = new Stack();

stack.Push(root);

List gos = new List();

while (stack.Count > 0)

{

Transform t = stack.Pop();

if (t.gameObject.isStatic)

{

gos.Add(t.gameObject);

}

for (int i = t.childCount-1; i >= 0; i--)

{

stack.Push(t.GetChild(i));

}

}

foreach (GameObject go in gos)

{

MeshFilter mf = go.GetComponent();

if (mf != null)

{

backupMeshFilterToMesh.Add(mf, mf.sharedMesh);

}

}

StaticBatchingUtility.Combine(gos.ToArray(), root.gameObject);

}

}

private static void UncombineStaticMeshes(Dictionary backupMeshFilterToMesh)

{

if (backupMeshFilterToMesh == null)

{

return;

}

foreach (KeyValuePair pair in backupMeshFilterToMesh)

{

pair.Key.sharedMesh = pair.Value;

if (pair.Key.sharedMesh != null)

{

MeshRenderer mr = pair.Key.gameObject.GetComponent();

if (mr == null)

{

continue;

}

SerializedObject so = new SerializedObject(mr);

SerializedProperty sp = so.FindProperty("m_SubsetIndices");

if (sp != null && sp.isArray)

{

sp.arraySize = 0;

so.ApplyModifiedProperties();

}

}

}

}

private static string GetUniqueName(string originalName, Dictionary context)

{

int nameUsageCount = context.ContainsKey(originalName) ? context[originalName] : 0;

context[originalName] = ++nameUsageCount;

if (nameUsageCount > 1)

{

string newName = originalName + "_" + nameUsageCount + "_(renamed)";

Debug.LogWarning("Renaming '" + originalName + "' to '" + newName + "'");

return newName;

}

else

{

return originalName;

}

}

private void WriteRenderObject(Transform transform, StreamWriter outFile, string indent)

{

GameObject go = transform.gameObject;

MeshFilter meshFilter = go.GetComponent();

MeshRenderer meshRenderer = go.GetComponent();

if ((meshRenderer == null) || (meshFilter == null)) {

return;

}

int subMeshIndex = -1;

int submeshCount = meshFilter.sharedMesh.subMeshCount;

SerializedObject so = new SerializedObject(meshRenderer);

SerializedProperty sp = so.FindProperty("m_SubsetIndices");

if (sp != null && sp.isArray)

{

if (sp.arraySize > 0)

{

submeshCount = sp.arraySize;

subMeshIndex = sp.GetArrayElementAtIndex(0).intValue;

}

}

bool exportSubmeshes = submeshCount > 1 ? true : false;

if (exportSubmeshes)

{

subMeshIndex = 0;

}

List lights = GetLightsForRenderer(meshRenderer);

bool extraNode = false;

if (lights.Count > 0 && transform.childCount > 0)

{

indent = indent + " ";

string isStatic = go.isStatic ? " Static=\"1\"" : "";

string layer = go.layer == 0 ? "" : " Layer=\"" + go.layer + "\"";

outFile.WriteLine(indent + "");

extraNode = true;

}

if (mDebugPushLightsToLeaf)

{

foreach (Light light in lights)

{

WriteLight(light, outFile, indent);

}

}

if (exportSubmeshes)

{

WriteSubLeaves(go, outFile, indent + " ");

}

else

{

WriteMesh(meshFilter.sharedMesh, meshRenderer, outFile, indent + " ", subMeshIndex);

WriteMaterial(meshRenderer, meshRenderer.sharedMaterial, outFile, indent + " ");

}

if (extraNode)

{

outFile.WriteLine(indent + "");

}

}

private List GetLightsForRenderer(Renderer renderer)

{

List lights = new List();

int layerMask = 1 << renderer.gameObject.layer;

foreach (Light light in mLightToName.Keys)

{

const int realtimeOnly = 0;

if (!IsLightmapped(renderer) || (GetLightmapping(light) == realtimeOnly))

{

if ((layerMask & light.cullingMask) != 0)

{

lights.Add(light);

}

}

}

return lights;

}

private void WriteSubLeaves(GameObject gameObject, StreamWriter outFile, string indent)

{

MeshFilter meshFilter = gameObject.GetComponent();

MeshRenderer meshRenderer = gameObject.GetComponent();

if ((meshRenderer == null) || (meshFilter == null))

{

return;

}

Mesh mesh = meshFilter.sharedMesh;

string isStatic = gameObject.isStatic ? " Static=\"1\"" : "";

string layer = gameObject.layer == 0 ? "" : " Layer=\"" + gameObject.layer + "\"";

SerializedObject so = new SerializedObject(meshRenderer);

SerializedProperty sp = so.FindProperty("m_SubsetIndices");

if (sp != null && sp.isArray)

{

if (sp.arraySize != 0)

{

for (int j = 0; j < sp.arraySize; j++)

{

int i = sp.GetArrayElementAtIndex(j).intValue;

outFile.WriteLine(indent + "");

WriteMesh(mesh, meshRenderer, outFile, indent + " ", i);

WriteMaterial(meshRenderer, meshRenderer.sharedMaterials[j], outFile, indent + " ");

outFile.WriteLine(indent + "");

}

}

else

{

int submeshCount = mesh.subMeshCount;

for (int i = 0; i < submeshCount; i++)

{

outFile.WriteLine(indent + "");

WriteMesh(mesh, meshRenderer, outFile, indent + " ", i);

WriteMaterial(meshRenderer, meshRenderer.sharedMaterials[i], outFile, indent + " ");

outFile.WriteLine(indent + "");

}

}

}

}

private void WriteNode(Transform transform, StreamWriter outFile, string indent)

{

GameObject go = transform.gameObject;

string trafo = GetTransformAsString(transform, go.isStatic);

string isStatic = "";

if (go.isStatic)

{

if (!trafo.Equals(""))

{

isStatic += " ";

}

isStatic += "Static=\"1\"";

}

bool isEmpty = go.transform.childCount == 0;

Component[] components = go.GetComponents();

isEmpty = isEmpty && (components == null || components.Length < 2);

string slash = isEmpty ? " /" : "";

string layer = go.layer == 0 ? "" : " Layer=\"" + go.layer + "\"";

outFile.WriteLine(indent + "

trafo + isStatic + layer + slash + ">");

WriteLightNode(go.GetComponent(), outFile, indent);

WriteCamera(go.GetComponent(), outFile, indent);

WriteColliders(go, outFile, indent);

WriteRigidbody(go, outFile, indent);

if (HasRenderObject(transform))

{

WriteRenderObject(transform, outFile, indent);

}

for (int i = 0; i < transform.childCount; i++)

{

Traverse(transform.GetChild (i), outFile, indent + " ");

}

if (!isEmpty)

{

outFile.WriteLine(indent + "

");

}

}

private void WriteSkybox (StreamWriter outFile, string indent)

{

Material skyboxMaterial = RenderSettings.skybox;

if (skyboxMaterial == null) {

return;

}

Shader skyBoxShader = skyboxMaterial.shader;

if (skyBoxShader == null) {

return;

}

if (!skyBoxShader.name.Equals ("RenderFX/Skybox")) {

return;

}

Texture2D posZTexture2D = GetTextureFromMaterial (skyboxMaterial, "_FrontTex");

Texture2D negZTexture2D = GetTextureFromMaterial (skyboxMaterial, "_BackTex");

Texture2D posXTexture2D = GetTextureFromMaterial (skyboxMaterial, "_LeftTex");

Texture2D negXTexture2D = GetTextureFromMaterial (skyboxMaterial, "_RightTex");

Texture2D posYTexture2D = GetTextureFromMaterial (skyboxMaterial, "_UpTex");

Texture2D negYTexture2D = GetTextureFromMaterial (skyboxMaterial, "_DownTex");

outFile.WriteLine (indent + "");

WriteMaterialState(skyboxMaterial, outFile, indent);

outFile.WriteLine (indent + " " + "");

WriteTexture (posZTexture2D, outFile, indent + " ");

outFile.WriteLine (indent + " " + "");

outFile.WriteLine (indent + " " + "");

WriteTexture (negZTexture2D, outFile, indent + " ");

outFile.WriteLine (indent + " " + "");

outFile.WriteLine (indent + " " + "");

WriteTexture (negXTexture2D, outFile, indent + " ");

outFile.WriteLine (indent + " " + "");

outFile.WriteLine (indent + " " + "");

WriteTexture (posXTexture2D, outFile, indent + " ");

outFile.WriteLine (indent + " " + "");

outFile.WriteLine (indent + " " + "");

WriteTexture (posYTexture2D, outFile, indent + " ");

outFile.WriteLine (indent + " " + "");

outFile.WriteLine (indent + " " + "");

WriteTexture (negYTexture2D, outFile, indent + " ");

outFile.WriteLine (indent + " " + "");

outFile.WriteLine(indent + "");

outFile.WriteLine (indent + "");

}

static private Texture2D GetTextureFromMaterial (Material material, string propertyName)

{

Texture2D texture = null;

if (material.HasProperty (propertyName)) {

texture = material.GetTexture (propertyName) as Texture2D;

}

return texture;

}

private void Traverse(Transform transform, StreamWriter outFile, string indent)

{

if (mIgnoreUnderscore && transform.gameObject.name.StartsWith("_"))

{

return;

}

WriteNode(transform, outFile, indent);

}

private void Export()

{

string[] unityScenePath = EditorApplication.currentScene.Split (char.Parse ("/"));

string unitySceneName = unityScenePath[unityScenePath.Length - 1];

if (string.IsNullOrEmpty (unitySceneName))

{

Debug.LogWarning("Scene has no name.\n");

}

else

{

if (unitySceneName.Substring (unitySceneName.Length - 6, 6).Equals (".unity")) {

unitySceneName = unitySceneName.Remove(unitySceneName.Length - 6);

}

}

StreamWriter outFile = new StreamWriter (mPath + unitySceneName + ".xml");

try {

WriteOptions(outFile);

WriteAssets(outFile);

outFile.WriteLine("");

string indent = " ";

if (!mDebugPushLightsToLeaf)

{

foreach (Light light in mLightToName.Keys)

{

WriteLight(light, outFile, "");

}

}

WriteStateFog (outFile, indent);

foreach (Transform transform in GetRootTransforms ()) {

Traverse (transform, outFile, indent);

}

WriteSkybox (outFile, indent);

outFile.WriteLine ("");

} finally {

outFile.Close ();

}

}

private string GetTransformAsString(Transform transform, bool useWorldTransform = false)

{

GameObject go = transform.gameObject;

MeshRenderer meshRenderer = go.GetComponent();

if (meshRenderer != null)

{

SerializedObject so = new SerializedObject(meshRenderer);

SerializedProperty sp = so.FindProperty("m_SubsetIndices");

if (sp != null && sp.isArray)

{

if (sp.arraySize > 0)

{

return string.Empty;

}

}

}

Vector3 position = transform.localPosition;

Quaternion rotation = transform.localRotation;

Vector3 scale = transform.localScale;

if (useWorldTransform)

{

position = transform.position;

rotation = transform.rotation;

scale = transform.lossyScale;

}

string trafo = "";

if (position.x != 0.0f || position.y != 0.0f || position.z != 0.0f)

{

trafo += "Pos=\"" + (-position.x) + ", " + position.y + ", " + position.z + "\"";

}

if (rotation.w != 1.0f || rotation.x != 0.0f || rotation.y != 0.0f || rotation.z != 0.0f)

{

if (!trafo.Equals(""))

{

trafo += " ";

}

trafo += "Rot=\"" + rotation.w + ", " + rotation.x + ", " + (-rotation.y) + ", " + (-rotation.z) + "\"";

}

if (scale.x != 1.0f || scale.y != 1.0f || scale.z != 1.0f)

{

if (!trafo.Equals(""))

{

trafo += " ";

}

trafo += "Scale=\"" + scale.x + ", " + scale.y + ", " + scale.z + "\"";

}

return trafo;

}

private void WriteOptions(StreamWriter outFile)

{

outFile.WriteLine("");

outFile.WriteLine(" ");

outFile.WriteLine("");

}

private void WriteAssets(StreamWriter outFile)

{

outFile.WriteLine("");

string indent = " ";

WriteLightAssets(outFile, indent);

WriteMeshAssets(outFile, indent);

WriteMaterialAssets(outFile, indent);

outFile.WriteLine("");

}

private void WriteLightAssets(StreamWriter outFile, string indent)

{

bool foundLight = false;

List rootTransforms = GetRootTransforms();

foreach (Transform transform in rootTransforms)

{

if (mIgnoreUnderscore && transform.gameObject.name.StartsWith("_"))

{

continue;

}

Light[] lights = transform.gameObject.GetComponentsInChildren();

foreach (Light light in lights)

{

const int bakedOnly = 2;

if (GetLightmapping(light) != bakedOnly)

{

if (!foundLight)

{

outFile.WriteLine(" ");

foundLight = true;

}

WriteLight(light, outFile, indent);

}

}

}

if (foundLight)

{

outFile.WriteLine(" ");

}

}

private struct MeshAndMeshRenderer

{

public Mesh mesh;

public MeshRenderer renderer;

}

private void WriteMeshAssets(StreamWriter outFile, string indent)

{

Stack stack = new Stack();

foreach (Transform transform in GetRootTransforms())

{

stack.Push(transform);

}

List renderMeshes = new List();

List collisionMeshes = new List();

while (stack.Count > 0)

{

Transform t = stack.Pop();

if (mIgnoreUnderscore && t.gameObject.name.StartsWith("_"))

{

continue;

}

for (int i = t.childCount - 1; i >= 0; i--)

{

stack.Push(t.GetChild(i));

}

MeshCollider meshCollider = t.gameObject.GetComponent();

Mesh collisionMesh = (meshCollider != null) ? meshCollider.sharedMesh : null;

if (HasRenderObject(t) || collisionMesh != null)

{

MeshFilter meshFilter = t.gameObject.GetComponent();

if (meshFilter == null && collisionMesh == null)

{

continue;

}

MeshRenderer meshRenderer = t.gameObject.GetComponent();

Mesh renderMesh = meshFilter != null ? meshFilter.sharedMesh : null;

if (meshFilter != null)

{

MeshAndMeshRenderer mmr = new MeshAndMeshRenderer();

mmr.mesh = renderMesh;

mmr.renderer = meshRenderer;

renderMeshes.Add(mmr);

}

if (collisionMesh != null && collisionMesh != renderMesh)

{

MeshAndMeshRenderer mmr = new MeshAndMeshRenderer();

mmr.mesh = collisionMesh;

mmr.renderer = null;

collisionMeshes.Add(mmr);

}

}

}

bool foundAsset = renderMeshes.Count > 0 || collisionMeshes.Count > 0;

if (foundAsset)

{

outFile.WriteLine(" ");

}

foreach (MeshAndMeshRenderer mmr in renderMeshes)

{

WriteMeshAsset(mmr.mesh, mmr.renderer, outFile, indent);

}

foreach (MeshAndMeshRenderer mmr in collisionMeshes)

{

WriteMeshAsset(mmr.mesh, mmr.renderer, outFile, indent, true);

}

if (foundAsset)

{

outFile.WriteLine(" ");

}

}

private void WriteMaterialAssets(StreamWriter outFile, string indent)

{

Stack stack = new Stack();

foreach (Transform transform in GetRootTransforms())

{

stack.Push(transform);

}

bool foundAsset = false;

while (stack.Count > 0)

{

Transform t = stack.Pop();

if (mIgnoreUnderscore && t.gameObject.name.StartsWith("_"))

{

continue;

}

for (int i = t.childCount-1; i >= 0; i--)

{

stack.Push(t.GetChild(i));

}

if (HasRenderObject(t))

{

MeshRenderer meshRenderer = t.gameObject.GetComponent();

foreach (Material material in meshRenderer.sharedMaterials)

{

string materialAssetName = GetMaterialAssetName(material, meshRenderer);

if (!mMaterialAssetsProcessed.Contains(materialAssetName))

{

if (!foundAsset)

{

foundAsset = true;

outFile.WriteLine(" ");

}

WriteMaterial(meshRenderer, material, outFile, indent);

}

}

}

}

if (foundAsset)

{

outFile.WriteLine(" ");

}

}

private void WriteMeshAsset(Mesh mesh, MeshRenderer meshRenderer, StreamWriter outFile, string indent,

bool isCollisionMesh = false)

{

if (mesh != null)

{

string meshAssetName = GetMeshAssetName(mesh, GetLightmapTilingOffset(meshRenderer));

if (!mMeshAssetsProcessed.Contains(meshAssetName))

{

WriteMesh(mesh, meshRenderer, outFile, indent, -1, isCollisionMesh);

}

}

}

private Vector4 GetLightmapTilingOffset(MeshRenderer meshRenderer)

{

if (meshRenderer == null)

{

return new Vector4(1, 1, 0, 0);

}

// combined meshes already have lightmap tiling and offset applied

Vector4 lightmapTilingOffset = meshRenderer.lightmapScaleOffset;

SerializedObject so = new SerializedObject(meshRenderer);

SerializedProperty sp = so.FindProperty("m_SubsetIndices");

if (sp != null && sp.isArray)

{

if (sp.arraySize != 0)

{

lightmapTilingOffset = new Vector4(1, 1, 0, 0);

}

}

return lightmapTilingOffset;

}

private void WriteStateFog (StreamWriter outFile, string indent)

{

if (!RenderSettings.fog)

{

return;

}

string enabled = RenderSettings.fog ? "1" : "0";

Color color = RenderSettings.fogColor;

string mode = "LINEAR";

if (RenderSettings.fogMode == FogMode.Exponential)

{

mode = "EXP";

}

else if (RenderSettings.fogMode == FogMode.ExponentialSquared)

{

mode = "EXPSQR";

}

outFile.WriteLine(indent + "

"Start=\"" + RenderSettings.fogStartDistance + "\" End=\"" + RenderSettings.fogEndDistance + "\"" + " Mode=\"" + mode + "\" />");

}

private void WriteLightNode(Light light, StreamWriter outFile, string indent)

{

if (light == null)

{

return;

}

outFile.WriteLine(indent + " " + "");

WriteLight(light, outFile, indent + " ");

outFile.WriteLine(indent + " " + "");

}

private void WriteLight(Light light, StreamWriter outFile, string indent)

{

if (light == null)

{

return;

}

bool alreadyProcessed = true;

if (!mLightToName.ContainsKey(light))

{

mLightToName.Add(light, GetUniqueName(light.name, mLightNameToCount));

alreadyProcessed = false;

}

string lightName = mLightToName[light];

Color ambient = RenderSettings.ambientLight;

Color color = light.color * light.intensity;

string lightmap = string.Empty;

const int realtimeOnly = 0;

if (GetLightmapping(light) == realtimeOnly)

{

ambient = new Color(0, 0, 0, 0);

}

else

{

lightmap = " Baked=\"1\"";

}

if (alreadyProcessed)

{

outFile.WriteLine(indent + " " + "");

}

else

{

string direction = string.Empty;

if (light.type != LightType.Point)

{

direction = " Direction=\"0, 0, 1\"";

}

string range = light.type != LightType.Directional ? " Range=\"" + light.range + "\"" : "";

string mask = light.cullingMask == ~0 ? "" : " Mask=\"" + light.cullingMask.ToString("X") + "\"";

string enabled = light.enabled ? "" : " Enabled=\"0\"";

outFile.WriteLine(indent + " " + "

"\"" + direction + range + " Ambient=\"" + ambient.r + ", " + ambient.g + ", " + ambient.b +

"\" Color=\"" + color.r + ", " + color.g + ", " + color.b + "\"" + mask + enabled + lightmap + " />");

}

}

private void WriteColliders(GameObject gameObject, StreamWriter outFile, string indent)

{

Collider[] colliders = gameObject.GetComponents();

foreach (Collider collider in colliders)

{

WriteCollider(collider, gameObject, outFile, indent);

}

}

private void WriteCollider(Collider collider, GameObject gameObject, StreamWriter outFile, string indent)

{

if (collider == null)

{

return;

}

string shape = GetColliderShapeName(collider);

string isEnabled = collider.enabled ? string.Empty : "Enabled=\"0\" ";

outFile.Write (indent + " " + "

if (collider is BoxCollider)

{

WriteBoxColliderAttributes(collider as BoxCollider, outFile, indent);

}

else if (collider is SphereCollider)

{

WriteSphereColliderAttributes(collider as SphereCollider, outFile, indent);

}

else if (collider is CapsuleCollider)

{

WriteCapsuleColliderAttributes(collider as CapsuleCollider, outFile, indent);

}

else if (collider is MeshCollider)

{

WriteMeshColliderAttributes(collider as MeshCollider, outFile, indent);

}

else if (collider is CharacterController)

{

WriteCharacterControllerAttributes(collider as CharacterController, outFile, indent);

}

else

{

Debug.Log("Collider shape not supported: '" + shape + "'.", gameObject);

}

Transform parent = gameObject.transform.parent;

if (parent != null && parent.lossyScale != Vector3.one)

{

Debug.LogWarning("'" + gameObject.name + "' has one or more parent transforms with scale. " +

"This causes incorrect collision shapes.", gameObject);

}

outFile.Write (" />\n");

}

private string GetColliderShapeName (Collider collider)

{

string typeName = collider.GetType ().Name;

typeName = typeName.Replace("Controller", "");

return typeName.Replace ("Collider", "");

}

private void WriteCharacterControllerAttributes(CharacterController characterController, StreamWriter outFile, string indent)

{

Vector3 center = characterController.center;

float height = characterController.height;

height = height - 2 * characterController.radius;

height = height < 0 ? 0 : height;

outFile.Write("Height=\"" + height + "\" Radius=\"" + characterController.radius + "\" Slope=\"" + characterController.slopeLimit +

"\" Step=\"" + characterController.stepOffset + "\" Center=\"" + (-center.x) + ", " + center.y + ", " + center.z + "\"");

}

private void WriteBoxColliderAttributes (BoxCollider boxCollider, StreamWriter outFile, string indent)

{

Vector3 center = boxCollider.center;

Vector3 size = boxCollider.size;

outFile.Write ("Center=\"" + (-center.x) + ", " + center.y + ", " + center.z +

"\" Size=\"" + size.x + ", " + size.y + ", " + size.z + "\"");

}

private void WriteSphereColliderAttributes(SphereCollider sphereCollider, StreamWriter outFile, string indent)

{

Vector3 center = sphereCollider.center;

float radius = sphereCollider.radius;

outFile.Write("Center=\"" + (-center.x) + ", " + center.y + ", " + center.z + "\" Radius=\"" + radius + "\"");

}

private void WriteCapsuleColliderAttributes(CapsuleCollider capsuleCollider, StreamWriter outFile, string indent)

{

Vector3 center = capsuleCollider.center;

float radius = capsuleCollider.radius;

float height = capsuleCollider.height;

height = height - 2 * radius;

height = height < 0 ? 0 : height;

char direction = capsuleCollider.direction < 1 ? 'X' : 'Y';

direction = capsuleCollider.direction > 1 ? 'Z' : direction;

outFile.Write("Center=\"" + (-center.x) + ", " + center.y + ", " + center.z + "\" Radius=\"" + radius + "\"" +

" Height=\"" + height + "\"" + " Direction=\"" + direction + "\"");

}

private void WriteMeshColliderAttributes(MeshCollider meshCollider, StreamWriter outFile, string indent)

{

string convex = meshCollider.convex ? " Convex=\"1\"" : "";

outFile.Write("Mesh=\"" + meshCollider.sharedMesh.name + "\"" + convex);

}

private void WriteRigidbody(GameObject gameObject, StreamWriter outFile, string indent)

{

Rigidbody rigidbody = gameObject.GetComponent();

if (rigidbody == null)

{

return;

}

string kinematic = rigidbody.isKinematic ? " Kinematic=\"1\"" : "";

// TODO: find a way to map PhysX values to Bullet values

string damping = rigidbody.drag != 0 ? " Drag=\"" + rigidbody.drag + "\"" : "";

string angularDamping = " AngularDrag=\"" + rigidbody.angularDrag + "\"";

outFile.Write(indent + " " + "

kinematic + damping + angularDamping + " />\n");

}

private void WriteCamera(Camera camera, StreamWriter outFile, string indent)

{

if (camera == null) {

return;

}

float fieldOfView = camera.fieldOfView;

if (camera.orthographic) {

fieldOfView = 0;

}

string viewport = string.Empty;

float left = camera.rect.xMin;

float bottom = camera.rect.yMin;

float right = camera.rect.xMax;

float top = camera.rect.yMax;

right = right > 1 ? 1 : right;

top = top > 1 ? 1 : top;

if (left != 0 || right != 1 || bottom != 0 || top != 1)

{

viewport = " Left=\"" + left + "\" Right=\"" + right + "\" Top=\"" + top + "\" Bottom=\"" + bottom + "\"";

}

string mask = camera.cullingMask == ~0 ? "" : " Mask=\"" + camera.cullingMask.ToString("X") + "\"";

string depth = camera.depth == 0 ? "" : " Depth=\"" + camera.depth + "\"";

string clear = string.Empty;

Color c = camera.backgroundColor;

string clearColor = " ClearColor=\"" + c.r + ", " + c.g + ", " + c.b + ", " + c.a + "\"";

switch (camera.clearFlags)

{

case CameraClearFlags.Depth:

clear = " Clear=\"Z\"";

clearColor = string.Empty;

break;

case CameraClearFlags.Nothing:

clear = " Clear=\"No\"";

clearColor = string.Empty;

break;

default:

break;

}

outFile.WriteLine (indent + " " + "

camera.nearClipPlane + "\" Far=\"" + camera.farClipPlane + "\"" + viewport + clear + clearColor + depth + mask + " />");

}

private string GetMaterialName(Material material, MeshRenderer meshRenderer)

{

string lightMapIndex = string.Empty;

if (meshRenderer.lightmapIndex != -1)

{

lightMapIndex += "_" + meshRenderer.lightmapIndex;

}

List lights = GetLightsForRenderer(meshRenderer);

if (lights.Count > 0)

{

lightMapIndex += "_lit";

}

return material.name + lightMapIndex;

}

private string GetMaterialAssetName(Material material, MeshRenderer meshRenderer)

{

return GetMaterialName(material, meshRenderer) + "_" + material.GetInstanceID().ToString("X8");

}

private void WriteMaterial(MeshRenderer meshRenderer, Material material, StreamWriter outFile, string indent)

{

if (material == null)

{

return;

}

string materialName = GetMaterialName(material, meshRenderer);

string materialAssetName = GetMaterialAssetName(material, meshRenderer);

bool alreadyProcessed = true;

if (!mMaterialAssetsProcessed.Contains(materialAssetName))

{

mMaterialAssetsProcessed.Add(materialAssetName);

mMaterialAssetNameToMaterialName.Add(materialAssetName, GetUniqueName(materialName, mMaterialNameToCount));

alreadyProcessed = false;

}

materialName = mMaterialAssetNameToMaterialName[materialAssetName];

if (alreadyProcessed)

{

outFile.WriteLine(indent + "");

return;

}

else

{

outFile.WriteLine(indent + "");

}

bool usesLightmap = meshRenderer.lightmapIndex != -1 && meshRenderer.lightmapIndex != 254;

bool isRealtimeLit = GetLightsForRenderer(meshRenderer).Count > 0;

if (usesLightmap)

{

Texture2D lightmap = LightmapSettings.lightmaps[meshRenderer.lightmapIndex].lightmapFar;

WriteTexture(lightmap, outFile, indent, true, isRealtimeLit);

}

var textures = GetTextures(material);

for (int i = 0; i < textures.Count; ++i)

{

if (i == 0)

{

WriteTexture(textures[i], outFile, indent, false, isRealtimeLit);

}

else

{

if (!IsNormalmap(textures[i]))

{

WriteTexture(textures[i], outFile, indent);

}

else if (mWriteNormalmaps)

{

WriteTexture(textures[i], outFile, indent);

}

}

}

WriteMaterialState(material, outFile, indent);

outFile.WriteLine(indent + "");

}

private List GetTextures(Material material)

{

List textures = new List();

if (material == null)

{

return textures;

}

int propertyCount = ShaderUtil.GetPropertyCount(material.shader);

for (int i = 0; i < propertyCount; i++)

{

ShaderUtil.ShaderPropertyType propertyType = ShaderUtil.GetPropertyType(material.shader, i);

if (ShaderUtil.ShaderPropertyType.TexEnv == propertyType)

{

var texture = material.GetTexture(ShaderUtil.GetPropertyName(material.shader, i)) as Texture2D;

if (texture != null)

{

textures.Add(texture);

}

}

}

return textures;

}

private static bool IsNormalmap(Texture texture)

{

if (texture == null)

{

return false;

}

string assetPath = AssetDatabase.GetAssetPath(texture);

if (assetPath == null)

{

return false;

}

TextureImporter textureImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;

if (textureImporter == null)

{

Debug.LogWarning("Cannot get TextureImporter for '" + texture.name + "' at " + assetPath);

return false;

}

return textureImporter.normalmap;

}

private void WriteMaterialState(Material materialState, StreamWriter outFile, string indent)

{

if (mExportStateMaterial == false)

{

return;

}

if (materialState.HasProperty("_Color"))

{

Color color = materialState.GetColor("_Color");

outFile.WriteLine (indent + " " + "

color.r + ", " + color.g + ", " + color.b + ", " + color.a + "\" />");

}

else if (materialState.HasProperty("_TintColor"))

{

Color color = materialState.GetColor("_TintColor");

outFile.WriteLine(indent + " " + "

color.r + ", " + color.g + ", " + color.b + ", " + color.a + "\" />");

}

else if (materialState.HasProperty("_Tint"))

{

Color color = materialState.GetColor("_Tint");

outFile.WriteLine(indent + " " + "

color.r + ", " + color.g + ", " + color.b + ", " + color.a + "\" />");

}

}

private void WriteTexture(Texture2D texture, StreamWriter outFile, string indent, bool isLightmap = false, bool isRealtimeLit = false)

{

if (texture == null)

{

return;

}

bool alreadyProcessed = true;

if (!mTextureToName.ContainsKey(texture))

{

mTextureToName.Add(texture, GetUniqueName(texture.name, mTextureNameToCount));

alreadyProcessed = false;

}

string texName = mTextureToName[texture] + ".png";

int mipmapCount = (mDontGenerateMipmapsForLightmaps && isLightmap) ? 1 : texture.mipmapCount;

string textureXmlNode = indent + "

"\" FilterMode=\"" + texture.filterMode + "\" AnisoLevel=\"" + texture.anisoLevel +

"\" WrapMode=\"" + texture.wrapMode + "\" Mipmaps=\"" + mipmapCount + "\" ";

if (isRealtimeLit)

{

if (isLightmap)

{

textureXmlNode += "BlendMode=\"Add\" ";

}

else

{

textureXmlNode += "BlendMode=\"Modulate\" ";

}

}

if (mDiscardTexturesOnBind)

{

textureXmlNode += "Usage=\"STATIC_DISCARD_ON_BIND\" ";

}

textureXmlNode += "/>";

outFile.WriteLine (textureXmlNode);

if (!alreadyProcessed)

{

SaveImage(texture, isLightmap);

}

}

private void SaveImage(Texture2D texture, bool isLightmap)

{

if (mExportXmlOnly)

{

return;

}

string assetPath = AssetDatabase.GetAssetPath(texture);

TextureImporter textureImporter = AssetImporter.GetAtPath (assetPath) as TextureImporter;

if (textureImporter == null)

{

Debug.Log("Error getting TextureImporter for '" + texture.name + "'");

return;

}

bool wasReadable = textureImporter.isReadable;

TextureImporterFormat wasFormat = textureImporter.textureFormat;

bool needsReimport = false;

if (wasReadable == false)

{

needsReimport = true;

textureImporter.isReadable = true;

}

if (texture.format == TextureFormat.DXT1)

{

needsReimport = true;

textureImporter.textureFormat = TextureImporterFormat.RGB24;

}

if (texture.format == TextureFormat.DXT5 || texture.format == TextureFormat.RGBA32)

{

needsReimport = true;

textureImporter.textureFormat = TextureImporterFormat.ARGB32;

}

if (needsReimport)

{

AssetDatabase.ImportAsset (assetPath);

}

string texName = mTextureToName[texture] + ".png";

int mipmapCount = (mDontGenerateMipmapsForLightmaps && isLightmap) ? 1 : texture.mipmapCount;

int bpp = textureImporter.DoesSourceTextureHaveAlpha() ? 4 : 3;

bpp = isLightmap ? 3 : bpp;

mStatistics.TexturesTotalSizeInRam += GetSizeFromLevelOfMipmaps (mipmapCount, texture) * bpp;

mStatistics.TexturesCount++;

if (!isLightmap)

{

Byte[] bytes = texture.EncodeToPNG();

File.WriteAllBytes (mPath + "/" + texName, bytes);

mStatistics.TexturesTotalSizeOnDisk += bytes.Length;

}

else

{

if (texture.format == TextureFormat.ARGB32)

{

Color32[] texSrc = texture.GetPixels32 ();

Texture2D texRGB = new Texture2D (texture.width, texture.height, TextureFormat.RGB24, false);

Color32[] texDst = texRGB.GetPixels32 ();

for (int k = 0; k < texSrc.Length; k++) {

float[] c = new float[4];

c [0] = texSrc [k].a / 255.0f;

c [1] = (texSrc [k].r / 255.0f) * 8.0f * c [0];

c [2] = (texSrc [k].g / 255.0f) * 8.0f * c [0];

c [3] = (texSrc [k].b / 255.0f) * 8.0f * c [0];

c [1] = c [1] > 1.0f ? 1.0f : c [1];

c [2] = c [2] > 1.0f ? 1.0f : c [2];

c [3] = c [3] > 1.0f ? 1.0f : c [3];

texDst [k].a = 255;// (byte)(c[0] * 255.0f);

texDst [k].r = (byte)(c [1] * 255.0f);

texDst [k].g = (byte)(c [2] * 255.0f);

texDst [k].b = (byte)(c [3] * 255.0f);

}

texRGB.SetPixels32 (texDst);

texRGB.Apply();

Byte[] bytes = texRGB.EncodeToPNG();

File.WriteAllBytes (mPath + "/" + texName, bytes);

mStatistics.LightmapsCount++;

mStatistics.LightmapsTotalSizeOnDisk += bytes.Length;

mStatistics.TexturesTotalSizeOnDisk += bytes.Length;

mStatistics.LightmapsTotalSizeInRam += GetSizeFromLevelOfMipmaps (mipmapCount, texture) * bpp;

} else {

Debug.Log ("Lightmap '" + texture.name + "'could not be read as ARGB32.");

}

}

if (needsReimport)

{

textureImporter.isReadable = wasReadable;

textureImporter.textureFormat = wasFormat;

AssetDatabase.ImportAsset (assetPath);

}

}

private string GetMeshAssetName(Mesh mesh, Vector4 lightmapTilingOffset)

{

string lightmapPostfix = "_" + lightmapTilingOffset.x + "_" + lightmapTilingOffset.y + "_" +

lightmapTilingOffset.z + "_" + lightmapTilingOffset.w;

return mesh.name + lightmapPostfix + "_" + mesh.GetInstanceID().ToString("X8");

}

private bool IsLightmapped(Renderer renderer)

{

GameObject go = renderer != null ? renderer.gameObject : null;

return go && (renderer.lightmapIndex < 254 && renderer.lightmapIndex != -1);

}

private int GetLightmapping(Light light)

{

SerializedObject serialObj = new SerializedObject(light);

SerializedProperty lightmapProp = serialObj.FindProperty("m_Lightmapping");

return lightmapProp.intValue;

}

private void WriteMesh(Mesh mesh, MeshRenderer meshRenderer, StreamWriter outFile, string indent,

int subMeshIndex = -1, bool isCollisionMesh = false)

{

if (mesh == null)

{

return;

}

Vector4 lightmapTilingOffset = GetLightmapTilingOffset(meshRenderer);

string meshName = mesh.name;

string meshAssetName = GetMeshAssetName(mesh, lightmapTilingOffset);

bool alreadyProcessed = true;

if (!mMeshAssetsProcessed.Contains(meshAssetName))

{

mMeshAssetsProcessed.Add(meshAssetName);

string uniqueMeshName = GetUniqueName(meshName, mMeshNameToCount);

uniqueMeshName = uniqueMeshName.Replace("root:", "root");

mMeshAssetNameToMeshName.Add(meshAssetName, uniqueMeshName);

alreadyProcessed = false;

}

meshName = mMeshAssetNameToMeshName[meshAssetName];

string subMesh = subMeshIndex == -1 ? "" : " SubMesh=\"" + subMeshIndex + "\"";

if (alreadyProcessed)

{

outFile.WriteLine(indent + "");

return;

}

outFile.WriteLine(indent + "");

if (mesh.subMeshCount > 1)

{

outFile.WriteLine (indent + " ");

int startIndex = 0;

for (int i = 0; i < mesh.subMeshCount; i++)

{

int indexCount = mesh.GetTriangles(i).Length;

outFile.WriteLine (indent + " " + "

"\" IndexCount=\"" + indexCount + "\" />");

startIndex += indexCount;

}

outFile.WriteLine (indent + " ");

}

string le = mWriteDataAsBigEndian ? string.Empty : " LittleEndian=\"1\"";

string vtxName = meshName + ".vtx";

outFile.WriteLine (indent + " ");

if (!alreadyProcessed) {

SaveVector3s (mesh.vertices, vtxName);

}

bool is16Bit = true;

int[] triangles = mesh.triangles;

foreach (int i in triangles)

{

if (i > 65535)

{

is16Bit = false;

break;

}

}

if (!is16Bit)

{

Debug.LogError("Mesh '" + mesh.name + "' uses 32bit indices.");

}

string is16BitString = is16Bit ? " 16bit=\"1\"" : string.Empty;

string idxName = meshName + ".idx";

outFile.WriteLine(indent + " ");

if (!alreadyProcessed) {

SaveIndices(mesh.triangles, idxName, is16Bit);

}

if (mesh.normals.Length > 0 && !isCollisionMesh)

{

string nmName = meshName + ".nm";

outFile.WriteLine (indent + " ");

if (!alreadyProcessed) {

SaveVector3s (mesh.normals, nmName);

}

}

if (mesh.colors.Length > 0 && !isCollisionMesh)

{

string is32BitString = mWriteColorsAs32Bit ? " 32bit=\"1\"" : string.Empty;

string colName = meshName + ".col";

outFile.WriteLine (indent + " ");

if (!alreadyProcessed) {

SaveColors (mesh, colName);

}

}

if (IsLightmapped(meshRenderer))

{

if (mesh.uv2.Length > 0 && !isCollisionMesh)

{

string uv1Name = meshName + ".uv0";

outFile.WriteLine(indent + " ");

if (!alreadyProcessed)

{

SaveVector2s(mesh.uv2, uv1Name, lightmapTilingOffset);

}

}

if (mesh.uv.Length > 0 && !isCollisionMesh)

{

bool hasUv2 = mesh.uv2.Length > 0;

string uv0Name = meshName + (hasUv2 ? ".uv1" : ".uv0");

string uvTag = hasUv2 ? "

outFile.WriteLine(indent + uvTag + uv0Name + "\"" + le + " />");

if (!alreadyProcessed)

{

SaveVector2s(mesh.uv, uv0Name, new Vector4(1, 1, 0, 0));

}

}

}

else

{

if (mesh.uv.Length > 0 && !isCollisionMesh)

{

string uv0Name = meshName + ".uv0";

outFile.WriteLine(indent + " ");

if (!alreadyProcessed)

{

SaveVector2s(mesh.uv, uv0Name, new Vector4(1, 1, 0, 0));

}

}

if (mesh.uv2.Length > 0 && !isCollisionMesh)

{

string uv1Name = meshName + ".uv1";

outFile.WriteLine(indent + " ");

if (!alreadyProcessed)

{

SaveVector2s(mesh.uv2, uv1Name, lightmapTilingOffset);

}

}

}

outFile.WriteLine (indent + "");

}

private void SaveVector3s (Vector3[] vectors, string name)

{

if (mExportXmlOnly) {

return;

}

FileStream fileStream = new FileStream (mPath + "/" + name, FileMode.Create);

BinaryWriter binaryWriter = new BinaryWriter (fileStream);

for (int i = 0; i < vectors.Length; i++)

{

Vector3 vec = vectors[i];

vec.x = -vec.x;

WriteFloat(vec.x, binaryWriter);

WriteFloat(vec.y, binaryWriter);

WriteFloat(vec.z, binaryWriter);

}

binaryWriter.Close ();

fileStream.Close ();

}

private void SaveVector2s (Vector2[] vectors, string name, Vector4 lightmapTilingOffset)

{

if (mExportXmlOnly) {

return;

}

FileStream fileStream = new FileStream (mPath + "/" + name, FileMode.Create);

BinaryWriter binaryWriter = new BinaryWriter (fileStream);

Vector2 scale = new Vector2 (lightmapTilingOffset.x, lightmapTilingOffset.y);

Vector2 offset = new Vector2 (lightmapTilingOffset.z, lightmapTilingOffset.w);

for (int i = 0; i < vectors.Length; i++)

{

Vector2 uv = offset + new Vector2 (scale.x * vectors [i].x, scale.y * vectors [i].y);

uv.y = 1.0f - uv.y; // OpenGL vs DirectX convention

WriteFloat(uv.x, binaryWriter);

WriteFloat(uv.y, binaryWriter);

}

binaryWriter.Close ();

fileStream.Close ();

}

private void SaveColors (Mesh mesh, string name)

{

if (mExportXmlOnly) {

return;

}

FileStream fileStream = new FileStream (mPath + "/" + name, FileMode.Create);

BinaryWriter binaryWriter = new BinaryWriter (fileStream);

if (mWriteColorsAs32Bit)

{

Color32[] colors = mesh.colors32;

for (int i = 0; i < colors.Length; i++)

{

binaryWriter.Write(colors[i].r);

binaryWriter.Write(colors[i].g);

binaryWriter.Write(colors[i].b);

binaryWriter.Write(colors[i].a);

}

}

else

{

Color[] colors = mesh.colors;

for (int i = 0; i < colors.Length; i++)

{

WriteFloat(colors[i].r, binaryWriter);

WriteFloat(colors[i].g, binaryWriter);

WriteFloat(colors[i].b, binaryWriter);

WriteFloat(colors[i].a, binaryWriter);

}

}

binaryWriter.Close ();

fileStream.Close ();

}

private void WriteFloat(float f, BinaryWriter writer)

{

if ((BitConverter.IsLittleEndian && mWriteDataAsBigEndian) ||

(!BitConverter.IsLittleEndian && !mWriteDataAsBigEndian))

{

byte[] x = BitConverter.GetBytes(f);

Array.Reverse(x);

writer.Write(x);

}

else

{

writer.Write(f);

}

}

private void SaveIndices(int[] indices, string name, bool is16Bit)

{

if (mExportXmlOnly) {

return;

}

FileStream fileStream = new FileStream (mPath + "/" + name, FileMode.Create);

BinaryWriter binaryWriter = new BinaryWriter (fileStream);

if (is16Bit)

{

for (int i = 0; i < indices.Length; i++)

{

ushort s = (ushort)indices[i];

if ((BitConverter.IsLittleEndian && mWriteDataAsBigEndian) ||

(!BitConverter.IsLittleEndian && !mWriteDataAsBigEndian))

{

byte[] x = BitConverter.GetBytes(s);

Array.Reverse(x);

binaryWriter.Write(x);

}

else

{

binaryWriter.Write(s);

}

}

}

else

{

for (int i = 0; i < indices.Length; i++)

{

if ((BitConverter.IsLittleEndian && mWriteDataAsBigEndian) ||

(!BitConverter.IsLittleEndian && !mWriteDataAsBigEndian))

{

byte[] x = BitConverter.GetBytes(indices[i]);

Array.Reverse(x);

binaryWriter.Write(x);

}

else

{

binaryWriter.Write(indices[i]);

}

}

}

binaryWriter.Close ();

fileStream.Close ();

}

private static int GetSizeFromLevelOfMipmaps (int mipmapCount, Texture2D texture)

{

if (mipmapCount == 1) {

return texture.width * texture.height;

}

int size = 0;

for (int i = 0; i < mipmapCount; i++) {

int n = 1 << i;

size += (n * n);

}

return size;

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/531972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

poj3422 Kaka's Matrix Travels(最小费用最大流问题)

1 /*2 poj3422 Kakas Matrix Travels 3 不知道 k次 dp做为什么不对&#xff1f;&#xff1f;&#xff1f;4 看了大牛的代码&#xff0c;才知道还可以这样做&#xff01; 5 开始没有理解将a 和 a‘ 之间建立怎样的两条边&#xff0c;导致程序一直陷入死循环&#xff0c;真心花了…

java把对象转成图片格式转换器安卓版,java 万能图片格式转换

话不多说&#xff0c;直接上代码import java.awt.image.BufferedImage;import java.awt.image.Raster;import java.io.File;import java.io.IOException;import javax.imageio.ImageIO;public class IOUtil {public static void pgm2png(String src, String dest) throws IOExc…

hadooppythonsql_python - hadoop,mapreduce demo

Hadoop,mapreduce 介绍59888745qq.com大数据工程师是在Linux系统下搭建Hadoop生态系统(cloudera是最大的输出者类似于Linux的红帽)&#xff0c;把用户的交易或行为信息通过HDFS(分布式文件系统)等存储用户数据文件&#xff0c;然后通过Hbase(类似于NoSQL)等存储数据&#xff0c…

hdu 2896 病毒侵袭 ac自动机

1 /*2 hdu 2896 病毒侵袭 ac自动机 3 从题意得知&#xff0c;模式串中没有重复的串出现&#xff0c;所以结构体中可以将last[]&#xff08;后缀链接&#xff09;数组去掉 4 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 。本题中主要是计算每一个模式串5 在主串中有没…

axure原件 总是丢失_Axure实现提示文本单击显示后自动消失的效果

FORM一 .新增的input输入属性 1.email类型 在表单提交E-mail地址时,无效的输入会生成很多无效数据,对后期的数据检索造成一定的影响.所以在表单提交之前,需要对输入的E-mail地址进行有效 ...Google的Protobuf协议分析protobuf和thrift类似,也是一个序列化的协议实现,简称PB(下文…

linux php不能写文件内容,php 在linux系统下写出文件问题

最近写了一个简单的生成文件&#xff0c;服务器用的linux 但是在将文件写出到路径的时候就会写出一个其他的文件夹其中一些代码如下define("paddy",dirname(__FILE__));$gkrequest_uri();$filepathpaddy.$gk&#xff1b;createfile($filefath,$file)&#xff1b;//$f…

python mysql删除数据_python-mysql删除和更新数据

删除数据import codecsimport MySQLdbdef connect_mysql():db_config {host: 192.168.48.128,port: 3306,user: xiang,passwd: 123456,db: python,charset: utf8}cnx MySQLdb.connect(**db_config)return cnxif __name__ __main__:cnx connect_mysql()sql select * from S…

xlat指令...

1 ;就是一个串str1&#xff0c; lea ebx, str1 然后我们ebx1总是加上的是一个字节&#xff0c; 无论&#xff08;串是word&#xff0c; byte&#xff0c; dword&#xff09;2 .3863 .model flat4 .stack 40965 include io.h6 ExitProcess proto near32 stdcall, deExitCode:dwo…

php 串口通信例程,HAL库串口通信例程

请问下 为什么要 用void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)这个函数呢?不用不行吗&#xff1f;static void MX_USART1_UART_Init(void){huart1.Instance USART1;huart1.Init.BaudRate 9600;huart1.Init.WordLength UART_WORDLENGTH_8B;huart1.Init.Stop…

char 类型与lpcwstr_「lpctstr」char* 与 LPCTSTR 类型的互相转换 - seo实验室

lpctstr1.char* 转换成 LPCTSTRchar ch[1024] "wo shi ni baba";int num MultiByteToWideChar(0,0,ch,-1,NULL,0);wchar_t *wide new wchar_t[num];MultiByteToWideChar(0,0,ch,-1,wide,num);解析&#xff1a;num 获得长字节所需的空间MultiByteToWideChar()表示将…

poj 2195 Going Home

1 /*2 做网络流的题建图真的是太重要了&#xff01;3 本题是将人所在的位置和房子所在的位置建立边的联系&#xff0c;其中man到house这一条边的流量为 1&#xff0c; 费用为两者的距离4 而方向边的流量为 0&#xff0c; 费用为正向边的相反数&#xff08;也就是沿着反…

CardLayout布局练习(小的图片浏览器)

1 /*2 涉及Panel中的图片的加载&#xff0c;还有Frame的关闭的方法&#xff0c; CardLayout&#xff08;int hgap, int vgap&#xff09;就会决定卡片面板的大小3 匿名类的使用。。。4 */5 import java.awt.*;6 import java.awt.event.*;7 import javax.swing.*;8 public class…

python求逆矩阵的方法,Python 如何求矩阵的逆

我就废话不多说了&#xff0c;大家还是直接看代码吧~import numpy as npkernel np.array([1, 1, 1, 2]).reshape((2, 2))print(kernel)print(np.linalg.inv(kernel))注意&#xff0c;Singular matrix奇异矩阵不可求逆补充&#xff1a;pythonnumpy中矩阵的逆和伪逆的区别定义&a…

plsql存过声明游标_plsql编程学习之游标一

oralce plsql编程的游标游标分类1显示游标2隐式游标隐式游标&#xff0c;oracle自动管理&#xff0c;不用声明&#xff0c;打开和关闭&#xff0c;ORACLE自动处理&#xff0c;使用隐式游标%FOUND时&#xff0c;需要加上 SQL%FOUND显示游标&#xff0c;需要自己声明&#xff0c;…

用命令行编译java并生成可执行的jar包

用命令行编译java并生成可执行的jar包 1.编写源代码。 编写源文件&#xff1a;CardLayoutDemo.java并保存&#xff0c;例如&#xff1a;I:\myApp\CardLayoutDemo.java。程序结构如下&#xff1a;package test;import java.awt.*; import javax.swing.*; //更多包的导入...clas…

python计时器单位,python(计时器)

计时器要求&#xff1a;定制一个计时器的类start 和 stop方法代表启动计时和停止计时假设计时器对象 t1&#xff0c;print(t1)和直接调用t1 均显示结果当计时器未启动或已停止计时&#xff0c;调用stop方法能给予温馨提示两个计时器对象可以相加&#xff1a; t1 t2只能使用提供…

查询分析300万笔记录_给你100万条数据的一张表,你将如何查询优化?

1.两种查询引擎查询速度(myIsam 引擎)InnoDB 中不保存表的具体行数&#xff0c;也就是说&#xff0c;执行select count(*) from table时&#xff0c;InnoDB要扫描一遍整个表来计算有多少行。MyISAM只要简单的读出保存好的行数即可。注意的是&#xff0c;当count(*)语句包含 whe…

poj 3321 Apple Trie

/*poj 3321 Apple Trie 这道题的关键是如何将一个树建成一个一维数组利用树状数组来解题&#xff01;可以利用dfs&#xff08;&#xff09;来搞定&#xff0c;我们在对一个节点深搜后&#xff0c;所经过的节点的数目就是该节点的子树的数目所以我们利用start[i]数组来记录 i 节…

php美团项目分享,美团项目(纯代码)(示例代码)

一.框架搭建1.icon规格要求可从文档中查找,搜索app icon.2.因为很多界面重复利用,所以不用storyboarda.删除stroyboard,在设置中Info -> Main storyboard file base name 项直接去除b.创建ZXHomeViewController(UICollectionViewController)和ZXNavigationController(UINavi…

ioc spring 上机案例_Spring的IoC入门案例

1、创建工程&#xff0c;导入坐标1.1 创建工程1.2 导入坐标xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">4.0.0org.examplespring_01_io…