1 module core.prefabs; 2 import core.gameobject; 3 import components; 4 import utility.filepath, utility.config; 5 6 import yaml; 7 import gl3n.linalg; 8 import std.variant; 9 10 final abstract class Prefabs 11 { 12 public static: 13 alias prefabs this; 14 15 Prefab[string] prefabs; 16 17 void initialize() 18 { 19 foreach( key; prefabs.keys ) 20 prefabs.remove( key ); 21 22 void addObject( Node object ) 23 { 24 auto name = object[ "Name" ].as!string; 25 26 prefabs[ name ] = new Prefab( object ); 27 } 28 29 foreach( file; FilePath.scanDirectory( FilePath.Resources.Prefabs, "*.yml" ) ) 30 { 31 auto object = Config.loadYaml( file.fullPath ); 32 33 if( object.isSequence() ) 34 foreach( Node innerObj; object ) 35 addObject( innerObj ); 36 else 37 addObject( object ); 38 } 39 } 40 } 41 42 final class Prefab 43 { 44 public: 45 this( Node yml ) 46 { 47 transform = new Transform; 48 Variant prop; 49 Node innerNode; 50 51 // Try to get from script 52 if( Config.tryGet!string( "Script.ClassName", prop, yml ) ) 53 scriptClass = ClassInfo.find( prop.get!string ); 54 else 55 scriptClass = null; 56 57 if( Config.tryGet!string( "Camera", prop, yml ) ) 58 { 59 //TODO: Setup camera 60 } 61 62 if( Config.tryGet!string( "Material", prop, yml ) ) 63 componentReferences ~= Assets.get!Material( prop.get!string ); 64 65 if( Config.tryGet!string( "AwesomiumView", prop, yml ) ) 66 { 67 //TODO: Initialize Awesomium view 68 } 69 70 if( Config.tryGet!string( "Mesh", prop, yml ) ) 71 componentReferences ~= Assets.get!Mesh( prop.get!string ); 72 73 if( Config.tryGet( "Transform", innerNode, yml ) ) 74 { 75 vec3 transVec; 76 if( Config.tryGet( "Scale", transVec, innerNode ) ) 77 transform.scale = transVec; 78 if( Config.tryGet( "Position", transVec, innerNode ) ) 79 transform.position = transVec; 80 if( Config.tryGet( "Rotation", transVec, innerNode ) ) 81 transform.rotation = quat.euler_rotation( transVec.y, transVec.z, transVec.x ); 82 } 83 84 if( Config.tryGet!Light( "Light", prop, innerNode ) ) 85 { 86 componentReferences ~= prop.get!Light; 87 } 88 } 89 90 this() 91 { 92 transform = new Transform; 93 scriptClass = null; 94 } 95 96 final GameObject createInstance( const ClassInfo overrideScript = null ) 97 { 98 GameObject result; 99 100 auto script = overrideScript is null ? scriptClass : overrideScript; 101 102 if( script ) 103 result = cast(GameObject)script.create(); 104 else 105 result = new GameObject; 106 107 result.transform.scale.vector[ 0..3 ] = transform.scale.vector[ 0..3 ]; 108 result.transform.position.vector[ 0..3 ] = transform.position.vector[ 0..3 ]; 109 result.transform.rotation.x = transform.rotation.x; 110 result.transform.rotation.y = transform.rotation.y; 111 result.transform.rotation.z = transform.rotation.z; 112 //result.transform.rotation.w = transform.rotation.w; 113 114 foreach( cpn; componentReferences ) 115 result.addComponent( cpn ); 116 117 foreach( cpncls; componentCreations ) 118 { 119 auto inst = cast(Component)cpncls.create(); 120 result.addComponent( inst ); 121 inst.owner = result; 122 } 123 124 result.transform.updateMatrix(); 125 126 return result; 127 } 128 129 private: 130 const ClassInfo scriptClass; 131 Transform transform; 132 Component[] componentReferences; 133 ClassInfo[] componentCreations; 134 }