Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CharWordReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public float ReadFloat() {
num = num * Mathf.Pow(10f, exp);
}
}
if (isNegative == true) {
if (isNegative) {
num = -num;
}

Expand Down
298 changes: 149 additions & 149 deletions OBJLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,183 +99,183 @@ private void LoadMaterialLibrary(string mtlLibPath)
/// <returns>Returns a GameObject represeting the OBJ file, with each imported object as a child.</returns>
public GameObject Load(Stream input)
{
var reader = new StreamReader(input);
//var reader = new StringReader(inputReader.ReadToEnd());
using (var reader = new StreamReader(input)) {
//var reader = new StringReader(inputReader.ReadToEnd());

Dictionary<string, OBJObjectBuilder> builderDict = new Dictionary<string, OBJObjectBuilder>();
OBJObjectBuilder currentBuilder = null;
string currentMaterial = "default";
Dictionary<string, OBJObjectBuilder> builderDict = new Dictionary<string, OBJObjectBuilder>();
OBJObjectBuilder currentBuilder = null;
string currentMaterial = "default";

//lists for face data
//prevents excess GC
List<int> vertexIndices = new List<int>();
List<int> normalIndices = new List<int>();
List<int> uvIndices = new List<int>();
//lists for face data
//prevents excess GC
List<int> vertexIndices = new List<int>();
List<int> normalIndices = new List<int>();
List<int> uvIndices = new List<int>();

//helper func
Action<string> setCurrentObjectFunc = (string objectName) =>
{
if (!builderDict.TryGetValue(objectName, out currentBuilder))
//helper func
Action<string> setCurrentObjectFunc = (string objectName) =>
{
currentBuilder = new OBJObjectBuilder(objectName, this);
builderDict[objectName] = currentBuilder;
}
};

//create default object
setCurrentObjectFunc.Invoke("default");

//var buffer = new DoubleBuffer(reader, 256 * 1024);
var buffer = new CharWordReader(reader, 4 * 1024);
if (!builderDict.TryGetValue(objectName, out currentBuilder))
{
currentBuilder = new OBJObjectBuilder(objectName, this);
builderDict[objectName] = currentBuilder;
}
};

//do the reading
while (true)
{
buffer.SkipWhitespaces();
//create default object
setCurrentObjectFunc.Invoke("default");

if (buffer.endReached == true) {
break;
}
//var buffer = new DoubleBuffer(reader, 256 * 1024);
var buffer = new CharWordReader(reader, 4 * 1024);

buffer.ReadUntilWhiteSpace();

//comment or blank
if (buffer.Is("#"))
//do the reading
while (true)
{
buffer.SkipUntilNewLine();
continue;
}

if (Materials == null && buffer.Is("mtllib")) {
buffer.SkipWhitespaces();
buffer.ReadUntilNewLine();
string mtlLibPath = buffer.GetString();
LoadMaterialLibrary(mtlLibPath);
continue;
}

if (buffer.Is("v")) {
Vertices.Add(buffer.ReadVector());
continue;
}

//normal
if (buffer.Is("vn")) {
Normals.Add(buffer.ReadVector());
continue;
}

//uv
if (buffer.Is("vt")) {
UVs.Add(buffer.ReadVector());
continue;
}
buffer.SkipWhitespaces();

//new material
if (buffer.Is("usemtl")) {
buffer.SkipWhitespaces();
buffer.ReadUntilNewLine();
string materialName = buffer.GetString();
currentMaterial = materialName;
if (buffer.endReached) {
break;
}

if(SplitMode == SplitMode.Material)
buffer.ReadUntilWhiteSpace();

//comment or blank
if (buffer.Is("#"))
{
setCurrentObjectFunc.Invoke(materialName);
buffer.SkipUntilNewLine();
continue;
}

if (Materials == null && buffer.Is("mtllib")) {
buffer.SkipWhitespaces();
buffer.ReadUntilNewLine();
string mtlLibPath = buffer.GetString();
LoadMaterialLibrary(mtlLibPath);
continue;
}

if (buffer.Is("v")) {
Vertices.Add(buffer.ReadVector());
continue;
}

//normal
if (buffer.Is("vn")) {
Normals.Add(buffer.ReadVector());
continue;
}
continue;
}

//new object
if ((buffer.Is("o") || buffer.Is("g")) && SplitMode == SplitMode.Object) {
buffer.ReadUntilNewLine();
string objectName = buffer.GetString(1);
setCurrentObjectFunc.Invoke(objectName);
continue;
}
//uv
if (buffer.Is("vt")) {
UVs.Add(buffer.ReadVector());
continue;
}

//face data (the fun part)
if (buffer.Is("f"))
{
//loop through indices
while (!buffer.endReached)
{
bool newLinePassed;
buffer.SkipWhitespaces(out newLinePassed);
if (newLinePassed == true) {
break;
}

int vertexIndex = int.MinValue;
int normalIndex = int.MinValue;
int uvIndex = int.MinValue;

vertexIndex = buffer.ReadInt();
if (buffer.currentChar == '/') {
buffer.MoveNext();
if (buffer.currentChar != '/') {
uvIndex = buffer.ReadInt();
}
if (buffer.currentChar == '/') {
buffer.MoveNext();
normalIndex = buffer.ReadInt();
}
}

//"postprocess" indices
if (vertexIndex > int.MinValue)
{
if (vertexIndex < 0)
vertexIndex = Vertices.Count - vertexIndex;
vertexIndex--;
}
if (normalIndex > int.MinValue)
//new material
if (buffer.Is("usemtl")) {
buffer.SkipWhitespaces();
buffer.ReadUntilNewLine();
string materialName = buffer.GetString();
currentMaterial = materialName;

if(SplitMode == SplitMode.Material)
{
if (normalIndex < 0)
normalIndex = Normals.Count - normalIndex;
normalIndex--;
setCurrentObjectFunc.Invoke(materialName);
}
if (uvIndex > int.MinValue)
continue;
}

//new object
if ((buffer.Is("o") || buffer.Is("g")) && SplitMode == SplitMode.Object) {
buffer.ReadUntilNewLine();
string objectName = buffer.GetString(1);
setCurrentObjectFunc.Invoke(objectName);
continue;
}

//face data (the fun part)
if (buffer.Is("f"))
{
//loop through indices
while (!buffer.endReached)
{
if (uvIndex < 0)
uvIndex = UVs.Count - uvIndex;
uvIndex--;
buffer.SkipWhitespaces(out var newLinePassed);
if (newLinePassed) {
break;
}

int vertexIndex = int.MinValue;
int normalIndex = int.MinValue;
int uvIndex = int.MinValue;

vertexIndex = buffer.ReadInt();
if (buffer.currentChar == '/') {
buffer.MoveNext();
if (buffer.currentChar != '/') {
uvIndex = buffer.ReadInt();
}
if (buffer.currentChar == '/') {
buffer.MoveNext();
normalIndex = buffer.ReadInt();
}
}

//"postprocess" indices
if (vertexIndex > int.MinValue)
{
if (vertexIndex < 0)
vertexIndex = Vertices.Count - vertexIndex;
vertexIndex--;
}
if (normalIndex > int.MinValue)
{
if (normalIndex < 0)
normalIndex = Normals.Count - normalIndex;
normalIndex--;
}
if (uvIndex > int.MinValue)
{
if (uvIndex < 0)
uvIndex = UVs.Count - uvIndex;
uvIndex--;
}

//set array values
vertexIndices.Add(vertexIndex);
normalIndices.Add(normalIndex);
uvIndices.Add(uvIndex);
}

//set array values
vertexIndices.Add(vertexIndex);
normalIndices.Add(normalIndex);
uvIndices.Add(uvIndex);
}
//push to builder
currentBuilder.PushFace(currentMaterial, vertexIndices, normalIndices, uvIndices);

//push to builder
currentBuilder.PushFace(currentMaterial, vertexIndices, normalIndices, uvIndices);
//clear lists
vertexIndices.Clear();
normalIndices.Clear();
uvIndices.Clear();

//clear lists
vertexIndices.Clear();
normalIndices.Clear();
uvIndices.Clear();
continue;
}

continue;
buffer.SkipUntilNewLine();
}

buffer.SkipUntilNewLine();
}
//finally, put it all together
GameObject obj = new GameObject(_objInfo != null ? Path.GetFileNameWithoutExtension(_objInfo.Name) : "WavefrontObject");
obj.transform.localScale = new Vector3(-1f, 1f, 1f);

//finally, put it all together
GameObject obj = new GameObject(_objInfo != null ? Path.GetFileNameWithoutExtension(_objInfo.Name) : "WavefrontObject");
obj.transform.localScale = new Vector3(-1f, 1f, 1f);
foreach (var builder in builderDict)
{
//empty object
if (builder.Value.PushedFaceCount == 0)
continue;

foreach (var builder in builderDict)
{
//empty object
if (builder.Value.PushedFaceCount == 0)
continue;
var builtObj = builder.Value.Build();
builtObj.transform.SetParent(obj.transform, false);
}

var builtObj = builder.Value.Build();
builtObj.transform.SetParent(obj.transform, false);
return obj;
}

return obj;
}

/// <summary>
Expand Down
5 changes: 3 additions & 2 deletions OBJLoaderHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Globalization;
using System;
using System.Globalization;
using UnityEngine;

namespace Dummiesman
Expand All @@ -25,7 +26,7 @@ public static void EnableMaterialTransparency(Material mtl)
/// </summary>
public static float FastFloatParse(string input)
{
if (input.Contains("e") || input.Contains("E"))
if (input.Contains("e", StringComparison.InvariantCultureIgnoreCase))
return float.Parse(input, CultureInfo.InvariantCulture);

float result = 0;
Expand Down
3 changes: 1 addition & 2 deletions OBJObjectBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,9 @@ private class ObjLoopHash {
public int uvIndex;

public override bool Equals(object obj) {
if (!(obj is ObjLoopHash))
if (!(obj is ObjLoopHash hash))
return false;

var hash = obj as ObjLoopHash;
return (hash.vertexIndex == vertexIndex) && (hash.uvIndex == uvIndex) && (hash.normalIndex == normalIndex);
}

Expand Down