Skip to content

Commit

Permalink
add: obj file to scene feature
Browse files Browse the repository at this point in the history
  • Loading branch information
hikipuro committed Dec 9, 2018
1 parent 1c1c4b9 commit 3e166ee
Show file tree
Hide file tree
Showing 7 changed files with 492 additions and 226 deletions.
1 change: 1 addition & 0 deletions src/Main.ts
Expand Up @@ -51,6 +51,7 @@ export class Main {
editor.setApp(app);
app.status.isEditor = true;
app.isEditing = true;
app.enableUint32Index();
app.width = app.canvas.parentElement.clientWidth;
app.height = app.canvas.parentElement.clientHeight;

Expand Down
1 change: 1 addition & 0 deletions src/tea/Tea.ts
Expand Up @@ -102,6 +102,7 @@ export * from "./objects/Skybox";
export * from "./objects/Texture";

export * from "./parsers/DaeReader";
export * from "./parsers/MtlReader";
export * from "./parsers/ObjReader";

export * from "./particles/Particle";
Expand Down
10 changes: 7 additions & 3 deletions src/tea/components/MeshRenderer.ts
Expand Up @@ -25,17 +25,21 @@ export class MeshRenderer extends Renderer {
if (this._meshFilter.mesh == null) {
return null;
}
var position = this.object3d.position;
var rotation = this.object3d.rotation;
var scale = this.object3d.scale;

this._bounds.copy(this._meshFilter.mesh.bounds);
var bounds = this._bounds;
bounds.center.add$(this.object3d.position);
bounds.center.scale$(scale);
bounds.center.add$(position);

var rotation = this.object3d.rotation;
bounds.extents.applyQuaternion(rotation);
var extents = bounds.extents;
extents[0] = Math.abs(extents[0]);
extents[1] = Math.abs(extents[1]);
extents[2] = Math.abs(extents[2]);
bounds.extents.scale$(this.object3d.scale);
bounds.extents.scale$(scale);
return bounds;
}

Expand Down
12 changes: 7 additions & 5 deletions src/tea/editor/views/HierarchyView.ts
Expand Up @@ -8,6 +8,7 @@ import { TreeViewItem } from "../basic/TreeViewItem";
import { HierarchyViewCommand } from "../commands/HierarchyViewCommand";
import { SceneInspector } from "../views/SceneInspector";
import { LocalFile } from "../LocalFile";
import { FileItemTag } from "./ProjectView";

@Component({
template: `
Expand Down Expand Up @@ -356,17 +357,17 @@ export class HierarchyView extends Vue {
return;
}
var currentPath = LocalFile.resolve(".");
var filename = dragSource.tag as string;
var tag = dragSource.tag as FileItemTag;
var filename = tag.path;
if (filename.indexOf(currentPath) !== 0) {
return;
}
filename = LocalFile.relative(currentPath, filename);
if (filename.indexOf("assets") !== 0) {
return;
}
filename = LocalFile.relative("assets", filename);
//filename = LocalFile.relative("assets", filename);
var ext = LocalFile.extname(filename);
ext = ext.toLowerCase();
var app = editor.status.app;
switch (ext) {
case ".js":
Expand All @@ -388,6 +389,7 @@ export class HierarchyView extends Vue {
break;
case ".jpg":
case ".png":
case ".svg":
var selectedObject = this._command.getSelectedObject();
if (selectedObject == null) {
return;
Expand All @@ -396,8 +398,8 @@ export class HierarchyView extends Vue {
if (renderer == null) {
return;
}
if (LocalFile.exists(filename)) {
renderer.material.mainTexture.load(filename, (err, url) => {
if (LocalFile.exists(tag.path)) {
renderer.material.mainTexture.load(tag.path, (err: string, url: string) => {
if (err) {
return;
}
Expand Down
41 changes: 39 additions & 2 deletions src/tea/editor/views/ProjectView.ts
Expand Up @@ -11,7 +11,7 @@ import { LocalDirectory } from "../LocalDirectory";
import { LocalFile } from "../LocalFile";
import { FileType } from "../FileType";

class FileItemTag {
export class FileItemTag {
path: string;
isFolder: boolean;

Expand Down Expand Up @@ -231,7 +231,6 @@ export class ProjectView extends Vue {
this.onSelectFileMenu
);
var path = this.getSelectedFilePath();
console.log(LocalFile.extname(path));
if (path == null) {
contextMenu.disableItem("Open");
contextMenu.disableItem("Delete");
Expand Down Expand Up @@ -516,6 +515,9 @@ export class ProjectView extends Vue {
inspectorView.show();
inspectorView.$nextTick(() => {
var component = inspectorView.getComponent() as FileInspector;
if (component == null) {
return;
}
var stat = LocalFile.stat(path);
component.fileType = FileType.getFileTypeString(ext);
component.type = FileInspector.Type.Text;
Expand All @@ -534,6 +536,9 @@ export class ProjectView extends Vue {
inspectorView.show();
inspectorView.$nextTick(() => {
var component = inspectorView.getComponent() as FileInspector;
if (component == null) {
return;
}
var stat = LocalFile.stat(path);
component.fileType = FileType.getFileTypeString(ext);
component.type = FileInspector.Type.Image;
Expand All @@ -552,6 +557,9 @@ export class ProjectView extends Vue {
inspectorView.show();
inspectorView.$nextTick(() => {
var component = inspectorView.getComponent() as FileInspector;
if (component == null) {
return;
}
var stat = LocalFile.stat(path);
component.fileType = FileType.getFileTypeString(ext);
component.type = FileInspector.Type.Default;
Expand Down Expand Up @@ -1018,6 +1026,35 @@ export class ProjectView extends Vue {
case "Refresh":
this.updateFileList();
break;
case "Convert":
console.log("select convert")
Tea.ObjReader.convertToMesh(path, (mesh: Tea.Mesh) => {
if (mesh == null) {
return;
}
var editor = this.$root as Editor;
var app = editor.status.app;
var scene = editor.status.scene;
var object3d = new Tea.Object3D(app);
object3d.name = LocalFile.basename(path);
var size = mesh.bounds.size;
var scale = 1.0 / Math.max(size[0], size[1], size[2]);
object3d.localScale.set(scale, scale, scale);
var shader = new Tea.Shader(app);
shader.attach(
Tea.ShaderSources.defaultVS,
Tea.ShaderSources.defaultFS
);
var renderer = object3d.addComponent(Tea.MeshRenderer);
//renderer.wireframe = true;
renderer.material = Tea.Material.getDefault(app);
renderer.material.shader = shader;
var meshFilter = object3d.addComponent(Tea.MeshFilter);
meshFilter.mesh = mesh;
scene.addChild(object3d);
//console.log(mesh);
});
break;
}
}
}
193 changes: 193 additions & 0 deletions src/tea/parsers/MtlReader.ts
@@ -0,0 +1,193 @@
import * as Tea from "../Tea";

class Context {
url: string;
callback: (materials: any) => void;
materials: any;
textureCount: number;
textureLoaded: number;

constructor() {
this.textureCount = 0;
this.textureLoaded = 0;
}

get isCompleted(): boolean {
if (this.textureLoaded >= this.textureCount) {
return true;
}
return false;
}

complete(): void {
this.callback(this.materials);
}
}

export class MtlReader {
constructor() {
}

readFile(url: string, callback: (material: any) => void): void {
if (callback == null) {
return;
}
var context = new Context();
context.url = url;
context.callback = callback;

Tea.File.readText(url, (err, data) => {
if (err) {
callback(null);
return;
}
this.read(context, data);
});
}

protected read(context: Context, data: string): void {
var materials: any = {};
var material: any = null;
this.forEachLine(data, (text: string, index: number) => {
var params = text.trim().split(/\s+/);
switch (params[0]) {
case "#":
// comments
break;
case "newmtl":
// new material
material = this.createMaterial();
materials[params[1]] = material;
break;
case "Ka": // ambient
case "Kd": // diffuse
case "Ks": // specular
case "Ke": // ?
case "Tf": // ?
material[params[0]] = this.parseColor(params);
break;
case "Ns": // ?
case "Ni": // ?
case "Tr": // ?
case "d": // dissolve
material[params[0]] = this.parseFloat(params);
break;
case "illum":
// illumination
material.illum = this.parseFloat(params);
break;
case "map_Ka": // texture
case "map_Kd": //
case "map_Ks": //
case "map_Ns": //
case "map_d": //
case "map_bump": //
case "bump": //
case "disp": //
case "decal": //
var path = "";
if (params.length <= 2) {
path = this.getUrl(context.url, params[1]);
} else {
path = this.getUrl(context.url, params[params.length - 1]);
}
//console.log("path", path);
if (material[params[0]] == null) {
context.textureCount++;
material[params[0]] = path;
}
//this.readImage(material, params[0], path);
break;
}
});

context.materials = materials;
if (context.isCompleted) {
//console.log("complete");
context.complete();
return;
}

for (var key in materials) {
var m = materials[key];
for (var k in m) {
if (k.indexOf("map_") < 0) {
continue;
}
var path = m[k];
if (path != null && path !== "") {
this.readImage(context, m, k, path);
}
}
}
}

protected readImage(context: Context, material: any, name: string, path: string): void {
Tea.File.readImage(path, (err, image) => {
if (err == null) {
material[name] = image;
}
context.textureLoaded++;
//console.log("context.textureLoaded", context.textureLoaded, context.textureCount);
if (context.isCompleted) {
//console.log("complete");
context.complete();
}
});
}


protected createMaterial(): any {
return {
Ka: null,
Kd: null,
Ks: null,
Ke: null,
Ns: null,
Ni: null,
Tr: null,
Ts: null,
d: null,
illum: null,
map_Ka: null,
map_Kd: null,
map_Ks: null,
map_Ns: null,
map_d: null,
map_bump: null,
bump: null,
disp: null,
decal: null
};
}

protected forEachLine(data: string, callback: (text: string, index: number) => void): void {
var lines = data.split(/\r\n|\r|\n/);
var length = lines.length;
for (var i = 0; i < length; i++) {
callback(lines[i], i);
}
}

protected getUrl(base: string, filename: string): string {
var url = new URL(base, location.toString());
var path = url.pathname;
path = path.substr(0, path.lastIndexOf("/") + 1);
return path + filename;
}

protected parseFloat(params: Array<string>): number | null {
var value = parseFloat(params[1]);
if (isNaN(value)) {
return null;
}
return value;
}

protected parseColor(params: Array<string>): Tea.Color {
var r = parseFloat(params[1]);
var g = parseFloat(params[2]);
var b = parseFloat(params[3]);
return new Tea.Color(r, g, b, 1);
}
}

0 comments on commit 3e166ee

Please sign in to comment.