# Creating objects on the fly

**URL:** <https://forum.castle-engine.io/t/creating-objects-on-the-fly/140>\
**Category:** Uncategorized\
**Created:** [April 21, 2020, 5:38pm UTC](https://forum.castle-engine.io/t/creating-objects-on-the-fly/140 "2020-04-21T17:38:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Peardox](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/p/dec6dc/32.png) [@Peardox](https://forum.castle-engine.io/u/Peardox)\
**Post date:** [April 21, 2020, 5:38pm UTC](https://forum.castle-engine.io/t/creating-objects-on-the-fly/140/1 "2020-04-21T17:38:05Z")

</div>

I’m developing an Application that helps players of Magic the Gathering and I’ve come to UI design time - CGE looks like a good option.

After weeks of messing with Blender (never used it before) I’ve hacked together a test obj of a MTG card that looks nice + realistic (new member - no upload so if you want to see what I’m banging on about the obj is at [https://peardox.com/script/mtg.zip](https://peardox.com/script/mtg.zip))

Anyway one obj can define any MTG card. All that changes is the image in the front of the card. In card.mtl replacing front.png with another card image is all that’s required.

Usually I’d use something like Scene.LoadFromStream(…) but there ain’t one

Basically the only thing that’s required is changing a filename to create any of the 25k+ possible cards.

I’d like to load in and composite the image used from a JPEG and a mask (PNGs are huge).

I presume there’s some way to have a base model you can switch the texture on - just can’t work out what to do

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [April 21, 2020, 7:26pm UTC](https://forum.castle-engine.io/t/creating-objects-on-the-fly/140/2 "2020-04-21T19:26:09Z")

</div>

Hi!

> After weeks of messing with Blender (never used it before) I’ve hacked together a test obj of a MTG card that looks nice + realistic (new member - no upload so if you want to see what I’m banging on about the obj is at [https://peardox.com/script/mtg.zip](https://peardox.com/script/mtg.zip))

Some notes about the OBJ model:

- Note that if you use Blender, I would advise exporting from Blender to glTF 2.0 now, instead of OBJ. See [Blender | Creating Game Data | Castle Game Engine](https://castle-engine.io/creating_data_blender.php) and [Supported model formats | Creating Game Data | Castle Game Engine](https://castle-engine.io/creating_data_model_formats.php) . glTF is a great format, I’m working since a few weeks to basically have perfect support of glTF in the engine (see news [Castle Game Engine – Open-Source 3D and 2D Game Engine](https://castle-engine.io/wp/) ) and it’s already working better than _any_ other format 🙂

- If you want to experiment with pretty cards look under dynamic lighting, consider using normal maps. You can generate a normalmap from an image using GIMP normalmap plugin.

> Anyway one obj can define any MTG card. All that changes is the image in the front of the card. In card.mtl replacing front.png with another card image is all that’s required.

The optimal way to do this is to load your model to an “X3D node graph” (instance of TX3DRootNode), replace the texture, and then create TCastleScene from this node graph.

So instead of loading like this:

```pascal
function LoadCard: TCastleScene;
begin
  Result := TCastleScene.Create(nil);
  Result.Load('castle-data:/card.obj');
end;

```

you would instead do this:

```pascal
function LoadCard(const TextureUrl: String): TCastleScene;
var
  CardNode: TX3DRootNode;
  TextureNode: TImageTextureNode;
begin
  Result := TCastleScene.Create(nil);
  
  CardNode := LoadNode('castle-data:/card.obj');
  TextureNode := CardNode.FindNode(TImageTextureNode, false) as TImageTextureNode;
  TextureNode.SetUrl([TextureUrl]);
  
  Result.Load(CardNode, true);
end;

```

This is a general way to process a model in CGE. So you process TX3DRootNode before passing it to TCastleScene.Load .

There are various ways to customize it:

- Instead of `CardNode.FindNode(TImageTextureNode, false)` you could look for a node in different ways or enumerate all nodes of certain types. See the [API references of TX3DNode](https://castle-engine.io/apidoc-unstable/html/X3DNodes.TX3DNode.html) and various methods like FindNode, TryFindNode, EnumerateNodes etc.

- Instead of loading CardNode from file each time (in each `LoadCard` invocation), you can load it once (e.g. make `CardNode` a global variable and call `CardNode := LoadNode('castle-data:/card.obj')` once, at the application initialization). Then in `LoadCard` you would merely copy an existing graph by `DeepCopy`, like this:

```pascal
function LoadCard(const TextureUrl: String): TCastleScene;
var
  CardNodeCopy: TX3DRootNode;
  TextureNode: TImageTextureNode;
begin
  Result := TCastleScene.Create(nil);
  
  CardNodeCopy := CardNode.DeepCopy as TX3DRootNode;
  TextureNode := CardNodeCopy.FindNode(TImageTextureNode, false) as TImageTextureNode;
  TextureNode.SetUrl([TextureUrl]);
  
  Result.Load(CardNodeCopy, true);
end;

// call like 
// MyScene := LoadCard('castle-data:/textures/some_different_texture.jpg');

```

This way the file is loaded only once, and your code only creates multiple copies of the graph, each copy with a different texture URL.

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [April 21, 2020, 7:37pm UTC](https://forum.castle-engine.io/t/creating-objects-on-the-fly/140/3 "2020-04-21T19:37:53Z")

</div>

P.S. I forgot to mention important hints: How to investigate this “X3D node graph” that I talk about ? 🙂

- It’s easiest to open the OBJ file in view3dscene (you have it in engine bin/ subdirectory, if you downloaded CGE binary release, or you can get it from [https://michalis.ii.uni.wroc.pl/view3dscene-snapshots/](https://michalis.ii.uni.wroc.pl/view3dscene-snapshots/) ). In view3dscene, save it to X3D using “File-\>Save as X3D (classic…)” menu item. Then open the resulting `xxx.x3dv` file in any text editor. You can search there e.g. for `ImageTexture`, this is the texture node (available in Pascal as `TImageTextureNode` instance). All the other nodes can be processed in the same way in CGE, you can add/remove nodes, you can even do it at runtime (after loading the scene, although _some_ changes are more expensive then).

- [https://castle-engine.io/vrml\_x3d.php](https://castle-engine.io/vrml_x3d.php) contains documentation of these nodes. Actually the X3D specification is the documentation of most of these nodes, and our [https://castle-engine.io/vrml\_x3d.php](https://castle-engine.io/vrml_x3d.php) (and subpages) links to it. The texture nodes are on this subpage: [https://castle-engine.io/x3d\_implementation\_texturing.php](https://castle-engine.io/x3d_implementation_texturing.php) .

---

<div class="post-metadata">

**Author:** ![Peardox](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/p/dec6dc/32.png) [@Peardox](https://forum.castle-engine.io/u/Peardox)\
**Post date:** [April 28, 2020, 7:16pm UTC](https://forum.castle-engine.io/t/creating-objects-on-the-fly/140/4 "2020-04-28T19:16:58Z")

</div>

Implemented as you suggested with some positioning added to LoadCard then added 12 of them to the ViewPort.

Looks better running than the screengrab suggests (grab’s slightly blurred for some reason)

Given the following image is there a simple way to click on one of the Cards and detect which one it was?

 ![v0.0.0.1](https://forum.castle-engine.io/uploads/default/original/1X/953a47b9ab94fc140039d86fa67dd424a89a11b1.jpeg)

Next steps - add a background + animate some cards

Completely unimportant info - That selection of cards is called Red Deck Wins (well one variant of it)

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [April 28, 2020, 11:30pm UTC](https://forum.castle-engine.io/t/creating-objects-on-the-fly/140/5 "2020-04-28T23:30:43Z")

</div>

> [@Peardox](#):
>
> Given the following image is there a simple way to click on one of the Cards and detect which one it was?

Sure. When each card is a separate TCastleScene, you can just look at `Viewport.MouseRayHit.First.Item` in a press event (like `TCastleWindowBase.OnPress`). This is an instance of `TCastleTransform` (ancestor of `TCastleScene`) under the mouse. Example is in [https://github.com/castle-engine/castle-engine/blob/master/examples/3d\_rendering\_processing/detect\_scene\_clicks.lpr](https://github.com/castle-engine/castle-engine/blob/master/examples/3d_rendering_processing/detect_scene_clicks.lpr) .

---

<div class="post-metadata">

**Author:** ![Peardox](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/p/dec6dc/32.png) [@Peardox](https://forum.castle-engine.io/u/Peardox)\
**Post date:** [April 30, 2020, 4:37am UTC](https://forum.castle-engine.io/t/creating-objects-on-the-fly/140/6 "2020-04-30T04:37:46Z")

</div>

Well that was indeed, as requested, nice and simple.

Touch is also detected on my laptop. I’ll have to try out iOS + Android at some point soon (fpcupdeluxe is being awkward on Windows, yet to try Mac)…
