|
@@ -1,331 +0,0 @@
|
|
|
-package hxd.fmt.hsd;
|
|
|
-
|
|
|
-class Serializer extends hxbit.Serializer {
|
|
|
-
|
|
|
- var version = 0;
|
|
|
-
|
|
|
- public var resPath : String = h3d.impl.MacroHelper.getResourcesPath();
|
|
|
- public var modelCache = new h3d.prim.ModelCache();
|
|
|
- var shaderVarIndex : Int;
|
|
|
- var shaderUID = 0;
|
|
|
- var shaderIndexes = new Map<hxsl.Shader,Int>();
|
|
|
- var cachedShaders = new Array<hxsl.Shader>();
|
|
|
- var cachedTextures = new Map<Int,h3d.mat.Texture>();
|
|
|
- var texOutputFormat : hxd.PixelFormat = RGBA;
|
|
|
-
|
|
|
- function addTexture( t : h3d.mat.Texture ) {
|
|
|
- if( t == null ) {
|
|
|
- addInt(0);
|
|
|
- return true;
|
|
|
- }
|
|
|
- addInt(t.id);
|
|
|
- if( cachedTextures.exists(t.id) )
|
|
|
- return true;
|
|
|
- addInt(t.filter.getIndex());
|
|
|
- addInt(t.mipMap.getIndex());
|
|
|
- addInt(t.wrap.getIndex());
|
|
|
- cachedTextures.set(t.id, t);
|
|
|
- if( t.name != null && hxd.res.Loader.currentInstance.exists(t.name) ) {
|
|
|
- addInt(1);
|
|
|
- addString(t.name);
|
|
|
- return true;
|
|
|
- }
|
|
|
- if( t.flags.has(Serialize) ) {
|
|
|
- addInt(2);
|
|
|
- addInt(t.width);
|
|
|
- addInt(t.height);
|
|
|
- addInt(t.flags.toInt());
|
|
|
- addInt(t.format.getIndex());
|
|
|
- var fmt = texOutputFormat;
|
|
|
- addInt(fmt.getIndex());
|
|
|
- for( face in 0...(t.flags.has(Cube) ? 6 : 1) ) {
|
|
|
- var pix = t.capturePixels(face);
|
|
|
- pix.convert(fmt);
|
|
|
- addBytesSub(pix.bytes, 0, pix.dataSize);
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
- var tch = hxd.impl.Api.downcast(t, h3d.mat.TextureChannels);
|
|
|
- if( tch != null ) {
|
|
|
- addInt(3);
|
|
|
- var channels = @:privateAccess tch.channels;
|
|
|
- addInt(t.width);
|
|
|
- addInt(t.height);
|
|
|
- addInt(t.flags.toInt());
|
|
|
- addInt(t.format.getIndex());
|
|
|
- for( i in 0...4 ) {
|
|
|
- var c = channels[i];
|
|
|
- if( c == null ) {
|
|
|
- addString(null);
|
|
|
- continue;
|
|
|
- }
|
|
|
- if( c.r == null )
|
|
|
- return false;
|
|
|
- addString(c.r.entry.path);
|
|
|
- addInt(c.c.toInt());
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- function getTexture() {
|
|
|
- var tid = getInt();
|
|
|
- if( tid == 0 )
|
|
|
- return null;
|
|
|
- var t = cachedTextures.get(tid);
|
|
|
- if( t != null )
|
|
|
- return t;
|
|
|
- var filter = h3d.mat.Data.Filter.createByIndex(getInt());
|
|
|
- var mipmap = h3d.mat.Data.MipMap.createByIndex(getInt());
|
|
|
- var wrap = h3d.mat.Data.Wrap.createByIndex(getInt());
|
|
|
- var kind = getInt();
|
|
|
- switch( kind ) {
|
|
|
- case 1:
|
|
|
- t = resolveTexture(getString());
|
|
|
- case 2,3:
|
|
|
- var width = getInt(), height = getInt();
|
|
|
- var flags : haxe.EnumFlags<h3d.mat.Data.TextureFlags> = haxe.EnumFlags.ofInt(getInt());
|
|
|
- var format = h3d.mat.Data.TextureFormat.createByIndex(getInt());
|
|
|
- var flags = [for( f in h3d.mat.Data.TextureFlags.createAll() ) if( flags.has(f) ) f];
|
|
|
- if( kind == 2 ) {
|
|
|
- var pixFormat = h3d.mat.Data.TextureFormat.createByIndex(getInt());
|
|
|
- t = new h3d.mat.Texture(width, height, flags, format);
|
|
|
- for( face in 0...(t.flags.has(Cube)?6:1) )
|
|
|
- t.uploadPixels(new hxd.Pixels(width, height, getBytes(), pixFormat), 0, face);
|
|
|
- } else {
|
|
|
- var ct = new h3d.mat.TextureChannels(width, height, flags, format);
|
|
|
- ct.allowAsync = false;
|
|
|
- for( i in 0...4 ) {
|
|
|
- var resPath = getString();
|
|
|
- if( resPath == null ) continue;
|
|
|
- var c = hxd.Pixels.Channel.fromInt(getInt());
|
|
|
- ct.setResource(hxd.Pixels.Channel.fromInt(i), hxd.res.Loader.currentInstance.load(resPath).toImage(), c);
|
|
|
- }
|
|
|
- t = ct;
|
|
|
- }
|
|
|
- default:
|
|
|
- throw "assert";
|
|
|
- }
|
|
|
- t.filter = filter;
|
|
|
- t.mipMap = mipmap;
|
|
|
- t.wrap = wrap;
|
|
|
- cachedTextures.set(tid, t);
|
|
|
- return t;
|
|
|
- }
|
|
|
-
|
|
|
- function resolveTexture( path : String ) {
|
|
|
- return hxd.res.Loader.currentInstance.load(path).toTexture();
|
|
|
- }
|
|
|
-
|
|
|
- public function loadHMD( path : String ) {
|
|
|
- return modelCache.loadLibrary(hxd.res.Loader.currentInstance.load(path).toModel());
|
|
|
- }
|
|
|
-
|
|
|
- public function addShader( s : hxsl.Shader ) {
|
|
|
- if( s == null ) {
|
|
|
- addInt(0);
|
|
|
- return;
|
|
|
- }
|
|
|
- var id = shaderIndexes.get(s);
|
|
|
- if( id != null ) {
|
|
|
- addInt(id);
|
|
|
- return;
|
|
|
- }
|
|
|
- id = ++shaderUID;
|
|
|
- shaderIndexes.set(s, id);
|
|
|
- addInt(id);
|
|
|
- addString(Type.getClassName(Type.getClass(s)));
|
|
|
- shaderVarIndex = 0;
|
|
|
- for( v in @:privateAccess s.shader.data.vars )
|
|
|
- addShaderVar(v, s);
|
|
|
- }
|
|
|
-
|
|
|
- function loadShader( name : String ) : hxsl.Shader {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- public function getShader() {
|
|
|
- var id = getInt();
|
|
|
- if( id == 0 )
|
|
|
- return null;
|
|
|
- var s = cachedShaders[id];
|
|
|
- if( s != null )
|
|
|
- return s;
|
|
|
- var sname = getString();
|
|
|
- var cl : Class<hxsl.Shader> = cast Type.resolveClass(sname);
|
|
|
- if( cl == null ) {
|
|
|
- s = loadShader(sname);
|
|
|
- if( s == null )
|
|
|
- throw "Missing shader " + sname;
|
|
|
- } else
|
|
|
- s = Type.createEmptyInstance(cl);
|
|
|
- @:privateAccess s.initialize();
|
|
|
- var sdyn = hxd.impl.Api.downcast(s, hxsl.DynamicShader);
|
|
|
- for( v in @:privateAccess s.shader.data.vars ) {
|
|
|
- if( !canSerializeVar(v) ) continue;
|
|
|
- var val : Dynamic = getShaderVar(v, s);
|
|
|
- if( sdyn != null )
|
|
|
- sdyn.setParamValue(v, val);
|
|
|
- else
|
|
|
- Reflect.setField(s, v.name+"__", val);
|
|
|
- }
|
|
|
- cachedShaders[id] = s;
|
|
|
- return s;
|
|
|
- }
|
|
|
-
|
|
|
- function canSerializeVar( v : hxsl.Ast.TVar ) {
|
|
|
- return v.kind == Param && (v.qualifiers == null || v.qualifiers.indexOf(Ignore) < 0);
|
|
|
- }
|
|
|
-
|
|
|
- function addShaderVar( v : hxsl.Ast.TVar, s : hxsl.Shader ) {
|
|
|
- if( v.kind != Param )
|
|
|
- return;
|
|
|
- switch( v.type ) {
|
|
|
- case TStruct(vl):
|
|
|
- for( v in vl )
|
|
|
- addShaderVar(v, s);
|
|
|
- return;
|
|
|
- default:
|
|
|
- }
|
|
|
- if( !canSerializeVar(v) ) {
|
|
|
- shaderVarIndex++;
|
|
|
- return;
|
|
|
- }
|
|
|
- var val : Dynamic = s.getParamValue(shaderVarIndex++);
|
|
|
- switch( v.type ) {
|
|
|
- case TBool:
|
|
|
- addBool(val);
|
|
|
- case TInt:
|
|
|
- addInt(val);
|
|
|
- case TFloat:
|
|
|
- addFloat(val);
|
|
|
- case TVec(n, VFloat):
|
|
|
- var v : h3d.Vector = val;
|
|
|
- addFloat(v.x);
|
|
|
- addFloat(v.y);
|
|
|
- if( n >= 3 ) addFloat(v.z);
|
|
|
- if( n >= 4 ) addFloat(v.w);
|
|
|
- case TSampler2D, TSamplerCube:
|
|
|
- if( !addTexture(val) )
|
|
|
- throw "Cannot serialize unnamed texture " + s+"."+v.name+" = "+val;
|
|
|
- default:
|
|
|
- throw "Cannot serialize macro var " + v.name+":"+hxsl.Ast.Tools.toString(v.type)+" in "+s;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function getShaderVar( v : hxsl.Ast.TVar, s : hxsl.Shader ) : Dynamic {
|
|
|
- switch( v.type ) {
|
|
|
- case TStruct(vl):
|
|
|
- var obj = {};
|
|
|
- for( v in vl ) {
|
|
|
- if( !canSerializeVar(v) ) continue;
|
|
|
- Reflect.setField(obj, v.name, getShaderVar(v, s));
|
|
|
- }
|
|
|
- return obj;
|
|
|
- default:
|
|
|
- }
|
|
|
- switch( v.type ) {
|
|
|
- case TBool:
|
|
|
- return getBool();
|
|
|
- case TFloat:
|
|
|
- return getFloat();
|
|
|
- case TInt:
|
|
|
- return getInt();
|
|
|
- case TVec(n, VFloat):
|
|
|
- var v = new h3d.Vector(getFloat(), getFloat());
|
|
|
- if( n >= 3 ) v.z = getFloat();
|
|
|
- if( n >= 4 ) v.w = getFloat();
|
|
|
- return v;
|
|
|
- case TSampler2D, TSamplerCube:
|
|
|
- return getTexture();
|
|
|
- default:
|
|
|
- throw "Cannot unserialize macro var " + v.name+":"+hxsl.Ast.Tools.toString(v.type);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function initHSDPaths( resPath : String, projectPath : String ) {
|
|
|
- this.resPath = resPath;
|
|
|
- }
|
|
|
-
|
|
|
- public function loadAnimation( resPath : String ) {
|
|
|
- return loadHMD(resPath).loadAnimation();
|
|
|
- }
|
|
|
-
|
|
|
- public function loadHSD( bytes ) {
|
|
|
- setInput(bytes, 0);
|
|
|
- if( getString() != "HSD" )
|
|
|
- throw "Invalid HSD file";
|
|
|
- version = getInt();
|
|
|
- beginLoad(bytes, inPos);
|
|
|
- initHSDPaths(getString(), getString());
|
|
|
- var objs = [];
|
|
|
- for( i in 0...getInt() ) {
|
|
|
- var obj : h3d.scene.Object = cast getAnyRef();
|
|
|
- objs.push(obj);
|
|
|
- }
|
|
|
- for( o in objs )
|
|
|
- for( m in o.getMeshes() )
|
|
|
- h3d.mat.MaterialSetup.current.customMeshInit(m);
|
|
|
-
|
|
|
- var camera = null;
|
|
|
- if( getBool() ) {
|
|
|
- camera = new h3d.Camera();
|
|
|
- camera.pos.set(getFloat(), getFloat(), getFloat());
|
|
|
- camera.target.set(getFloat(), getFloat(), getFloat());
|
|
|
- camera.up.set(getFloat(), getFloat(), getFloat());
|
|
|
- camera.fovY = getFloat();
|
|
|
- camera.zNear = getFloat();
|
|
|
- camera.zFar = getFloat();
|
|
|
- camera.zoom = getFloat();
|
|
|
- camera.update();
|
|
|
- }
|
|
|
-
|
|
|
- endLoad();
|
|
|
- return { content : objs, camera : camera };
|
|
|
- }
|
|
|
-
|
|
|
- public function saveHSD( obj : h3d.scene.Object, includeRoot : Bool, ?camera : h3d.Camera ) {
|
|
|
- begin();
|
|
|
- addString("HSD");
|
|
|
- addInt(version); // version
|
|
|
-
|
|
|
- var pos = out.length;
|
|
|
- usedClasses = [];
|
|
|
- addString(resPath);
|
|
|
- #if sys
|
|
|
- addString(Sys.getCwd());
|
|
|
- #else
|
|
|
- addString(null);
|
|
|
- #end
|
|
|
-
|
|
|
- var objs = includeRoot ? [obj] : [for( o in obj ) if( o.allowSerialize ) o];
|
|
|
- addInt(objs.length);
|
|
|
- #if heaps_enable_serialize
|
|
|
- for( o in objs )
|
|
|
- addAnyRef(o);
|
|
|
- #else
|
|
|
- throw "HSD support requires -D heaps_enable_serialize";
|
|
|
- #end
|
|
|
-
|
|
|
- addBool(camera != null);
|
|
|
- if( camera != null ) {
|
|
|
- addFloat(camera.pos.x);
|
|
|
- addFloat(camera.pos.y);
|
|
|
- addFloat(camera.pos.z);
|
|
|
- addFloat(camera.target.x);
|
|
|
- addFloat(camera.target.y);
|
|
|
- addFloat(camera.target.z);
|
|
|
- addFloat(camera.up.x);
|
|
|
- addFloat(camera.up.y);
|
|
|
- addFloat(camera.up.z);
|
|
|
- addFloat(camera.fovY);
|
|
|
- addFloat(camera.zNear);
|
|
|
- addFloat(camera.zFar);
|
|
|
- addFloat(camera.zoom);
|
|
|
- }
|
|
|
-
|
|
|
- return endSave(pos);
|
|
|
- }
|
|
|
-
|
|
|
-}
|