TMS WEB Core 3D
TMS WEB Core 3D component library can be used to create impressive 3D WebGL applications in Delphi. It consists of several components to display interactive 3D Charts and Models in a Web Application. These components internally use WebGL through Three.js, an open source, cross-browser JavaScript library. The best thing is that one need not know WebGL or Three.js in order to make basic 3D applications with these components. At the same time, if the need arises, direct Three.Js API calls can be made in Delphi code through a JS interface library provided for the purpose.
Your first 3D Chart application
Create a standard TMS Web Application in the Delphi IDE by choosing File
, New
, Other
, TMS Web Application
.
A new web form is created. Go to the Tool Palette
and select the TWebThreeJsChart
component from the “TMS Web 3D” section and drop it on the web form.
Now the only thing remaining is to include the proper Three.js
library file. Right-click on the Project and select “Manage JavaScript Libraries.”
Choose the “Three JS (3D)” library and click OK
Save and Run the project. You will see a Default Chart
come up in the browser. Try to rotate the chart with the mouse and zoom with the mouse wheel. You get that interactive functionality out of the box, without writing any code!
You can now customize the data series for this chart in the code of the form as per your requirement. For some sample code, please see the demo project under the TMS folder Demo
, 3D
, Chart
. The demo code is discussed in the next section.
3D Business Chart Applications
As shown above, the TWebThreeJsChart
component can be used to create 3D
Business Chart
applications that draw bar, line or area charts.
The 3D Bar Chart Demo
After creating a quick 3D
chart application as shown in the previous section, the next step is to
try and understand the customization code in the Chart Demo
so that you can code your own
custom data series for a similar 3D
bar chart.
First of all, open the Chart Demo
under the TMS folder Demo
, 3D
, Chart
and run it. Move the
mouse over the chart items and you will see them glow with a Text Popup
showing the value.
Try out various features given in the Demo before we discuss the code.
The Terminology for Axes
Before coding the data series, you will need to understand how each axis is named. The above picture shows the name of each Axis
.
Creating the Data Series object
Please look at the Web Form
code of the procedure LoadSampleSeries1
.
var
aSeries: TThreeJsChartSeries;
begin
aSeries := TThreeJsChartSeries.Create(
TJSArray.New('East', 'West',
'North', 'South'),
TJSArray.New('Q1', 'Q2', 'Q3',
'Q4')
);
The constructor of the Series
object expects 2
parameters as the Axis
Labels to be passed in
two JS Arrays: 1. Legend
Axis Labels 2
. Category Axis Labels
Then the data is added in the form of each Legend Row
as an array in the following code. The Demo uses hard coded data but you can have your own logic to obtain the data for each Legend row
.
aSeries.addLegendRow('East',
TJSArray.New(41834, 52835, 46563,
60184));
aSeries.addLegendRow('West',
TJSArray.New(48842, 62964, 54243,
73796));
...
Series
set up code is easy to understand:
aSeries.valueAxisMarkMaximum := 100000;
aSeries.valueAxisMarkStep := 20000;
aSeries.valueFormatFloat := '$#,##0';
aSeries.valueAxisFormatFloat := ''; //use the above
aSeries.Title := 'Sales by Region';
aSeries.ValueAxisTitle := 'Quaterly Sales';
aSeries.LegendAxisTitle := 'Regions';
aSeries.CategoryAxisTitle := 'Quarters';
threeJsChart.Series := aSeries;
Notable points:
- The Format to show values on the chart items can be different from the format to show values on the
Value Axis
marks. But the above code uses the same format for both. - The series object is finally assigned to the
Series
property of theChart
component. The aboveLoad procedure
is called from theWebFormCreate
event and then the chart is displayed by the following code.
The chart component is smart enough to decide on proper axes length and marks based on the data. But you can set the dimensions of items too, resulting in a bigger or smaller chart area.
Other features shown in the Demo
You can run and explore the Chart
Demo to see many other features demonstrated:
- Built in objects: Many built in objects like the Camera, Spotlight, etc are automatically added by the component. You don’t have to write any code.
- Interactive Rotation and Zoom with the mouse and mouse wheel: You get this functionality out of the box, without writing any code.
- Choice of Chart Type: Chart items can be shown as
Bars
,Cylinders
,Cones
,Lines
orAreas
. - Auto colors: Colors are assigned automatically to
Legend
rows. You can specify custom colors too. - Dimension Properties for items: Item
Width
,Space
andPlot Width
(for Line and Area charts) can be changed. The dimensions are inWebGL
units. The component is smart enough to determine the length of bottom2
axes automatically based on the item dimensions. But you can override the default length ofValue Axis
by a separate property. - Transparency of Chart Items: can be set with additional Opacity property.
- Optional Legend display: can be specified to associate colors with Legend items.
- Auto Marking of
Value Axis
: The demo code does not use this feature by default. But you can switch on this checkbox to see its effect. This is a smart feature that determines the marks on the Value scale based on the data.
Other Niceties available:
- Auto rotate axis labels to always face the Camera
- Show value popups on all items
- Transparency and opacity control
Events
The following events are available:
- Interaction with Items:
OnItemClick
,OnItemExit
,OnItemDblClick
,OnItemMouseEnter
,OnItemMouseLeave
,OnItemMouseMove
- Interaction with other areas of the chart:
OnClick
,OnDblClick
For example, the Demo uses the above events to show features like displaying value popups on items and glowing of items when the mouse is moved over the items or when the items are clicked.
For example, the Demo uses the above events to show features like displaying value popups on items and glowing of items when the mouse is moved over the items or when the items are clicked.
3D Math Chart Applications
The component TWebThreeJsMathChart
is available to create 3D Math Chart
applications that draw Scatter
or Surface
charts.
The 3D Scatter Chart Demo
Open this Demo under the TMS folder Demo, 3D
, Scatter and run it.
The Terminology for Axes
Before coding the data series, you will need to understand how each axis is named in a Math
chart. This is different from the bar chart seen earlier that uses business terminology. The above
picture shows the name of each Axis
.
Creating the Data Series object
Please look at the Web Form code of the procedure LoadSampleSeries1
. The Series
class
is TThreeJsMathChartSeries
. The code that passes X
, Y
, Z
data to the series is:
Chart Demo
.
Other features shown in the Demo
Other features demonstrated are similar to those described for the earlier Chart Demo
except for the following differences:
-
Auto Marking feature now determines the length and scale marks for all
3
axes based on theSeries
data. The Demo uses this feature. This feature saves considerable effort for a typicalMath Chart
application to pre determine and set the length and scale marks for each axis. -
Improved Legend: The Legend in the scatter chart shows the shape of the point in addition to the color. The Events used in the Demo are also similar to those described for the earlier Chart Demo.
The 3D Surface Chart Demo
This demo demonstrates the features of TWebThreeJsMathChart
component used to draw a surface chart based on an Equation
. Hence, it is called a Parametric Surface Chart. Open this Demo under the TMS folder Demo
, 3D
, Surface
and run it.
How it works
In the Demo, you can select a Surface Equation
from a dropdown list to draw the surface chart
accordingly. For example, here is another Surface Chart
produced by the Demo:
Creating the Data Series object
Please look at the Web Form
code of the procedure LoadEquation
. The Series class is same as
that for earlier Scatter Demo– TThreeJsMathChartSeries
. But the procedure to add the data
for surface chart is different:
The ranges of values for X
and Y
are passed along with a Delphi Parametric callback function.
The Chart component does the following:
- Generates X and Y values based on the parameters passed
- For each pair of values, calls back the
Parametric
function of the application to get the value of Z.
The callback function used in the Demo is:
function TForm2.surfaceCallBack(x, y: double): double;
begin
case cbSeries.ItemIndex of
1: Result := abs(x-y);
2: Result := -x*x - y*y + 6;
3: Result := sin(x)*x+cos(y)*y;
4: Result := 2 * sqrt(x*x/3 + y*y/8);
5: Result := sqrt(abs(1.5 * (x*x/3 - y*y/4) - 6));
6: Result := 8 * (sin(x) + cos(y));
else
Result := x*x + y*y;
end;
end;
Z
value accordingly.
Other features shown in the Demo
You can run and explore the 3D Surface Chart Demo to see some more features provided for the Surface chart:
- Show Wire Frame: The cells of the wire frame depend on the
Resolution
value. - Show Wire Frame Texture: This draws a wire frame texture directly on the colored surface of the chart. With the default high resolution, you may not be able to see this. Try a lower resolution value to see how this works.
- Use
Custom
Colors
andTexture
.
3D PaintBox Applications
The TWebThreeJsPaintBox
component lets you create arbitrary 3D
Scenes containing often
used objects like Cubes
, Spheres
, Text
and more. In fact, these primitives come from the base
class and the already created Chart
components are great examples of the kind of applications
that are possible.
The 3D PaintBox Demo
You can open the PaintBox Demo
under the TMS folder Demo
, 3D
, Paintbox
and run it.
The Terminology for Axes
This component uses standard WebGL
axes. These are shown in the picture above. You need
to provide the positions of objects accordingly. All dimensions and positions are in WebGL units.
The code for adding objects
The objects are added to the scene in the OnCreate
event of the Web Form
with a code that
looks like the following. The initial parameters for each object are dimensions, followed by the a
TColor
, followed by X
, Y
, Z
position.
// Add a Bar with color $ff7777
anObject := threeJsPaintBox.AddBar( 2, 3, 2, $ff7777, 8, 7, 10);
anObject.name := 'bar1';
// Add a cube
anObject := threeJsPaintBox.AddCube(3, $00FF00, 16, 5, 8);
anObject.name := 'cube2';
// Add a Sphere
anObject := threeJsPaintBox.AddSphere(2, $0000ff, 10, 8, 4);
anObject.name := 'sphere1';
// Add a Cylinder
anObject := threeJsPaintBox.AddCylinder(1, 1, 7, $00ffff, 4, 3.5, 13);
anObject.name := 'cylinder1';
// repaint the box to show new objects
threeJsPaintBox.Invalidate;
There are many more parameters for above functions with defaults, for example, to specify transparency. But the Demo code does not use them and default values are used for those. You can make quite impressive 3D
applications by creating objects as shown above. The 3D
Chart components discussed earlier are examples of such applications.
Direct Use of the Three.Js
API
Object creation methods like “AddCube”
return a 3D
Object of the type TThreeJsObject3D
. Such types are Three.Js
objects made available to you in Delphi syntax via the specially coded JS Interface unit “Libthreejs.”
The end result is that you can directly use the methods and properties of these objects as documented in Three.Js
documentation. For example, to change the position of an object, you will change its “position” property directly, in Delphi code. All the methods that expect a color as a parameter have been modified to use TColor
of Delphi for the convenience of Delphi developers even though Three.Js
internally uses the Web color codes.
Sample code for Other features
Please run this Demo and inspect the source to see how you can perform these actions on objects in your own code.
- Built in objects: Many built in objects like the
Camera
,Spotlight
, etc are automatically added by the component. You don’t have to write any code. - Interactive Rotation and Zoom with the mouse and mouse wheel: You get this functionality out of the box, without writing any code.
- Rotation by code: Rotate the whole scene around the origin by
RotateLeft
andRotateRight
methods of the component. The demo usesRotate
trackbars to show this feature. - Change Center of Viewing: To make another object’s position as the center of viewing/rotation, use the method
SetTargetViewVector
and pass the position of another object. This is demonstrated by the button “Set Cube2 as Center of Viewing.” - Panning by code: Similarly, you can pan the camera by
Pan*
methods of the component. The demo shows this feature by the4
Pan buttons. - Zooming by code: Use the
ZoomIn
method. This is shown by theZoom trackbar
. - Save orientation: Suppose you want to save the exact orientation of the scene with respect to the camera and then restore it later. A SaveState method is provided for this purpose. Similarly, a
ResetState
restores the orientation to a saved state. The Demo shows this feature by “Save Orientation” and “Restore Orientation” buttons. - Debugging arrow: Sometimes, you may want to know the exact position of certain invisible objects like the
SpotLight
and its target. A methodShowDebugArrow
is provided for this purpose. The demo shows this feature via the button “ShowArrow
from Spotlight to ItsTarget
.” - Moving an object: If you have the handle of an object, you can change its position property directly. This is shown by the buttons “Move Spotlight Up/Down” where the object used is the
Built
InSpotLight
object. You can use such code on any object that you have saved as a variable. The bottom trackbars are used in the Demo to move the object selected in the List “Operations on Object.”
Events
The following events are available:
- Interaction with Objects:
OnItemClick
,OnItemExit
,OnItemDblClick
,OnItemMouseEnter
,OnItemMouseLeave
,OnItemMouseMove
- Interaction with other areas of the Scene:
OnClick
,OnDblClick
3D Model Applications
The TWebThreeJsModelBox
component lets you create or load arbitrary 3D
Models from
model files. In addition to the earlier described PaintBox
methods, it contains methods to add
Obj/Mtl
or GLTF
models from model files and can Export
the scene to GLTF
model files.
“ThreeJS Models (3d)” JS Library is required
If you use the TWebThreeJsModelBox
component in an application, you should include the JS
Library “ThreeJS Models (3d)” by using the same Project right-click menu “Manage JavaScript
Libraries” that is described in an earlier section “Your first 3D Chart application.”
The 3D Model Demo
Since this Demo needs to load models from data files, an extra second step is required to copy those files as described below.
- Open the Model Demo under the
TMS folder Demo
,3D
,Model
. - Copy the
2
subfolders from theData
folder of the project to the web output folder. - Now build and run the Demo.
- Select the
Model “R2 D2 Robot”
at the top and click on“Load Obj/Mtl Object”
to get a result similar to the following picture.
The Code to Load OBJ/MTL Models
You will see a code like the following to add objects from OBJ/MTL
files:
threeJsModelBox.AddObjectMtl('model-R2D2',
'r2-d2.obj', 'assets/',
'r2-d2.mtl', 'assets/',
'assets/');
OBJ
and MTL
model file
names and various folders accompanying them.
The code to Load GLTF Model
You will find this in the action code of Load GLTF
Model button. The call is AddObjectGltf
that is
much simpler because only one GLTF
file needs to be specified with an optional path for the
accompanying folder, often not needed.
Getting the Object in OnObjectLoad
event
Note that the loading of the Model is asynchronous and requires internal loading of many other
files such as textures. So the above Add
methods do not return an Object
immediately.
Instead, you have to use the event OnObjectLoad
that hands over the object to you. There, you
can take other actions on the object like rotating it if needed. For example, if you see the code for this event,you will see a particular “Gothic Fence”
object being rotated after loading because
its default loaded view is horizontal, flat.
Additional features for Models
Auto Position Object after Loading by the method BringObjectInFullView
A third party 3d model object can be of any size. The Three.Js
code to properly position the
camera so as to bring the object of any size in full view is complicated. Hence, the component
implements a method BringObjectInFullViewthat
does this job well.
This method is used in the Demo’s OnObjectLoad event to bring the object properly in view.
You can see the difference made by this auto positioning method by unchecking the option
when loading the R2 D2
model. The model is large and if you do not use the above method, you
can only see the feet of the Robot after a load. You need to zoom out to see the full Robot
which is big.
Additional Lights and Gamma Correction
To demonstrate loading of GLTF
models, the Demo uses an already exported GLTF
file from
the Demo itself for the same R2 D2
Robot. Just click on the button “Load GLTF File”
to load it.
You will notice that the loaded model appears darker as compared to OBJ/MTL
loaded result.
This is so because GLTF
models process the model as per their own algorithms needed to
store everything in one file. Hence, GLTF
models often need more light and something called a
“Gamma Correction.” Hence,please switch on those options in the Demo, and then reload to
see how it works better.
The above options use the component method AddLights
and the property UseGammaCorrection
.
Changing colors of lights
The Model Demo also shows sample code for changing color of various lights, including the
built-in SpotLight
and AmbientLight
.