0% found this document useful (0 votes)
589 views20 pages

Obj2pbt Documentation 9 3 21

This document describes a program that converts .obj 3D model files into .pbt files that can be used in the Core game engine. The program breaks triangle meshes into individual right triangles, calculates the position, scale, and rotation of each triangle, and writes this data into a .pbt file. The code is organized using classes like Object and Folder to represent the 3D elements and hierarchy that will be converted from the .obj file.

Uploaded by

api-560762422
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
589 views20 pages

Obj2pbt Documentation 9 3 21

This document describes a program that converts .obj 3D model files into .pbt files that can be used in the Core game engine. The program breaks triangle meshes into individual right triangles, calculates the position, scale, and rotation of each triangle, and writes this data into a .pbt file. The code is organized using classes like Object and Folder to represent the 3D elements and hierarchy that will be converted from the .obj file.

Uploaded by

api-560762422
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

.OBJ TO .

PBT FILE CONVERTER


FOR CORE

BY: THE .OBJ TO .PBT GROUP

Document author: Gabriel Becker (Zanth)


Document co-authors: Rivvnik (Jacob) and Zolge (Zak)
1

Contents
1 Introduction .................................................................................................................................. 2
1.1 Project Overview .................................................................................................................. 2
1.2 Project Contributors .............................................................................................................. 2
2 Requirements ............................................................................................................................... 3
2.1 User Requirements ................................................................................................................ 3
2.1.1 Software requirements ................................................................................................... 3
2.1.2 How to use the program ................................................................................................. 3
2.2 Project Functional Requirements .......................................................................................... 3
3 Code documentation .................................................................................................................... 4
4 Methodology .............................................................................................................................. 11
4.1 Overview ............................................................................................................................. 11
4.2 Splitting one triangle into two right triangles ..................................................................... 11
4.3 Calculating position, scale, and rotation ............................................................................. 13
4.3.1 Position ........................................................................................................................ 13
4.3.2 Scale ............................................................................................................................. 14
4.3.3 Rotation ........................................................................................................................ 14
4.4 Position, scale, and rotation to .pbt ..................................................................................... 15
5 Testing........................................................................................................................................ 16
5.1 Overview ............................................................................................................................. 16
5.2 Testing Methodology .......................................................................................................... 16
5.2.1 Example 1 .................................................................................................................... 16
5.3 Position ............................................................................................................................... 17
5.4 Scale .................................................................................................................................... 17
5.5 Rotation ............................................................................................................................... 18
5.6 .obj to .pbt ........................................................................................................................... 19

Document last updated: 9/2/2021


2

1 Introduction
1.1 Project Overview
Manticore Games created Core as a platform for users to create and publish minigames utilizing
assets provided by the game’s engine; thus, many Core minigames look inherently similar due to
the limited roster of assets available to creators.

This project is an attempt to work around this limit, resulting in a program that converts .obj
models — exported from software like Cinema4D or Blender — into .pbt files capable of being
understood by Core’s game engine.

1.2 Project Contributors


Tag Discord tag GitHub username Roles
Rivvnik @Rivvnik#1111 Rivvnik project head, main
code contributor,
document co-author
Zolge @Zolge#9558 ZolgeAZ project co-author, Core
creator, document co-
author
Zanth @Zanth#2048 GabeBecker2048 code contributor,
document author
Aphrim @Aphrim#1337 aphrim code contributor
Waffle @Waffle#3956 Waffle3z code contributor, Core
creator
3

2 Requirements
2.1 User Requirements

2.1.1 Software requirements


The following is required to run this program:
- A Windows 10 PC (other versions of Windows might work but have not been tested)
- A triangulated .obj file

2.1.2 How to use the program


To utilize the program:
- Open obj2pbt.exe
- Click on the text button that says “select triangulated .obj file”
- Select the .obj file you wish to convert
- Let the program do its work
o The program may say it is not responding for long periods of time. Do not close
the program; it is likely still working as intended.
- When the program finishes it will generate your .pbt file in the location where your .obj
file was

2.2 Project Functional Requirements


The functional requirements of a project describe what it should do.

There is one functional requirement for this project:

- When the user opens the program and selects a .obj file, the program will convert the .obj
into an equivalent .pbt file
4

3 Code documentation
The program was written entirely in python and was then compiled into an executable file using
the pyinstaller library.

class Object(name, position, rotation, scale, parent_id, mesh_id)


Attributes Methods
name def generate_pbt_part

position

rotation

scale

parent_id

mesh_id

id

Represents an object

name

The name of the object


Type
str

position

The position of the object in 3D space. For right triangles, this is the point where the right
angle occurs
Type
list[ float, float, float ]

rotation

The rotation of the object in 3D. The three xyz-Euler angles required to rotate the object
Type
list[ float, float, float ]

scale

The scale of the object in 3D. For wedges, this is thickness, length, and width of the
object
Type
5

list[ float, float, float ]

parent_id

The id of the object’s parent. This id represents a Folder


Type
int

mesh_id

The mesh id of the object


Type
int

id

The id of the object


Type
int

generate_pbt_part()

Generates a string that can be inserted into a .pbt file to add the object

Parameters
None

Return Type
str

class Folder(root)
Attributes Methods
id def add_child
children def children_to_string
root def generate_pbt_part

Represents a parental grouping of Objects

id

The id of the folder


Type
int

children
6

A list of child Objects


Type
list[ Object* ]

root

The PBT object to which the Folder belongs


Type
PBT

add_child(name, mesh_name, position, rotation, scale, parent_id)

Generates an Object child with corresponding parameters and adds to self.children

Parameters

name (str) - the name of the child


mesh_name (str) - the name of the mesh. Used to generate the mesh_id of the Object
position (list[ float, float, float ]) - the position of the object in 3D space. For
right triangles, this is the point where the right angle occurs
rotation (list[ float, float, float ]) - the rotation of the object in 3D. The three
xyz-Euler angles required to rotate the object
scale (list[ float, float, float ]) - the scale of the object in 3D. For wedges, this
is thickness, length, and width of the object
parent_id (int or None) - the parent id of the object. If this is None, then it will be set to
the Folder’s id

Return Type
Object

child_to_string()

Generates a string of the Folder’s children to be inserted into the .pbt file. This function
is used in generate_pbt_part()

Parameters
None

Return Type
str

generate_pbt_part()

Generates a string that can be inserted into a .pbt file to add the folder. This is done by
iterating through all Objects in self.children and adding their data into a string

Parameters
None
7

Return Type
str

class PBT(name)
Attributes Methods
template_name def get_mesh_id_for_name
template_id def add_folder
root_id def children_to_string
objects def all_objects_pbt
meshes_by_id def object_assets_pbt
def generate_pbt

template_name

The name of the template. This is set by the name parameter during initialization
Type
str

template_id

The id of the template


Type
int

root_id

The id of the root


Type
int

objects

A list of Folders to add to the .pbt file


Type
list[ Folder* ]

meshes_by_id

A list of dictionaries containing a mesh’s id and name


Type
list[ dict{“id” : int, “name” : str}* ]

get_mesh_id_for_name(mesh_name)
8

Finds the dictionary in self.meshes_by_id whose “name” key is mesh_name. If mesh_name


is not in self.meshes_by_id, then it is added. Returns the mesh id

Parameters

mesh_name (str) - the name of the mesh to find

Return Type
int

add_folder()

Generates a new Folder with self as the root parameter of Folder(root), and adds it to
self.objects. Returns the new Folder

Parameters
None

Return Type
Folder

children_to_string()

Generates a string of all the Folder’s ids in self.objects to be inserted into the .pbt file.
This function is used in generate_pbt()

Parameters
None

Return Type
str

all_objects_pbt()

Generates a string of all Folder’s pbt parts in self.objects. This is done by iterating
through all Folders in self.objects and adding their data into a string. This function is
used in generate_pbt()

Parameters
None

Return Type
str

objects_assets_pbt()
9

Generates a string of all meshes in self.meshes_by_id. This is done by iterating through


all meshes in self.meshes_by_id and adding their data into a string. This function is used
in generate_pbt()

Parameters
None

Return Type
str

generate_pbt()

Generates a string to be put into a .pbt file

Parameters
None

Return Type
str

def generate_id()
Generates a random and unique id and returns the id

Parameters
None

Return Type
int

def triangle(a, b, c)
Takes in three points representing a triangle in 3D space and returns the position, scale,
rotation of the two right triangles that split the given triangle. The methodology for this is
detailed in section 4.2 and 4.3. The order of returned values is as follows:
- Position of triangle0
- Position of triangle1
- Scale of triangle0
- Scale of triangle1
- Rotation of triangle0
- Rotation of triangle1

Parameters
a (list[ float, float, float ]) - a point on a triangle
10

b (list[ float, float, float ]) - a point on a triangle


c (list[ float, float, float ]) - a point on a triangle

Return Type
Tuple( list[ float, float, float ], list[ float, float, float ],
list[ float, float, float ], list[ float, float, float ],
list[ float, float, float ], list[ float, float, float ])

def run(path)

Takes a file path to an .obj file as input, converts it into a .pbt file, and writes the .pbt file
into the directory that the .obj file belongs to.

Parameters

path (str) – the file path to the .obj file

Return Type
None
11

4 Methodology
4.1 Overview
3D models in triangulated .obj files are defined by polygons split into triangles. Core does not
have support for arbitrary triangles defined by point triplets; it does, however, support placement
of 3D wedges. By setting the wedge’s thickness to 0.002, we can essentially create 3D right
triangular planes.

By extracting the triangle information from an .obj file, splitting each triangle into two right
triangles, converting the point triplets into wedges defined by vectors with thickness 0.002, and
placing that data into a .pbt file, we convert the .obj model into an equivalent .pbt model.

4.2 Splitting one triangle into two right triangles


Starting with three arbitrary and unique points, 𝑎, 𝑏, and 𝑐, we define triangle △ 𝑎𝑏𝑐 with angle
∠𝑎𝑐𝑏 being the largest (or, in the case of equilateral triangle, tied for the largest) angle in the
triangle.

Pictures and example for ease of visualization:

̅̅̅ and 𝑎𝑐
We imagine sides 𝑎𝑏 ⃗⃗⃗⃗ and 𝑎𝑏
̅̅̅ as vectors 𝑎𝑏 ⃗⃗⃗⃗ :
12

Define a new vector ⃗⃗𝑙1, which is the vector projection of 𝑎𝑐 ⃗⃗⃗⃗ onto vector ⃗⃗⃗⃗
𝑎𝑏 (denoted by
proj𝑎𝑏
⃗⃗⃗⃗⃗ ⃗⃗⃗⃗
𝑎𝑐 ). This can be calculated by:
⃗⃗⃗⃗ ∙ ⃗⃗⃗⃗
𝑎𝑐 𝑎𝑏
proj⃗⃗⃗⃗⃗ ⃗⃗⃗⃗
𝑎𝑐 or 𝑙1 = ⃗⃗⃗⃗
𝑎𝑏
𝑎𝑏 ⃗⃗⃗⃗ ⃗⃗⃗⃗
𝑎𝑏 ∙ 𝑎𝑏

⃗⃗⃗⃗ onto 𝑎𝑐
Define another new vector, 𝑝, which is the vector rejection of 𝑎𝑏 ⃗⃗⃗⃗ . This can be calculated
by:
𝑝 = ⃗⃗⃗⃗
𝑎𝑏 − ⃗⃗𝑙1
13

By definition of vector rejection, 𝑝 is at a right angle to ⃗⃗⃗⃗


𝑎𝑏 and points to 𝑐.

Finally, define one last vector, ⃗𝑙⃗2 which is defined by:

𝑎𝑐 ∙ ⃗⃗⃗⃗
⃗⃗⃗⃗ 𝑎𝑏
⃗⃗⃗
𝑙2 = (1 − ⃗⃗⃗⃗
) 𝑎𝑏
⃗⃗⃗⃗
𝑎𝑏 ∙ ⃗⃗⃗⃗
𝑎𝑏

Using these vectors, we can define two triangles, which we call triangle0 and triangle1.

4.3 Calculating position, scale, and rotation


Wedges in Core have three required components – position, scale, and rotation. Using the
vectors found in section 3.3, these components can be calculated.

4.3.1 Position
14

The position of a wedge in Core is the point where the right angle occurs. Notice that this point is
⃗⃗⃗⃗ that ⃗⃗𝑙1 and ⃗⃗⃗
the same for both triangle0 and triangle1. Position in our model is the point on 𝑎𝑏 𝑙2
point towards, and from which 𝑝 originates.

This is calculated by:


𝑐+𝑎 ⃗⃗⃗⃗ ∙ ⃗⃗⃗⃗
𝑎𝑐 𝑎𝑏
position = +( ⃗⃗⃗⃗
) 𝑎𝑏
2 2‖𝑎𝑏 ⃗⃗⃗⃗ ‖

4.3.2 Scale
The scale of a wedge in Core is a list of three variables: thickness, length, and width.
- The thickness of our wedges is 0.002, which is the smallest acceptable thickness. This is
so our wedges appear as triangles.

- The length of our wedges is calculated by:


o Length of triangle0 = ‖𝑙⃗⃗1 ‖
o Length of triangle1 = ‖𝑙⃗⃗2 ‖

- The width of our wedges is a shared side and is therefore the same for both triangle0 and
triangle1. This is calculated by:
o Width of triangle0/triangle1 = ‖𝑝‖

4.3.3 Rotation
The rotation of a wedge in Core is defined by the xyz-Euler angles required to rotate the wedge.
To calculate rotation, we first need to define the 3x3 rotation matrices for triangle0 and triangle1,
which we will call matrix0 and matrix1 respectively.

This is defined as:

̂
−𝑝̂ × 𝑎𝑏
- matrix0= [ 𝑝̂ ]
−𝑎𝑏̂

̂
−(−𝑝̂ × 𝑎𝑏)
- matrix1 = [ 𝑝̂ ]
̂
𝑎𝑏

Where:
15

𝑝
- 𝑝̂ is the unit vector of 𝑝, i.e. 𝑝̂ = ‖𝑝‖

⃗⃗⃗⃗⃗
- ̂ is the unit vector of ⃗⃗⃗⃗
𝑎𝑏 ̂ = 𝑎𝑏
𝑎𝑏, i.e. 𝑎𝑏 ⃗⃗⃗⃗⃗ ‖
‖𝑎𝑏

- ̂ is the cross product of −𝑝̂ and 𝑎𝑏


−𝑝̂ × 𝑎𝑏 ̂

Rotation for our program is then calculated through the following scipy function:

- Rotation of triangle0 =
scipy.spatial.transform.Rotation.from_matrix(matrix0).as_Euler('xyz',
degrees=True) * [-1, -1, 1]

- Rotation of triangle1=
scipy.spatial.transform.Rotation.from_matrix(matrix1).as_Euler('xyz',
degrees=True) * [-1, -1, 1]

We multiply the angles by [-1, -1, 1] as a correction for Core.

4.4 Position, scale, and rotation to .pbt


Once we have calculated the position, scale, and rotation of the two triangles, we can put this
data into a newly created .pbt file by following the correct .pbt syntax.
16

5 Testing
5.1 Overview
Because this project is very informal, testing documentation is not detailed, formalized, or even
required. Most tests are either kept secret or deleted after they have served their purpose.

The focus of this testing is to ensure overall correctness.

5.2 Testing Methodology


We can compare our program’s output to known-good data to test for correctness.

5.2.1 Example 1

First, we draw triangle △ 𝑎𝑏𝑐 in Core with the following three points:

{
"a": [-9.42809009552002, -1.92450094223022, -2.72165536880493],
"b": [-8.52802848815918, 1.74077653884888, -4.92365980148315],
"c": [-8.57492923736572, -1.40028011798859, -4.95073795318604]
}

We then extracted the triangle data from Core:

{
"triangle_1": {
"position": {
"x": -9.070,
"y": -0.466,
"z": -3.598
},
"rotation": {
"x": -114.189,
"y": 30.261,
"z": -103.797
},
"scale": {
"x": 0.026,
"y": 0.017,
"z": 0.000
}
},
"triangle_2": {
"position": {
"x": -9.070,
"y": -0.466,
17

"z": -3.598
},
"rotation": {
"x": 125.080,
"y": 51.990,
"z": 117.915
},
"scale": {
"x": 0.017,
"y": 0.017,
"z": 0.000
}
}
}

We can now test this known-good data against the data that our program outputs.

5.3 Position
The position of a wedge in Core is the point where the right angle occurs. We can test this
calculation with the example detailed in 5.2.1

When we ran the program with the test data above, the program output the following positions:

"triangle_1": {
"position": {
"x": -9.070,
"y": -0.466,
"z": -3.598
},

},
"triangle_2": {
"position": {
"x": -9.070,
"y": -0.466,
"z": -3.598
},

}

which is the correct output

5.4 Scale
The scale of a wedge in Core is a list of three variables: thickness, length, and width. We can test
this calculation with the example detailed in 5.2.1

When we ran the program with the test data above, the program output the following scales:
18

"triangle_1": {

"scale": {
"x": 0.026,
"y": 0.017,
"z": 0.000
}
},
"triangle_2": {

"scale": {
"x": 0.017,
"y": 0.017,
"z": 0.000
}
}

which is the correct output

5.5 Rotation
The rotation of a wedge in Core is the xyz-Euler angles required to rotate the wedge. We can test
this calculation with the example detailed in 5.2.1

When we ran the program with the test data above, the program output the following rotations:

"triangle_1": {

"rotation": {
"x": -114.189,
"y": 30.261,
"z": -103.797
},

},
"triangle_2": {

"rotation": {
"x": 125.080,
"y": 51.990,
"z": 117.915
},

}

which is the correct output.

5.6 .obj to .pbt


19

This test fully converts a .obj file to .pbt. To test this, we will download a .obj model and fully
converted it to a .pbt model with the program. We then put this model into Core and see if the
converted model looks correct.

We created the following model:

After converting the model from .obj format into a .pbt file, we inserted it into Core Create and
saw the following results:

As can be seen in the screenshots above, this is the correct output.

Models within .obj files may be split into groups to allow separate coloration as seen below:

You might also like