[XUI] 3D, rotations and pivots

Star-Dust

Expert
Licensed User
Longtime User

Star-Dust

Expert
Licensed User
Longtime User
Difference between separate points and shared points:

Having an object, we know that it is described makes several polygons. Each polygon is defined by 3 or 4 points or more points. (Typically CADs use only 3 points per polygon)

Some Polygons that form the object have the same vertices as those next to it (see image,)
so they could be calculated only once.

To do this we must keep a list of unique vertices. The polygons instead of containing 3 points, contain three links to three points in the list of vertices.
upload_2018-6-25_14-29-15.png



In the image above we see that the points calculated from 35 are reduced only 15. Theoretically the calculation time is halved. How to implement it.

upload_2018-6-25_14-34-26.png

In separate points you need to have a list that contains a custom type.
B4X:
Type MyTypePolygon (Polygon_ID as int, ListPoint as List)
Type MyVertices (X as Float,Y as Float, Z as Float)
Dim ListPolygon as List

.....
ListPolygon.initialize

Dim NewPolygon as MyTypePolygon
NewPolygon.Initialize
NewPolygon.ID=100
NewPolygon.ListPoint.Initialize

Dim Point as MyVertices
Point.Initialize
Point.X=0
Point.Y=1
Point.Z=2

NewPolygon.ListPoint.Ad(Point)

ListPolygon.Add(NewPolygon)
ListPolygon

In shared points you need to have a custom list, which will contain the identifier of the polygon and a list of Indices

B4X:
Type MyTypePolygon (Polygon_ID as int, ListIndex_Of_Point as List)
Type MyVertices (X as Float,Y as Float, Z as Float)
Dim ListPolygon as List
Dim ListVertices as List

.....
ListPolygon.Initialize
ListVertices.Initialize


Dim Point as MyVertices
Point.Initialize
Point.X=0
Point.Y=1
Point.Z=2

Dim Position_InTo_ListVertice as int = AddVertice_If_not_Exist(ListVertices,Point)

Dim NewPolygon as MyTypePolygon
NewPolygon.Initialize
NewPolygon.ID=100
NewPolygon.ListIndex_Of_Point.Initialize
NewPolygon.ListIndex_Of_Point.Add(Position_InTo_ListVertice)

.....

This is just a simplified example to show how to implement a list of shared points.

Although theoretically you save computation time and it should be fast, managing multiple lists, indexing and searching if points already exist lower performance.
At least if I do not understand a better method of implementation

Update:
It seems that having shared points is effective when the object has many points, we speak of the order of tens of thousands / hundreds of thousands or even millions of points.
Below these sizes it is not very performing
 
Last edited:

OliverA

Expert
Licensed User
Longtime User
Dim Position_InTo_ListVertice as int = AddVertice_If_not_Exist(ListVertices,Point)
Actually you could do something like
B4X:
Dim newPoint as MyVertices = AddVertice_If_not_Exist(ArrayVertices, Point)
AddVertice would just return a reference of a point that exists in ArrayVertices (either because it just has been added, or it returns an existing point's reference). At this point, if you transform newPoint (change its values), the point with the same reference in ArrayVertices will also be changed. If you travers the ArrayVertices array and do your transformations, then all the points of the Polygons that reference the points in the ArrayVertices list will also be changed. No list lookup needed. I do not know if this would help with the speed of things, but it would take out a list lookup step. One must take care though to only assign a polygon's vertices from the ArrayVertices list and any new vertices are added to the ArrayVertices first before assigning them. Please note, this is just a brainstorm and may not be appropriate for this case.
 

OliverA

Expert
Licensed User
Longtime User
Another thought: Don't pass Point (a MyVertices object) to the AddVertice_If_not_Exist method, but the coordinates. This way you do not allocate a MyVertices object in case it does not need allocation. The method can decide if it needs to create a a MyVertices object or return an existing MyVertices object.

B4X:
Dim newPoint as MyVertices = AddVertice_If_not_Exist(ArrayVertices, X, Y, Z)
 

Star-Dust

Expert
Licensed User
Longtime User
Another thought: Don't pass Point (a MyVertices object) to the AddVertice_If_not_Exist method, but the coordinates. This way you do not allocate a MyVertices object in case it does not need allocation. The method can decide if it needs to create a a MyVertices object or return an existing MyVertices object.

B4X:
Dim newPoint as MyVertices = AddVertice_If_not_Exist(ArrayVertices, X, Y, Z)
In fact, this is how I do in my library, this was just an example to explain the concept of shared points. ;)
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Another thought: Don't pass Point (a MyVertices object) to the AddVertice_If_not_Exist method, but the coordinates. This way you do not allocate a MyVertices object in case it does not need allocation. The method can decide if it needs to create a a MyVertices object or return an existing MyVertices object.

B4X:
Dim newPoint as MyVertices = AddVertice_If_not_Exist(ArrayVertices, X, Y, Z)
Excellent reflection, I still reason with the old basic that did not have the pointers :p
 

sorex

Expert
Licensed User
Longtime User
Although theoretically you save computation time and it should be fast, managing multiple lists, indexing and searching if points already exist lower performance.

This is good for the 'designer' side of it and in theory you should only do this once when you add the object and then build a fast working setup (see below).

If I would use it in the end in a game menu or something I'd use an .obj like export of what I created with the lib and write custom array based routines for it.

for example (float or double needs to be tested on speed, int's are a lot faster but objects are always using tiny float numbers)

int polyCount
int Polys()
float VerticeX()
float VerticeY()
float VerticeZ()
bool VerticeAlreadyDrawn()
float CoordX()
float CoordY()
float CoordZ()
float VelX
float VelY
float VelZ

then you don't need all the list/map lookups, size checks and custom types.

lists are easy for quick mockup's but arrays are usually faster in the end.

But I already like that speed of what the library currently gives so thumbs up!
 

Star-Dust

Expert
Licensed User
Longtime User
I did the tests and the ints are much slower than the Float since the rotation are done with Sin and cos
 

Star-Dust

Expert
Licensed User
Longtime User
Excuse me, Google traslate does not translate correctly
 

Star-Dust

Expert
Licensed User
Longtime User
Looking, I saw that several have faced the problem of 3D graphics, with quite interesting results.
with the XUI interface, without using native APIs, I think we can not go beyond, at least with my limited knowledge.
I update the last things left unfinished. And I think I'll produce a library by July (I hope)

Now pause
 

OliverA

Expert
Licensed User
Longtime User

Star-Dust

Expert
Licensed User
Longtime User

OliverA

Expert
Licensed User
Longtime User
I did not know of the existence of less accurate mathematics
I did not pick the best wording. I just happened to remember that sin/cos and other computer intensive mathematics can usually be done in other ways that may prove faster, by trading accuracy for speed. With today's hardware, that may be a moot point.
 

Star-Dust

Expert
Licensed User
Longtime User
I did not pick the best wording. I just happened to remember that sin/cos and other computer intensive mathematics can usually be done in other ways that may prove faster, by trading accuracy for speed. With today's hardware, that may be a moot point.
From what little I have understood to not calulate SIN and COS every time required, it keeps a vector containing all the values of SIN and COS from 0 to 360 degrees.
Would this speed up?

Then create a table according to a code that I do not understand what it does
(see: http://www.java-gaming.org/topics/fast-math-sin-cos-lookup-tables/24191/view.html)

Now I have no time, I'll see another day
 
Last edited:

sorex

Expert
Licensed User
Longtime User
there will be a difference between multiplying with floats and just a look up table.

most computers since 486's have FPUs to improve these math speeds.

as written before it all depends on what your final result will be. if you want to spin a 3D logo in 4 seconds at 60fps you can pre-calc everything at app start or read it in from an asset file. only needs 4*60*3*verticesCountForFrameX and maybe a poly(+color) list of data if it's filled vector

most time will be wasted on the drawing altho you can cheat here aswell.
 

Star-Dust

Expert
Licensed User
Longtime User
B4XCanvas is not slower than the "native" Canvas objects. The performance of both is exactly the same.
YES I understood this, I meant native APIs for 3D. the API we use for the revolutions of the views (RotateX, RotateY).
I did not mean the Canvas that you already explained that has the same performance
 

Star-Dust

Expert
Licensed User
Longtime User
Sin formulas
Image4.gif


Cos formulas
Image6.gif
 
Top