File: animate_3d_model_by_code.lpr

package info (click to toggle)
castle-game-engine 6.4%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 194,520 kB
  • sloc: pascal: 364,585; ansic: 8,606; java: 2,851; objc: 2,601; cpp: 1,412; xml: 851; makefile: 725; sh: 563; php: 26
file content (97 lines) | stat: -rw-r--r-- 3,738 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
{
  Copyright 2008-2017 Michalis Kamburelis.

  This file is part of "Castle Game Engine".

  "Castle Game Engine" is free software; see the file COPYING.txt,
  included in this distribution, for details about the copyright.

  "Castle Game Engine" is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  ----------------------------------------------------------------------------
}

{ Example how to animate (change, modify) the 3D model (it's VRML/X3D graph)
  using ObjectPascal code.
  Run this program without any parameters in this directory
  (it opens file "data/boxes.x3dv") and watch the trivial animation.
  You can rotate/move the scene by dragging with mouse,
  see view3dscene docs (we use the same "Examine" camera).

  For programmers:

  Generally, you just change VRML/X3D graph (rooted in Scene.RootNode)
  however you like, whenever you like. TX3DNode class has a lot of methods
  to find and change nodes within the graph, you can insert/delete/change
  any of their children nodes, fields, and generally do everything.
  Remember to call "Changed" on every changed field (or change it only
  by Send methods, see more info on
  [http://castle-engine.sourceforge.net/vrml_engine_doc/output/xsl/html/section.scene.html#section.scene_caching].)

  Of course, in case of trivial animation in this program, we could
  also express it directly in VRML/X3D and just load the scene,
  setting Scene.ProcessEvents := true. This would make the scene "animate itself",
  without the need for any ObjectPascal code to do this. But, for example sake,
  we animate it here by our own code.
}

program animate_3d_model_by_code;

uses CastleVectors, X3DNodes, CastleWindow, CastleLog,
  CastleUtils, SysUtils, CastleGLUtils, CastleScene, CastleCameras,
  CastleFilesUtils, CastleParameters, CastleStringUtils, CastleKeysMouse,
  CastleApplicationProperties;

var
  Window: TCastleWindow;
  Scene: TCastleScene;

var
  TransformBox2: TTransformNode;
  TransformBox3: TTransformNode;
  TransformBox4: TTransformNode;

procedure Update(Container: TUIContainer);
begin
  { We want to keep track of current time here (for calculating rotations
    below). It's most natural to just use Scene.Time property for this.
    (Scene.Time is already incremented for us by SceneManager.) }

  { change rotation angles (4th component of the vector),
    leaving the rotation axis (XYZ components) unchanged. }

  TransformBox2.Rotation := Vector4(TransformBox2.Rotation.XYZ, Scene.Time);
  TransformBox3.Rotation := Vector4(TransformBox2.Rotation.XYZ, Scene.Time * 2);
  TransformBox4.Rotation := Vector4(TransformBox2.Rotation.XYZ, Scene.Time * 4);
end;

begin
  Window := TCastleWindow.Create(Application);

  Parameters.CheckHigh(0);
  ApplicationProperties.OnWarning.Add(@ApplicationProperties.WriteWarningOnConsole);

  Scene := TCastleScene.Create(nil);
  try
    Scene.Load(ApplicationData('boxes.x3dv'));
    TransformBox2 := Scene.RootNode.FindNodeByName(TTransformNode,
      'Box2Transform', true) as TTransformNode;
    TransformBox3 := Scene.RootNode.FindNodeByName(TTransformNode,
      'Box3Transform', true) as TTransformNode;
    TransformBox4 := Scene.RootNode.FindNodeByName(TTransformNode,
      'Box4Transform', true) as TTransformNode;

    { init SceneManager with our Scene }
    Window.SceneManager.MainScene := Scene;
    Window.SceneManager.Items.Add(Scene);

    { init SceneManager.Camera }
    Window.SceneManager.ExamineCamera.Init(Scene.BoundingBox, 0.1);

    Window.OnUpdate := @Update;
    Window.SetDemoOptions(K_F11, CharEscape, true);
    Window.OpenAndRun;
  finally Scene.Free end;
end.