Cogs Scenes are defined using JSon format. Scenes contains explicit hierarchy of entities and resources.
Scenes are sometime also called Asset, but differs from the the Cogs Asset System Assets handled creating field AssetSystem.AssetComponent.asset.
Scene formats are loaded using Bridge functions:
bool loadScene(BridgeContext * context, const char * filename, int(AssetLoadFlags flags));
bool loadAsset(BridgeContext * context, const char * filename, EntityId rootId, int(AssetLoadFlags flags));
bool loadAssetFromString(BridgeContext* context, const char* contents, EntityId rootId, int(AssetLoadFlags flags));
Entities can be saved to Scene format using Bridge function:
bool writeAsset(BridgeContext * context, const char * filename, EntityId rootId, int(AssetWriteFlags flags));
{
"meta": {
"flags": "true"
},
"extensions": [ ],
"imports": [ ],
"variables": [ ]
"templates": { },
"resources": { },
"entities": [ ]
}
Note that the scene file is parsed sequentially and the order of these sections should be as specified above with the exception of 'imports' (See note for imports).
Specification of the file format of each section of the scene file.
Optional section. If this section exists and there is a member "flags" (value ignored) the default scene initialization is disabled. Same effect as setting loading flag: AssetLoadFlags::NoDefault. Intended usage is for scenes also containing camera and light setup in addition.
The extensions array may contain the names of engine extensions required by the scene. This section must be added at the top of the Scene to ensure extensions are loaded and initialized before the scene contents is parsed.
{
"extensions": [
"Cogs.Core.Extensions.Physics",
"Cogs.Core.Extensions.Audio",
]
}
An imports section may contain a single string naming a scene file to load or an array of scene files to load and process.
The imports section may be placed in between other sections, and imports are processed at the time the imports section is encountered. This makes it possible both to define resources in a top level scene to be used by imported scenes, and to define entities in imported scenes that are referenced in the top level scene.
{
"imports": "Other.scene",
// Or
"imports": [
"Other.scene",
"Another.scene"
]
}
A templates section may contain entity templates (also named entity definitions), describing a set of components and field values that make up a new type of entity.
Defined entity types may then be referenced when selecting the type of an entity in the entities section.
{
"templates": {
"MyEntity": {
"components": [
"TransformComponent",
"MyComponent"
],
"defaults": {
"MyComponent": {
"myValue": 1.0
}
}
}
}
}
A variables section may specify values of Cogs runtime variables which this scene will set.
{
"variables": {
"renderer.pipeline": "Pipelines/ForwardTonemap.pipeline",
"renderer.ambientLightColor": "1 1 1",
"renderer.ambientLightIntensity": 0.3,
// Same as above:
"renderer": {
"ambientLightIntensity": 0.3
}
},
}
Value types supported are:
Cogs runtime variables could also be used in other fields in the scene using runtime.getVariable() function.
"entities": [
{
"name": "Script",
"type": "Script",
"ScriptComponent": {
"source": "runtime.loadScene(runtime.getVariable('single_screen') == 'true' ? 'Scenes/SimSalma_1screen.scene' : runtime.getVariable('wide_screen') == 'true' ? 'Scenes/SimSalma_widescreen.scene' : 'Scenes/SimSalma_2screens.scene');",
"flags": "SourceText | JavaScript"
},
}
]
A resources section may contain resources (Model, Texture, Font etc.) that are referenced by entities instanced by the scene, or otherwise used by e.g. post-processing or GUI.
All resources are specified as "key": { // Value }
pairs where the key must be a unique string, and the value a valid resource description.
{
"resources": {
"StandardMaterial": "StandardMaterial.material",
"Name": {
"type": "Mesh" | "MaterialInstance" | "Texture" | "Model" | "GuiDocument" | "NameOfResourceReadedExtension" ("Sound")
"key": "value" ...
},
}
}
Resource entries specifies either a material: Resource value must be a string ending in ".material".
All resource other entries must have the "Name" as key and a property "type" to give type of resource.
{
"resources": {
"MyMaterial": "CustomMaterial.material", // Defines a MaterialInstance
"Sphere": {
"type": "Mesh",
"generator": { // Similar to MeshGeneratorComponent
"shape": "Sphere",
"size": [ 1, 1, 1 ],
"samples": 24
}
},
"MyMesh": {
"type": "Mesh",
"positions": [], // vec3
"instancePositions": [], // vec3
"instanceColors": [], // vec4
"normals": [], // vec3
"bbox": [2], // vec3, vec3
},
"Model": {
"type": "Model",
"source": "Models/Crate/Crate.obj"
},
"ModelMaterial": {
"type": "MaterialInstance",
"material": "StandardMaterial",
"metallic": 1.0,
"roughness": 0.5
},
"Texture": {
"type": "Texture",
"source": "Textures/Checkerboard.png",
+ extra params.
}
},
}
The above format can also be specified when reading field values in the entities section.
type
is given by field type and can be omitted.
For example creating a Mesh and MaterialInstance:
"InstancedMeshRenderComponent": {
"instanceMesh": {
"instancePositions": [
[ -10, 0, 0 ],
[ 0, 0, 0 ],
],
"instanceColors": [
[ 0.2, 0.3, 0.5, 1 ],
[ 1, 1, 1, 1 ],
]
},
"material": {
"type": "DefaultMaterial",
"variants": {
"InstancedPositions": true,
"InstancedColors": true
},
"options": {
"CullMode": "None"
},
"properties": {
"diffuseColor": [ 1.0, 1.0, 1.0, 1.0 ]
}
}
}
An entities array may contain entities that are either instanced or references previously created entities.
{
"entities": [
{
"name": "MyEntityInstance",
"type": "MyEntity", // References the "MyEntity" template type
"MyComponent": { // References the "MyComponent" instance on this entity
"myValue": 2.0 // Modify a field value on the instance
}
},
{
"name": "$MyEntityInstance", // References the existing entity named "MyEntityInstance"
"MyComponent.myValue": 3.0 // Modify a field value using Component.field shorthand notation
}
]
}
{
"name": "",
"type": "",
"children": [],
"properties": {},
"Component": {}
}
// or shorthand for LoD Group
{
"name": "",
"lods": "",
// Other properties
}
// or shorthand for Asset
{
"name": "",
"asset": "",
// Or
"asset": {
"source": "",
"flags": ""
}
}
// or shorthand for Model
{
"name": "",
"model": "",
// Or
"model": {
"source": "",
"flags": ""
}
}
The name field may contain a name for the entity for identification or referencing usage. Name uniqueness is not enforced, however having multiple entities with the same name makes referencing and entity identification from e.g. GUI and scripts much more difficult.1
{
"name": "MyEntityName01" // Names a new entity
}
The name field may use the $Name syntax to reference an existing entity. If this syntax is used, no new entity instance is created, and if an existing instance with the given name does not exist, the entity is considered invalid.
{
"name": "$Camera" // References an existing entity in the scene.
}
The type field may be the name of an entity template to use when instantiating the entity. The entity template determines the set of components added to the entity and the values of the fields contained by the components.
If the entity references an existing entity (using the $MyEntity name syntax), the type field must not be set, as changing the template of an entity after creation is not supported.
{
"type": "Camera" // Defined in Default.entities
}
The children field may contain an array of entities to instantiate and attach to the containing entity as children. The syntax follows that of the global entities section, with the only difference being the parent/child relationship being set.
{
"children": [
{
"name": "Child",
"type": "AnyEntityTemplate",
"children": [
// Child entities can contain its own children
{
"name": "ChildChild",
"type": "...",
"children": []
}
]
}
]
}
The properties field may contain an object with properties for the given entity. The properties section may contain key/value pairs where the key is a valid string and the value is a Bool, Int, Float, String, or an Array of Float values.
{
"properties": {
"myBool": true,
"myInt": 0,
"myFloat": 1.0,
"myString": "string",
"myArray": [ 0, 0, 0 ]
}
}
Most properties have no predetermined behavior but a couple of names are reserved for internal usage:
The asset field may be used to indicate the entity is a Cogs Asset System Asset. The value of the field must either be a string path to a valid asset file, or an object with detailed asset instantiation properties. It is an error to use the asset field alongside the "type", "model", or "lods" fields.
{
"asset": "Path/To/Asset.asset",
// Or
"asset": {
"source": "Path/To/Asset.asset",
"flags": "None"
}
}
Note that the "flags" contains the AssetLoadFlags enum values and may have to be set for correct loading of the asset.
"asset": {
"source": "Assets/TestHierarchicalLod.asset.zst",
"flags": "InstantiateOnDemand | RelativePaths"
}
The asset source can also be just a number to reduce the amount of strings to store in memory. This is interpreted as the path xxxxxxxx.asset
where the x's are the lower-case hexadecimal representation.
The model field may be used to indicate the entity is a Model. The value of the field must either be a string path to a valid model file, or an object with detailed model instantiation properties. It is an error to use the model field alongside the "type", "asset", or "lods" fields.
{
"model": "Path/To/Model.cogsbin",
// Or
"model": {
"source": "Path/To/Model.cogsbin",
"flags": "None"
//TODO: WIP
"offset": 0,
// Or
"parts": [],
// Or
"part": 0,
// Or
"roots": []
"kb": model_size_in_KB
}
}
The model can also be just a number to reduce the amount of strings to store in memory. This is interpreted as the path xxxx/xxxx.cogsbin
where the x's are the lower-case hexadecimal representation,
where the first most significant digits is the folder name.
The lods field may be used to indicate the entity is a LoD Group. The value of the field must be an array of entities or arrays of entities.
Additional properties controlling LoD behavior may be given using the "properties" field on the containing entity.
{
"lods": [
// All entities in a entity array are treated as a single LoD
[
{
"name": "LOD0_0",
"model": "Model_Left_LOD0.cogsbin"
},
{
"name": "LOD0_1",
"model": "Model_Right_LOD0.cogsbin"
}
],
{
"name": "LOD1",
"model": "Model_LOD1.cogsbin"
},
{
"name": "LOD2",
"type": "Sphere",
"MeshGeneratorComponent.samples": 32
},
{
"name": "LOD3:Placeholder",
"type": "Sphere",
"MeshGeneratorComponent.samples": 16
}
],
// Optional:
"properties": {
"errors": [ 10, 20, 50, 100 ],
"bbox": [ 0, 0, 0, 1, 1, 1 ]
}
}
The entity may contain any number of component fields. Component fields must have the name of a component type as key, and "fieldName": "fieldValue"
pairs contained in a value object.
If the name of a component field does not match any existing components on the entity, a new component of the given type name is created and attached to the entity.
If the component name does not match any existing component types an error is generated.
{
"TransformComponent": {
"position": [ 0, 0, 0 ],
"scale": [ 2, 2, 2 ]
},
"MyComponent": {
"myValue": 3.0
}
}
Shorthand
To make some manual editing scenarios a bit simpler, a shorthand syntax for setting a single field on a component is introduced. Using "Component.fieldName": "fieldValue"
one may set a single field on the component.
{
"TransformComponent.position": [ 0, 0, 0 ]
}
Rotations are internally represented as quaternions, which can be specified in the following forms:
"rotation": [w, x, y, z]
where w
is the real part and x,y,z
is the imaginary vector.
"rotation": [[x,y,x], theta]
where x,y,x
is the axis about which to rotate and theta
is the amount of rotation in radians.
"rotation": [[a_x,a_y,a_x], [b_x,b_y,b_x]]
where the quaternion rotates the direction of the vector a_x,a_y,a_x
to the direction of the vector b_x,b_y,b_x
. The two vectors do not need to be normalized.