fbx import, initial version

This commit is contained in:
Vadim Lopatin 2016-04-05 15:17:11 +03:00
parent 35ee4fbb99
commit 22f9b7a8c7
10 changed files with 2427 additions and 25 deletions

View File

@ -284,6 +284,7 @@
<Compile Include="src\dlangui\graphics\scene\camera.d" />
<Compile Include="src\dlangui\graphics\scene\drawableobject.d" />
<Compile Include="src\dlangui\graphics\scene\effect.d" />
<Compile Include="src\dlangui\graphics\scene\fbximport.d" />
<Compile Include="src\dlangui\graphics\scene\light.d" />
<Compile Include="src\dlangui\graphics\scene\material.d" />
<Compile Include="src\dlangui\graphics\scene\mesh.d" />

View File

@ -143,6 +143,7 @@
<Compile Include="src\dlangui\graphics\scene\camera.d" />
<Compile Include="src\dlangui\graphics\scene\drawableobject.d" />
<Compile Include="src\dlangui\graphics\scene\effect.d" />
<Compile Include="src\dlangui\graphics\scene\fbximport.d" />
<Compile Include="src\dlangui\graphics\scene\light.d" />
<Compile Include="src\dlangui\graphics\scene\material.d" />
<Compile Include="src\dlangui\graphics\scene\mesh.d" />

View File

@ -775,6 +775,7 @@
<File path="src\dlangui\graphics\scene\camera.d" />
<File path="src\dlangui\graphics\scene\drawableobject.d" />
<File path="src\dlangui\graphics\scene\effect.d" />
<File path="src\dlangui\graphics\scene\fbximport.d" />
<File path="src\dlangui\graphics\scene\light.d" />
<File path="src\dlangui\graphics\scene\material.d" />
<File path="src\dlangui\graphics\scene\mesh.d" />

View File

@ -8,8 +8,9 @@ import dlangui.graphics.scene.material;
import dlangui.graphics.scene.effect;
import dlangui.graphics.scene.model;
import dlangui.graphics.scene.node;
import dlangui.graphics.scene.objimport;
import dlangui.graphics.scene.light;
import dlangui.graphics.scene.objimport;
import dlangui.graphics.scene.fbximport;
import dlangui.graphics.glsupport;
import dlangui.graphics.gldrawbuf;
import derelict.opengl3.gl3;
@ -121,8 +122,8 @@ class UiWidget : VerticalLayout, CellVisitor {
dirLightNode.translateX(2);
dirLightNode.translateY(3);
dirLightNode.translateZ(3);
//dirLightNode.light = Light.createPoint(vec3(1, 0.5, 0.5), 15); //Light.createDirectional(vec3(1, 0.5, 0.5));
dirLightNode.light = Light.createDirectional(vec3(1, 0.5, 0.8));
dirLightNode.light = Light.createPoint(vec3(1, 0.5, 0.5), 15); //Light.createDirectional(vec3(1, 0.5, 0.5));
//dirLightNode.light = Light.createDirectional(vec3(1, 0.5, 0.8));
dirLightNode.light.enabled = true;
_scene.addChild(dirLightNode);
@ -147,13 +148,21 @@ class UiWidget : VerticalLayout, CellVisitor {
Node3d cubeNode = new Node3d("cubes", cubeDrawable);
_scene.addChild(cubeNode);
{
// test FBX import
FbxModelImport importer;
string src = loadTextResource("suzanne.fbx");
importer.filename = "suzanne.fbx";
importer.parse(src);
}
ObjModelImport importer;
string src = loadTextResource("suzanne.obj");
importer.parse(src);
Log.d("suzanne mesh:", importer.mesh.dumpVertexes(20));
Material suzanneMaterial = new Material(EffectId("colored.vert", "colored.frag", null), null); //"SPECULAR"
//suzanneMaterial.ambientColor = vec3(0.5, 0.5, 0.5);
suzanneMaterial.diffuseColor = vec4(1.0, 0.7, 0.5, 1.0);
suzanneMaterial.diffuseColor = vec4(0.7, 0.7, 0.5, 1.0);
//suzanneMaterial.specular = true;
Model suzanneDrawable = new Model(suzanneMaterial, importer.mesh);
suzanneNode = new Node3d("suzanne", suzanneDrawable);
@ -364,8 +373,8 @@ class UiWidget : VerticalLayout, CellVisitor {
//projectionViewModelMatrix.setIdentity();
//Log.d("matrix uniform: ", projectionViewModelMatrix.m);
//checkgl!glEnable(GL_CULL_FACE);
checkgl!glDisable(GL_CULL_FACE);
checkgl!glEnable(GL_CULL_FACE);
//checkgl!glDisable(GL_CULL_FACE);
checkgl!glEnable(GL_DEPTH_TEST);
checkgl!glCullFace(GL_BACK);

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,7 @@ res/mdpi/tx_fabric.jpg
res/mdpi/crate.png
res/mdpi/blocks.png
res/models/suzanne.obj
res/models/suzanne.fbx
res/shaders/colored.vert
res/shaders/colored.frag
res/shaders/lighting.vert

View File

@ -477,13 +477,19 @@ class Tokenizer {
}
/// tokenize source into array of tokens (excluding EOF)
public Token[] tokenize(string code, string[] _singleLineCommentPrefixes = ["//"]) {
public Token[] tokenize(string code, string[] _singleLineCommentPrefixes = ["//"], bool skipSpace = false, bool skipEols = false, bool skipComments = false) {
Token[] res;
auto tokenizer = new Tokenizer(code, "");
auto tokenizer = new Tokenizer(code, "", _singleLineCommentPrefixes);
for (;;) {
auto token = tokenizer.nextToken();
if (token.type == TokenType.eof)
break;
if (skipSpace && token.type == TokenType.whitespace)
continue;
if (skipEols && token.type == TokenType.eol)
continue;
if (skipComments && token.type == TokenType.comment)
continue;
res ~= token;
}
return res;

View File

@ -1172,3 +1172,21 @@ class DrawableCache {
}
}
// load text resource
string loadTextResource(string resourceId) {
import dlangui.graphics.resources;
import std.string : endsWith;
string filename;
filename = drawableCache.findResource(resourceId);
if (!filename) {
Log.e("Object resource file not found for resourceId ", resourceId);
assert(false);
}
string s = cast(string)loadResourceBytes(filename);
if (!s) {
Log.e("Cannot read text resource ", resourceId, " from file ", filename);
assert(false);
}
return s;
}

View File

@ -0,0 +1,181 @@
module dlangui.graphics.scene.fbximport;
import dlangui.core.logger;
import dlangui.core.math3d;
import dlangui.dml.tokenizer;
import dlangui.graphics.scene.mesh;
struct FbxModelImport {
Token[] tokens;
ParseState[] stateStack;
ParseState state;
string filename;
static class ParseState {
string paramName;
Token[] literalParams;
Token[] additionalLiteralParams;
this(string name) {
paramName = name;
}
void addLiteral(Token token) {
literalParams ~= token;
}
}
protected void pushState(ParseState state) {
stateStack ~= state;
this.state = state;
Log.d("pushState:[", stateStack.length, "] name=", state.paramName);
}
protected ParseState popState() {
if (!state || stateStack.length < 1)
error("stack is empty");
Log.d("popState: [", stateStack.length, "] name=", state.paramName, " params:", state.literalParams, " addParams: ", state.additionalLiteralParams );
stateStack.length = stateStack.length - 1;
state = stateStack.length ? stateStack[$ - 1] : null;
return state;
}
protected bool matchTypes(TokenType t1, TokenType t2) {
return (tokens.length > 1 && tokens[0].type == t1 && tokens[1].type == t2);
}
protected bool skip(int count) {
if (count >= tokens.length) {
tokens = null;
return false;
}
tokens = tokens[count .. $];
return true;
}
protected string parseParamName() {
if (matchParamName()) {
string name = tokens[0].text;
skip(2);
return name;
}
return null;
}
protected bool matchParamName() {
return matchTypes(TokenType.ident, TokenType.colon);
}
protected void error(string msg) {
if (tokens.length)
throw new ParserException(msg, filename, tokens[0].line, tokens[0].pos);
throw new ParserException(msg, filename, tokens[0].line, tokens[0].pos);
}
// current token is {, parse till matching }
protected void parseObject() {
if (!skip(1))
error("unexpected eof");
pushState(new ParseState(null));
for (;;) {
if (string name = parseParamName()) {
parseParam(name);
} else {
break;
}
}
if (!tokens.length)
error("eof while looking for }");
if (tokens[0].type != TokenType.curlyClose)
error("} expected");
skip(1);
popState();
}
protected Token[] parseLiteralList() {
Token[] res;
if (!tokens.length)
error("unexpected eof");
Token t = tokens[0];
while (t.type == TokenType.str || t.type == TokenType.integer || t.type == TokenType.floating || t.type == TokenType.minus || (t.type == TokenType.ident && !matchParamName())) {
// unary minus handling
if (t.type == TokenType.minus) {
if (!skip(1))
error("Unexpected eof");
t = tokens[0];
if (t.type == TokenType.integer)
t.intvalue = -t.intvalue;
else if (t.type == TokenType.floating)
t.floatvalue = -t.floatvalue;
else
error("number expected");
}
res ~= t;
if (!skip(1)) {
break;
}
t = tokens[0];
if (t.type != TokenType.comma)
break;
if (!skip(1))
error("Unexpected eof");
t = tokens[0];
}
return res;
}
protected void parseParam(string name) {
pushState(new ParseState(name));
if (!tokens.length)
error("unexpected eof");
if (matchParamName()) {
// next param
popState();
return;
}
// process non-named parameter list
Token t = tokens[0];
if (t.type == TokenType.str || t.type == TokenType.integer || t.type == TokenType.floating || t.type == TokenType.minus || (t.type == TokenType.ident && !matchParamName())) {
state.literalParams = parseLiteralList();
if (!tokens.length) {
popState();
return;
}
t = tokens[0];
}
if (t.type == TokenType.curlyOpen) {
parseObject();
if (tokens.length) {
t = tokens[0];
if (t.type == TokenType.comma) {
// additional params
if (!skip(1))
error("unexpected eof");
t = tokens[0];
if (t.type == TokenType.str || t.type == TokenType.integer || t.type == TokenType.floating || t.type == TokenType.minus || (t.type == TokenType.ident && !matchParamName())) {
state.additionalLiteralParams = parseLiteralList();
}
}
}
popState();
return;
}
if (matchParamName() || t.type == TokenType.curlyClose) {
// next param
popState();
return;
} else {
error("parameter name expected");
}
}
protected bool parseAll() {
while (tokens.length) {
if (string name = parseParamName()) {
parseParam(name);
} else {
if (tokens.length)
error("Parameter name expected");
}
}
return true;
}
bool parse(string source) {
import dlangui.dml.tokenizer;
try {
tokens = tokenize(source, [";"], true, true, true);
return parseAll();
} catch (ParserException e) {
Log.d("failed to tokenize OBJ source", e);
return false;
}
return true;
}
}

View File

@ -264,20 +264,3 @@ struct ObjModelImport {
}
// load text resource
string loadTextResource(string resourceId) {
import dlangui.graphics.resources;
import std.string : endsWith;
string filename;
filename = drawableCache.findResource(resourceId);
if (!filename) {
Log.e("Object resource file not found for resourceId ", resourceId);
assert(false);
}
string s = cast(string)loadResourceBytes(filename);
if (!s) {
Log.e("Cannot read shader source resource ", resourceId, " from file ", filename);
assert(false);
}
return s;
}