class: top, left, inverse, title-slide # Education & Globalization ## Session 13 ### Dr. Zhou Yisu 周憶粟 ### 2018/10/04 --- # Global flows of people ## Aimes To consider different types of global flows of people To examine the push and pull factors involved in shaping flows of people To examine the structures that expedite 加速 or impede 抑制 (i.e. barriers) flows of people --- .pull-left[

“每年十月一日，又到了中国潜水员交配的季节。他们不远万里，成群结队的来到东南亚各珊瑚礁海域，觅食、产卵。这是一趟非凡的旅程，他们将冒着被海洋大型掠食者捕杀、海洋船只螺旋桨、以及海洋内不稳定洋流的危险，进行为期7天的交配。然后再各自返回他们的栖息地。” pic.twitter.com/AdaqvGO3YJ
— Maki.🌺 (@makittsp) September 29, 2018
 ] .pull-right[ .green[Translation:] Every October 1st is the mating season of Chinese divers. They traveled thousands of miles in teams and groups to the South East Asian coral reefs for food and mating. This is an extraordinary journey: These divers risked their lives of being eaten by large sea predators, strangled by ship propellers, and carried away by unstable ocean currents. They mated during these 7 days and returned to their habitats.] --- ## People flows Globalization can be seen to have .green[expedited] 加速 global flows of people, although there is a long history of exodus and travel throughout the world Flows of people: - .orange[Migrants/ immigration] 移民: People who live in a country where they were not born and have important social ties to that country - .orange[Human trafficking survivors] 人口販運 - .orange[Tourists] 遊客 --- ## Migration/Immigration .pull-left[ Includes: - Temporary labor migrants 臨時性勞工移民 - Highly skilled migrants 高技術移民 - Forced migrants 強制移民 - Family reunification migrants 家庭團聚 - Return migrants 返鄉移民 Difference compared to historical trends: - Migration from developed countries declining - Number of migrants from developing countries increasing ] .pull-right[ Problems involved in tracking flows: - Lack of or inadequate data collection - Use of different definitions and measures - Little tracking of expats .red[1] - Lack of information on undocumented immigration .footnote[ [1] expats is short for .violet[expatriate] 移居外國的人] ] --- ## Example: Macao as a "floating city" .kt[2016中期人口統計結果顯示，今年8月澳門人口共650,900人，較2011人口普查的552,503人增加17.8%；過去五年澳門人口的年平均增長率為3.3%，高於2006至2011 年的1.9%。在澳門居住的外地僱員較五年前大幅增加68.8%至105,200人；而不包括外地僱員及外地學生的本地人口有536,400人，升幅為10.5%。] .footnote[Souce: http://www.dsec.gov.mo/Intercensos2016/SurveyRespondentsCorner/MechanismVisitWorkflow.aspx] There are about .violet[18%] of Macao population who work and live in Macao actually are not technically "Macao". Some additional questions: - How to identify .green[migrant worker] (外地僱員)? - What about those who .green[move across boarder everyday]? - What about those .green[Macau residents who live in Zhuhai]? --- ## The push/pull framework to understand the flow of people .orange[Push] factors might include: - Political persecution 政治迫害 - Economic depression 經濟不景氣 - War 戰爭 - Famine 饑荒 .orange[Pull] factors might include: - Favorable immigration policies 更優厚的移民政策 - Labor shortage 勞工短缺 - Similarities in culture and language 文化、語言的相同性 (i.e. colonial linkage) - Social networks (i.e. 同鄉會 an association of fellow provincials or townsmen) --- Many restrictions 限制 to migration still exist, motivations include: - Desire to retain labor so can compete in global markets - Influx of immigrants can cause local conflicts - Concerns about terrorism encourage or justify strict restrictions on flow - Diluting 稀釋 of identity Closely related to role of nation-state: .violet[limited & bounded, identifying "otherness"] --- ## Analysis: Singapore's immigration policy __Case:__ - English version: https://www.sbsgroup.com.sg/blog/revised-singapore-immigration-policies/ - Chinese version (slightly more detailed): http://bit.ly/2NieMyE __Questions to consider:__ - Who can immigrate? Why Singapore allows immigration - What are the benefits? - What are the push & pull factors? --- ## Push factors - Push factors are gender/class - specific - Not-ideal living conditions: + Environment too crowded + Housing too expensive + Environmental condition is bad - Access to better job markets (e.g. better pay & working environment) - Identify with foreign culture - Better education for children --- ## Pull factors - .violet[Aging population] 人口老齡化: shortage of young people - .violet[Skills shortage] 勞動技能短缺: highly skilled, entrepreneurship - .violet[Capital shortage] 資本短缺: seeking external funding or capable business man to boost economy - Talent recruitment - Social, economic, political benefits + More efficient governance + Less corruption + Less taxes - Ease of travel - Geographic location 地理位置 --- ## Labor migration >one who is forced or has chosen to search for work outside her/his home country by "push" and "pull" factors May be temporary or permanent: _ranging from weeks to years_ Mainly (in terms of sheer number) involves flow of .green[low] or .green[un-skilled work] and .green[undocumented] immigrants, but can also be highly skilled knowledge workers (small in number but highly compensated) Many barriers to flows still exist: - Economic cycle in hosting region - Religious difference - Domestic labor protection; Quota on foreign labor - Relationship among sending and hosting countries/regions --- ### A parallel process: "Low end globalization" 低端全球化 by Gordon Mathews .pull-left[ ![](https://www.hongkongfp.com/wp-content/uploads/2017/06/gordon-mathews_d.jpg) - mostly small merchants, construction workers, traders.. ] .pull-right[ ![](https://www.hongkongfp.com/wp-content/uploads/2017/12/000_Hkg9003972.jpg) ] --- ## Dynamics of labor migration .violet[Remittances] 匯款: accounts for significant share of sending countries' economy .violet[Diaspora] 移民社群: - The Turkish case. There are about 1.5 million people living in Germany holding Turkish citizenship. They represented very important political resources .red[2] Because many immigrant are entrepreneurs, scientists, social innovators, policy makers have been studying: Brain drain and Brain gain 人材外流 & 人材聚集. National government (such as Singapore) particularly concerns about attracting talented people: - "Brains are everywhere" .footnote[ [2] For more explanations: http://www.politico.eu/article/turks-abroad-play-pivotal-referendum-role-netherlands-erdogan-diaspora/] --- ## Forced migration .violet[Refugees] 難民: those forced to leave their homeland, or who leave involuntarily, because they fear for their safety .violet[Asylum seekers] 政治庇護: refugees who seek to remain in the country to which they flee Example: Syria refugee crisis http://www.syria-visualized.com/ --- ## Human trafficking > The recruitment and movement of people through force or coercion, for purposes of sexual exploitation or forced labor 700,000–2 million people trafficked/year Has increased dramatically since early 2000s Coordinated through transnational criminal networks Highly profitable "industry" --- ### Sex trafficking: - Victims used as sexual slaves or sold to pimp - Most common recruitment method is through deceitful job offer - Mostly women and girls, but also boys - Various tactics used to keep victims from running away - Must service up to 20–25 men/day ### Labor trafficking - Forced labor + domestic workers (see next slide) + fisherman ([a case of Taiwan](https://www.twreporter.org/topics/far-sea-fishing-investigative-report)) - Interactive table: http://got-data.blogspot.com/2014/03/cost-of-human-life-and-human.html --- background-image: url(https://cdn.theatlantic.com/assets/media/img/2017/05/02/WEL_Tizon_Lola_Lead_16X9/1920.jpg) background-size: contain background-position: top ### Further read: My family's slave .footnote[ Synopsis: 她與我們家人一起生活了五十六年。她帶大了我和我的兄弟姐妹，從早到晚做飯做清潔，從來沒有工資。十一歲的我，一個典型的美國孩子，意識到她其實是我們家的奴隸。 She lived with us for 56 years. She raised me and my siblings without pay. I was 11, a typical American kid, before I realized who she was. ] --- ## Tourists Those on the move as they want to be; travel for pleasure Nation-states facilitate some of these flows, but some barriers to movement exist and impact different groups and places unevenly: - [Chinese tourists in South Korea](https://theinitium.com/article/20170215-international-youke/) One of the structures that can either expedite or impede tourism is .violet[geopolitics] 地緣政治 --- background-image: url(https://d32kak7w9u5ewj.cloudfront.net/media/image/2017/02/a5c2869313f4438292a1703f038e578d.png?imageView2/1/w/1080/h/720/format/jpg) background-size: contain --- ## Tourism Growth facilitated by reduced costs in transportation, but still mainly restricted to elites & middle class in North Specialized forms developing, e.g. eco-tourism, adventure tourism, ethno-tourism Flows from developed to less developed countries can be for tourism but also economic, i.e. low-cost products and services (e.g. medical tourism): - Biggest destination for medical tourism in Asia: Thailand .red[3]. .footnote[ [3] Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3883860/ ] --- ## EDU Tourism ![:wscale 55%](./pic/edutourism.jpg) .footnote[Source: http://www.scmp.com/news/china/society/article/2107398/inside-us45-billion-business-education-tourism-latest-frontier] --- class: inverse, middle ### One last thing. Immigration at global scale begs one question eventually: # WHO AM I? Where should I be? Who can I trust? Who are my friends? --- ### Meet Greg Lam who is a popular YouTuber with the .yellow[Life Where I am From] project ![:wscale 60%](https://cdn.japantimes.2xx.jp/wp-content/uploads/2016/10/p9-st.-michel-lwif-a-20161024.jpg) - https://www.youtube.com/channel/UCqwxJts-6yF33rupyF_DCsA - Greg himself is we today call "multi-ethnicity": he is Chinese, Scottish, Spanish, Portuguese, Mayan --- ## Does racial/national identity matter? It sure does. But does it mean ".violet[they]" can nevern be ".violet[us]"? There are certainly many answers but one thing is clear: when we reach global interconnectedness, this question becomes more important than ever: - Social policy is constructed around identity - Identity politics is central to all political process around the world - Two extremes: .orange[transhumanism] 超人類主義 at one end and .orange[political tribes] 政治部落 at the other. --- # .red[Summary] Global people flows are not new but increasing and becoming more complex, multidirectional Whilst barriers impact flows of migrants, low-skilled migrants are most significantly impeded (i.e. "we want you but we don't want you forever") Nation-states have a significant role to play Flows of people have generally been treated very differently to political, economic, and technical flows Many barriers remain, some increasing, depending on type and direction of the flow of people --- ## Resources - Content is taken from Rizter & Dean, Chapter 10 - About identity + What is transhumanism? https://en.wikipedia.org/wiki/Transhumanism + What is political tribes? https://law.yale.edu/yls-today/news/professor-amy-chua-publishes-book-political-tribes + A middle ground? [Why anyone can be Chinese by Daniel Bell](https://www.wsj.com/articles/can-anyone-be-chinese-1500045078) - Gordon Mathews interview + English: http://bit.ly/2y6jj1S + Chinese: http://bit.ly/2OrCGMW + His book: _The World in Guangzhou: Africans and Other Foreigners in South China’s Global Marketplace_ 世界在廣州：南中國全球貿易市場中的非洲人和其他外國人 - My family's slave: Lola's story + English version: https://www.theatlantic.com/magazine/archive/2017/06/lolas-story/524490/ + Chinese version: https://mp.weixin.qq.com/s/d7_ygIwiabQfNbnLxQtgkg


{% extends "base.html" %} {% block title %}Edit user information{% endblock %} {% from "includes/_formHelper.html" import render_field %} {% block content %}
Username already in use


There are different types of triangles that exist. We'll be looking at 3 types of triangles in this app.
This application lets you know the type of triangle you are dealing with just by inputting the values of its length.
You simply input 3 separate figures into each box and click submit.
The results will show if your figures form either an equilateral triangle, an isosceles triangle,a scalene triangle or if the figures do not form a triangle
at
all.
Please input your figures inside the following boxes then click on submit.
*Note that only numbers will be accepted. DO NOT INPUT LETTERS,PUNCTUATION MARKS OR OTHER SYMBOLS.


Personal
Custom domains
Sleeps after 30 mins of inactivity
Free
Small team
Never sleeps
Multiple workers for more powerful apps
$150
Enterprise
Dedicated
Simple horizontal scalability
$400


{% extends 'base.html' %} {% block content %} Activity Recognition Welcome, {{name}} Logout
Are you sure you want to log-off?
Based on Python and OpenCV


TRIANGLE-TRACKER
What type of Triangle is this?.
Determine it for me
Enter a:
Enter b:
Enter c:
CHECK OUT
DESIGN BY STEPHEN OTIENO


{{ define "title" }} {{ end }} {{ define "body" }}
If you are interested in reserving this parcel, click “Reserve Now” button for any of the payment options. You will be redirected to our payment page to make the initial reservation payment. Downpayment amount does not include a ${{ $.Site.Params.default_doc_fee }} document preparation fee.
{{$feature.Description}}
{{ $info.title }} {{ if $info.phone }} - {{ $info.phone }} {{ end }}


Core Reference
Engage Core
RequireJS Path
'engage/engage_core'
Inherited object functions of the BackboneJS view, see http://backbonejs.org/#View
Added object functions and properties:
| Name | Parameters | Type | Description |
|---|---|---|---|
| log(value):void | value:String | function | function to log via the core cross browser |
| Event:EngageEvent | none | property | Returns the EngageEvent object prototype, the see EngageEvent Object for more information |
| trigger(event):void | event:EngageEvent | function | triggers an EngageEvent |
| on(event, handler, context):void | event:EngageEvent, handler:function, context:object | function | install an event handler on a EngageEvent |
| model:EngageModel | none | property | Returns the singleton engage model for this session, see EngageModel for more information's |
| getPluginPath(pluginName):String | pluginName:String | function | Returns the absolute path of a plugin by name. |
EngageEvent Object
| Name | Paramters | Type | Description |
|---|---|---|---|
| EngageEvent(name, description, type) | name:String, description:String, type:String | constructor | Create a new unbound EngageEvent, with a name, description and a type. For Example: var myEvent = new EngageEvent('play', 'plays the video', 'trigger') |
| getName:String | none | function | Gets the name |
| getDescription:String | none | function | Gets the description |
| getType:String | none | function | Gets the Type, can be a "handler", "trigger" or "both" |
| toString:String | none | function | Build a string that describes the event |
Engage Model
Inherited object functions of the BackboneJS model, see http://backbonejs.org/#Model, how to use BackboneJS models. This model is a global singleton object and can be used by each plugin to add new models which can be used by another plugin again.
No special functions are added, but the model is filled with some default data. This default data can be used by each plugin, which has a reference to the EngageModel.
| Property Name | Type | Description |
|---|---|---|
| pluginsInfo | Backbone Model | Contains Information's of each plugin |
| pluginModels | Backbone Collection | Contains the plugin models |
| urlParameters | Object | Contains the data of the URL parameters. |
Plugin Object
Each plugin must create and return a object with some properties which are set by the plugin itself. It is recommend to keep a reference to the object because some properties are set by the core after the plugin is processed.
| Property Name | Type | Description |
|---|---|---|
| name | String | Name of the plugin, e.g. "Engage Controls". This property is set by the plugin. |
| type | String | Type of the plugin, e.g. "engage_controls", see the plugin table in Architecture for the other plugin types. This property is set by the plugin. |
| version | String | Version of plugin. This property is set by the plugin. |
| styles | Array of Strings | Array of the paths of css files relative to the static folder of each plugin . This property is set by the plugin. |
| template | String | Before the plugin object is returned by the plugin logic, the template property contains the path to the template relative to the static folder. The path property is set first by the plugin. After the plugin object is returned and the Theodul core processed the plugin, the template property is filled with the real template data and can be used to re-render the view. |
| container | String | Contains the ID of the HTML div container, which contains the rendered template. This can be used to re-render the view. This property is set by the core. |
| pluginPath | String | Contains the absolute path of the plugin. This property is set by the core. |
| events | Object | Contains all events which are used of this plugin. Each handled and each triggered event. |


E.g.(1) If age is more than 16 they are allowed to drive
Else they aren't allowed
E.g.(2) If the password is the same as the correct password, allow access
Else don't allow access.


When youo work with us,you are part of the team of committed collaorators. All aspects of our software development process aare intergrated,interactive and agile. Our approach unifies design,development and product management to create excetional products. We start each project by understanding your business goals,the user's needs and the product requirements Then we will help translate them into efective and elegant solutions


ReactPhysics3D is an open source C++ physics engine library that can be used in 3D simulations and games. The library is released under the ZLib license.
The ReactPhysics3D library has the following features:
The ReactPhysics3D library is released under the open-source ZLib license. For more information, read the "LICENSE" file.
In order to build the library on your system, you first need to clone the code repository with
the following command:
git clone https://github.com/DanielChappuis/reactphysics3d.git
Note that the git versioning software needs to be installed on your system.
Then, you will need to build (compile) the library and install it on your system in order to
use it in your project. The best way is to use CMake for that. CMake will generate the
necessary files on your platform (Windows, OS X or Linux) to build the library.
CMake can be downloaded at http://www.cmake.org or using your package-management
program (apt, yum, …) on Linux. If you have never used CMake before, you should read the
page http://www.cmake.org/cmake/help/runningcmake.html as it contains a lot of
useful information.
The remaining of this section will describe how to build and install the library with
CMake.
Now we need to configure CMake to tell it what you want to build. Maybe you simply want to build the library in debug or release mode or maybe you also want to build the unit tests or the testbed application with demos. At the end of this step, CMake will generate the native build tool files on your platform that you will use to build the library. For instance, it can generate a Visual Studio solution on Windows, a XCode project on OS X or files for the make command on OS X or Linux.
First, we will see how to configure CMake and generate the native build tool files using the
CMake tool with the command line. First, you need to create a folder where you want to
build the library. Then go into that folder and run the following ccmake command:
ccmake <path_to_library_source>
where <path_to_library_source> must be replaced by the path to the
reactphysics3d/ folder of the repository you have cloned. It is the folder that contains the
CMakeLists.txt file of ReactPhysics3D. Running this command will launch the CMake
command line interface. Hit the ’c’ key to configure the project. There, you can
also change some predefined options (see section 4.4 for more details) and then,
hit the ’c’ key again to configure the build. Once you have set all the values as
you like, you can hit the ’g’ key to generate the native build tool files in the build
directory that you have created before. Finally, you can exit the CMake interface.
If your prefer, you can use the graphical user interface of CMake instead. To do
this, run the cmake-gui program. First, the program will ask you for the source
folder. You need to select the reactphysics3d/ folder of the repository you have
cloned. You will also have to select a folder where you want to build the library.
Select any empty folder that is on your system. Then, you can click on Configure.
CMake will ask you to choose an IDE that is on your system that will be used to
compile the library. For instance, you can select Visual Studio, Qt Creator, XCode, ...
Then, click on the Finish button. Then, you can change the compilation options.
See section 4.4 to see what are the possible options. Once this is done, click on
Configure again and finally on Generate as you can see in the following picture.
Now, if you go into the folder you have chosen to build the library, you should find the native build tool files that you will use to build the library on your platform.
Now, that you have generated the native build tool files on your system, you will need to build (compile) the library.
On Linux or Mac OS X, you can compile the library on the command line using the make
command. Go into the directory where you have generated the native build tool files and run
the following command:
make
The library will start compiling.
If you have generated the native build tool files in the previous step on Windows, you should have obtained a Visual Studio solution of ReactPhysics3D. Now, you can open the Visual Studio solution (.sln file). Once Visual Studio is open, you first need to change the compilation mode to Release at the top instead of Debug. Then, right click on the reactphysics project in the Solution Explorer and click on Build in order to compile the library (see the following picture).
The library will start compiling.
Now that you have compiled the library, you can install it on your system in order to put the compiled library file, the header files and the exported CMake targets in a standard location on your system so that it can be easily imported into your project.
On Linux or Mac OS X, you can use the make command to install the library. You simply
need to run the following command:
sudo make install
The library is now installed on your system. For instance, On Linux Ubuntu, the library may have been installed in the /usr/local/lib/ folder and the header files in the /usr/local/include/ folder.
In order to install the library on your system using Visual Studio, you need to open Visual
Studio with administrator rights. This is needed in order to have the correct rights to write the
files in the C:\Program Files (x86)\ folder on your computer for instance. To do that,
type Visual Studio in the Start Menu, when Visual Studio has been found, right click on it
and click on Run as administrator. This will open Visual Studio with administrator rights.
Then, you need to open the Visual Studio solution (.sln file) of ReactPhysics3D that has been generated previously with CMake. To do that, click on File in the top menu of Visual Studio, then on Open and Project/Solution.... Then, you need to select the ReactPhysics3D Visual Studio solution (.sln file) on your system. Once the solution is open, you first need to change the mode at the top to Release instead of Debug. Then, right click on the INSTALL project in the Solution Explorer menu and click on Build (see the following picture). This will install the ReactPhysics3D library in a standard location on your system like C:\Program Files (x86)\ReactPhysics3D\ for instance.
You can find below the different CMake options that you can set before building the library:
If you have built and installed the ReactPhysics3D on your system with CMake as explained in the section 4, it is easy to import the library in your project. You probably already have a CMakeLists.txt file for your project. Therefore, to import the ReactPhysics3D library, you simply need to add the following line in the CMakeLists.txt file of your project.
This will tell CMake to find the installed ReactPhysics3D library on your system and import the library file and headers so that you can link it to your project. Note that if you are working on Windows or Mac OS X, you might need to use the following code in your CMakeLists.txt file before calling the previous function. This will help CMake to find the installed ReactPhysics3D library on Windows or Mac OS X.
Then, you need to tell CMake that your project (executable) depends on ReactPhysics3D with the following line in your CMakeLists.txt file:
The ReactPhyscis3D repository contains a folder with an Hello World project here. In
this folder, you can find a CMakeLists.txt and a Main.cpp file that show how to import and
use the ReactPhysics3D library in a simple project.
Here is the example CMakeLists.txt file of the Hello World project:
Then in your C++ source file, you need to include the main ReactPhysics3D header file
with the following line:
Also note that all the classes of the library are available in the reactphysics3d
namespace or its shorter alias rp3d. Therefore, you can use this namespace in your code
with the following declaration:
Here is the Main.cpp file of the Hello World project:
The first thing you need to do when you want to use ReactPhysics3D is to instantiate the
PhysicsCommon class. This main object will then be used as a factory to instantiate one or
multiple physics worlds and other objects. This class is also responsible for the memory
management of the library. All the memory allocations are centralized into this
PhysicsCommon object. This class also contains the logger for the different events that can
occur.
In order to use ReactPhysics3D, you have to create an instance of the PhysicsCommon
class:
Then, you can use this object to instantiate a physics world for instance:
When you will need to add a body into your world, you will probably need to
create a collider with a given type of collision shape. Again, you will need to use the
PhysicsCommon object to instantiate a collision shape as in the following example:
As you can see, the PhysicsCommon object is the first thing you will need to instantiate in order to use ReactPhycsi3D in your code.
The PhysicsCommon class is responsible for all the memory allocations that occur in
ReactPhysics3D. The base memory allocations in ReactPhysics3D are done using the
std::malloc() and std::free() methods. If you want to use your own behavior to
allocate and free memory, you can pass a custom memory allocator to the constructor of the
PhysicsCommon object. You simply need to create a class that inherits from the
MemoryAllocator class of ReactPhysics3D and overrides the allocate() and release()
methods.
Note that several methods of ReactPhysics3D will create an instance of an
object and return a pointer so that you can use that object. This the case for the
creation of a PhysicsWorld or a RigidBody as you can see in the following code:
Note that because those objects have been instantiated by ReactPhysics3D and not by
you, the library is responsible to delete those objects. Therefore, you must not call the C++
delete operator on those objects. There are methods that you can call to destroy those
objects when you do not need them anymore to release memory but if you don’t do it, the
library will do it for you when the PhysicsCommon object is deleted. The following
example shows how to destroy previously created RigidBody and PhysicsWorld:
Once you have created a PhysicsCommon object (see section 6), you will have to create a
physics world. A physics world is a place where you can add the bodies that you want to
simulate. It is possible to create multiple physics worlds but you will probably never need
more than one.
There are two main ways to use ReactPhysics3D. The first one is to create bodies that
you have to manually move in the physics world and test for collision between
them or do some raycasting. To do this, you need to add some collision bodies
(class CollisionBody) in the world as described in section 9. In this case, the
physics engine will not be responsible to animate your bodies. You will have to move
the bodies manually by yourself because you are only interested in the collision
between your bodies. A possible use case for this could be an application where
the user has to place furniture in a room and you need to give the user some
feedback when the 3D shapes of the furniture are intersecting and therefore in
an invalid configuration. Here are some methods that use can use in this case:
The second way to use the library is to create bodies and let ReactPhysics3D animate their motions automatically using the laws of physics. This is done by creating rigid bodies (class RigidBody) in your physics world and by updating the simulation by calling the PhysicsWorld::update() method each frame. The rigid bodies will move according to the forces, collision between bodies and joint constraints of the physics world. A typical use case is a 3D real-time game for instance.
In order to create a physics world, you need to call the createPhysicsWorld() method of
the main PhysicsCommon object:
This method will return a pointer to the physics world that has been created.
When you create a physics world as in the previous example, it will have some
default settings. If you want to customize some settings, you need to create a
PhysicsWorld::WorldSettings object and give it in parameter when you create your
physics world as in the following example:
The settings are copied into the world at its creation. Therefore, changing the values of
your PhysicsWorld::WorldSettings instance after the world creation will not have any
effect. However, some methods are available to change settings after the world creation.
You can take a look at the API documentation to see what world settings can be changed in
the PhysicsWorld class.
ReactPhysics3D uses an iterative solver to simulate the contacts and joints. For contacts,
there is a unique velocity solver and for joints there is a velocity and a position solver. By
default, the number of iterations of the velocity solver is 10 and the number of iterations for
the position solver is 5. It is possible to change the number of iterations for both solvers.
To do this, you need to use the following two methods:
Increasing the number of iterations of the solvers will make the simulation more precise but also more expensive to compute. Therefore, you should change those values only if necessary.
The purpose of the sleeping technique is to deactivate resting bodies so that they are not
simulated anymore. This is used to save computation time because simulating many bodies
is costly. A sleeping body (or group of sleeping bodies) is awaken as soon as
another body collides with it or a joint in which it is involed is enabled. The sleeping
technique is enabled by default. You can disable it using the following method:
Note that it is not recommended to disable the sleeping technique because the
simulation might become slower. It is also possible to deactivate the sleeping technique on a
per body basis. See section 10.5 for more information.
A body is put to sleep when its linear and angular velocity stay under a given velocity threshold for a certain amount of time (one second by default). It is possible to change the linear and angular velocity thresholds using the two methods PhysicsWorld::setSleepLinearVelocity() and PhysicsWorld::setSleepAngularVelocity(). Note that the velocities must be specified in meters per second. You can also change the amount of time (in seconds) the velocity of a body needs to stay under the threshold to be considered sleeping. To do this, use the PhysicsWorld::setTimeBeforeSleep() method.
When the PhysicsWorld is used to animate the bodies through time according to the laws
of physics, the world has to be updated each time you want to simulate a step forward in
time (for instance each frame in a real-time simulation).
To update the physics world, you need to use the PhysicsWorld::update() method.
This method will perform collision detection and update the position and orientation of the
bodies according to the forces, joints constraints and collision contacts. Once you have
updated the world, you will be able to retrieve the new position and orientation of your
bodies in order to render the next frame. The PhysicsWorld::update() method requires a
timeStep parameter. This is the amount of time you want to advance the physics simulation
(in seconds).
The smaller the time step you pick, the more precise the simulation will be.
For a real-time application, you probably want to use a time step of at most
seconds to have at least a 60 Hz framerate. Most of the time, physics engines
prefer to work with a constant time step. It means that you should always call the
PhysicsWorld::update() method with the same time step parameter. You do not want to
use the exact time between two frames as your time step because it will not be constant.
You can use the following technique. First, you need to choose a constant time step.
Let say the time step is seconds. Then, at each frame, you compute the time
difference between the current frame and the previous one and you accumulate this
difference in a variable called accumulator. The accumulator is initialized to zero at the
beginning of your application and is updated at each frame. The idea is to divide
the time in the accumulator in several constant time steps. For instance, if your
accumulator contains 0.145 seconds, it means that we can take 8 physics steps of
seconds during the current frame. Note that 0.012 seconds will remain in the
accumulator and will probably be used in the next frame. As you can see, with
this technique, multiple physics steps can be taken at each frame. It is important
to understand that each call to the PhysicsWorld::update() method is done
using a constant time step that is not varying with the framerate of the application.
Here is what the code looks like at each frame:
If you want to know more about physics simulation time interpolation, you can read the nice article from Glenn Fiedler at https://gafferongames.com/post/fix_your_timestep/.
Sometimes, you might need to get the contacts information (contact point, normal,
penetration depth, …) that occurs in your physics world.
If you are using a physics world to only test for collisions (you never call the
PhysicsWorld::update() method), you can retrieve contacts information directly when you
call the PhysicsWorld::testCollision() group of methods. Those methods take a
pointer to a CollisionCallback class. You simply need to create a custom class that
inherits from this class and override the CollisionCallback::onContact() method. When
you call one of the PhysicsWorld::testCollision() methods, the onContact() method
of your class will be called with all the information about the contacts in parameters.
However, if you are using ReactPhysics3D for a real-time simulation by calling the PhysicsWorld::update() method each frame, you should use the EventLister class to retrieve contacts as described in section 15.
When you don’t need the physics world anymore, you can destroy it to release some
memory. When the physics world is destroyed, all the bodies that have been added into it
and that have not been destroyed already will be destroyed.
Note that the pointer to the physics world and all the objects that have been created inside it (bodies, colliders, …) will become invalid after this call.
Once you have created a physics world, it is time to add bodies into it. At this point, you will have to choose between the two types of bodies of ReactPhysics3D. You can create either a CollisionBody or a RigidBody. If you only want to add bodies into your world, move them manually and test if they collide without simulating their motion using the laws of physics, you can create bodies of type CollisionBody. However, if you want your bodies to be physically animated, you will need to use bodies of type RigidBody. The RigidBody class is described in section 10. The current section explains how to use a CollisionBody.
When you create a collision body, you need to specify its initial transform. This transform
describes the initial position and orientation of the body in the world. You need to create an
instance of the Transform class with a vector describing the initial position and a quaternion
for the initial orientation of the body.
You need to call the PhysicsWorld::createCollisionBody() method to create a
collision body in the physics world you have previously created. This method will
return a pointer to the instance of the CollisionBody object that has been created
internally. You will then be able to use that pointer to get or set values of the body.
The following code describes how to create a collision body in the physics world.
In order to test collision between your body and other bodies in the world, you probably want to add some colliders to your body. Take a look at section 11 to learn what is a collider and how to use it.
A collision body has to be moved manually in the world because it is not simulated by the
physics engine. In order to move it, you need to use the CollisionBody::setTransform()
method to set a new position and new orientation to the body.
In order to destroy a collision body, you need to use the PhysicsWorld::destroyCollisionBody()
method. You need to use the pointer to the body you want to destroy in argument. Note that
after calling this method, the pointer will not be valid anymore and therefore, you should not
use it.
The following code shows how to destroy a collision body:
Once the physics world has been created, you can add rigid bodies into it. A rigid body is an object that will be simulated using the laws of physics. It has a mass, a position, an orientation and one or several colliders. It will react to forces and collisions. The physics world will compute contacts between the bodies and will update their positions and orientations accordingly at each time step. You can also create joints between bodies to link them in different configurations. In ReactPhysics3D, the RigidBody class (which inherits from the CollisionBody class) is used to describe a rigid body.
In order to create a rigid body, you need to specify its transform. The transform describes
the initial position and orientation of the body in the world. You need to create an instance of
the Transform class with a vector describing the initial position and a quaternion for the
initial orientation of the body.
You have to call the PhysicsWorld::createRigidBody() method to create a rigid body
in the world. This method will return a pointer to the instance of the RigidBody object that
has been created internally. You will then be able to use that pointer to get or set values to
the body.
You can see in the following code how to create a rigid body in your world:
Once your rigid body has been created in the world, you will probably want to add it one or more colliders as described in section 11.
There are three types of bodies: static, kinematic and dynamic.
A static body has infinite mass, zero velocity but its position can be changed manually.
Moreover, a static body does not collide with other static or kinematic bodies.
On the other side, a kinematic body has infinite mass, its velocity can be changed
manually and its position is computed by the physics engine. A kinematic body does not
collide with other static or kinematic bodies.
Finally, A dynamic body has non-zero mass, non-zero velocity determined by forces and
its position is determined by the physics engine. Moreover, a dynamic body can collide with
other dynamic, static or kinematic bodies.
For instance, you can use a static body for the floor, a kinematic body for a moving
platform and a dynamic body for a rock that could fall on the floor.
When you create a new body in the world, it is of dynamic type by default. You
can change the type of the body using the RigidBody::setType() method as
follows:
By default, all the rigid bodies with react to the gravity force of the world. If you do
not want the gravity to be applied to a given body, you can disable it using the
RigidBody::enableGravity() method as in the following example:
Damping is the effect of reducing the velocity of the rigid body during the simulation to simulate effects like air friction for instance. By default, no damping is applied. However, you can choose to damp the linear or/and the angular velocity of a rigid body. For instance, without angular damping a pendulum will never come to rest. You need to use the RigidBody::setLinearDamping() and RigidBody::setAngularDamping() methods to change the damping values. The damping value has to be positive and a value of zero means no damping at all.
As described in section 8.2.2, the sleeping technique is used to disable the simulation of
resting bodies. By default, the bodies are allowed to sleep when they come to
rest. However, if you do not want a given body to be put to sleep, you can use the
RigidBody::setIsAllowedToSleep() method as in the next example:
During the simulation, you can apply a force or a torque to a given rigid body.
This force can be applied to the center of mass of the rigid body by using the
RigidBody::applyForceToCenterOfMass() method. You need to specify the force
vector (in Newton) as a parameter. If the force is applied to the center of mass,
no torque will be created and only the linear motion of the body will be affected.
You can also apply a force to any given point in world-space using the
RigidBody::applyForceAtWorldPosition() method or in local-space with the
RigidBody::applyForceAtLocalPosition() method. You need to specify the
force vector (in Newton) and the point where to apply the given force. Note that
if the point is not the center of mass of the body, applying a force will generate
some torque and therefore, the angular motion of the body will be affected as well.
It is also possible to apply a torque to a given body using the RigidBody::applyTorque()
method. You simply need to specify the torque vector (in Newton ⋅ meter) as in the following
example:
Note that when you call the previous methods, the specified force/torque will be added to the total force/torque applied to the rigid body and that at the end of each call to the PhysicsWorld::update(), the total force/torque of all the rigid bodies will be reset to zero. Therefore, you need to call the previous methods during several frames if you want the force/torque to be applied during a certain amount of time.
When you call the PhysicsWorld::update() method, the bodies positions and orientations
are updated to satisfy the contacts and joints constraint between the bodies. After calling
this method, you can retrieve the updated position and orientation of each body to render it.
To do that, you simply need to use the RigidBody::getTransform() method to get the
updated transform. This transform represents the current local-to-world-space transform of
the body.
As described in section 8.3, at the end of a frame, there might still be some remaining
time in the time accumulator. Therefore, you should not use the updated transform directly
for rendering but you need to perform some interpolation between the updated transform
and the one from the previous frame to get a smooth real-time simulation. First, you need to
compute the interpolation factor as folows:
Then, you can use the Transform::interpolateTransforms() method to compute the
linearly interpolated transform:
The following code is the one from section 8.3 for the physics simulation loop but with the
update of a given rigid body.
If you need the array with the corresponding 4 × 4 OpenGL transformation matrix for
rendering, you can use the Transform::getOpenGLMatrix() method as in the following
code:
A nice article to read about this time interpolation is the one from Glenn Fiedler at https://gafferongames.com/post/fix_your_timestep/.
The mass, center of mass and inertia tensor of a rigid body are important parameters for the physical simulation of a rigid body.
The RigidBody has a mass value (in kilograms) which is 1 kilogram by default. There are two ways to set the mass of a rigid body. First, you can set it directly using the RigidBody::setMass() method. Secondly, it is also possible to compute this mass automatically using the mass of the colliders of the rigid body. As described in section 11.3, the material of each collider has a mass density value. This value is 1 by default. You change change the mass density value of the colliders of a rigid body and then use the RigidBody::updateMassFromColliders() method to automatically compute the mass of the rigid body using the mass density and shape of its colliders. Note that you will need to call this method again if you add another collider to the rigid body.
The center of mass of a RigidBody is the mean location of the distribution of mass of the body in space. By default the center of mass of the rigid body is located at its origin. There are two ways to set the center of mass of a rigid body. First, you can set it directly using the RigidBody::setLocalCenterOfMass() method. Secondly, as for the mass, the center of mass can also be computed automatically using the mass, shape and transform of all the colliders of the rigid body. As described in section 11.3, the material of each collider has a mass density value. This value is 1 by default. You can set the mass density value of the colliders and then use the RigidBody::updateLocalCenterOfMassFromColliders() method to automatically compute the center of mass of the rigid body. Note that you will need to call this method again if you add another collider to the rigid body.
The inertia tensor of a RigidBody is a 3 × 3 matrix describing how the mass is distributed inside the rigid body which is used to calculate its rotation. The inertia tensor depends on the mass and the shape of the body. By default the local inertia tensor of a rigid body is the identity matrix. There are two ways to set the inertia tensor of a rigid body. First, you can set it directly using the RigidBody::setLocalInertiaTensor() method. Note that this will set the inertia tensor of the body in local-space coordinates which is usually a diagonal matrix. This method takes a Vector3 with the three diagonal entries of the matrix. Secondly, the local inertia tensor can be computed automatically using the mass density, shape and transform of all the colliders of the body. As described in section 11.3, the material of each collider has a mass density value which is 1 by default. You can set the mass density value of the colliders and then use the RigidBody::updateLocalInertiaTensorFromColliders() method to automatically compute the local inertia tensor of the body. Note that you will need to call this method again if you add another collider to the rigid body.
Note that it is also possible to automatically compute the mass, center of mass and inertia tensor of a rigid body at the same time using the RigidBody::updateMassPropertiesFromColliders().
It is really simple to destroy a rigid body when you don’t need it anymore. You simply need to
use the PhysicsWorld::destroyRigidBody() method. You need to use the pointer to the
body you want to destroy as a parameter. Note that after calling that method, the pointer will
not be valid anymore and therefore, you should not use it. When you destroy a rigid
body that was part of a joint, that joint will be automatically destroyed as well.
Here is how to destroy a rigid body:
A body can only collide against an other body if it has at least one collider. A collider (class
Collider) describes the collision shape of the body. A body can have multiple colliders
attached to it. When adding a collider to a body, you need to specify its collision
shape (box, sphere, capsule, …) and its transform relative to the origin of the body.
Before adding a collider to a body, you need to create a collision shape. A collision
shape can be instantiated by calling a method of the main PhysicsCommon object.
The following example shows how instantiate a collision shape (a sphere shape)
from the PhysicsCommon object and use it to add a new collider to a rigid body.
Note that a given collision shape instance can be shared between multiple colliders. The next section presents the different types of collision shapes that are available in ReactPhysics3D.
As we have just seen, a collision shape is used to describe the shape of a collider for collision detection. They are many types of collision shapes that you can use. They all inherit from the CollisionShape class.
The BoxShape class describes a box collision shape centered at the origin of the collider.
The box is aligned with the shape local X, Y and Z axis. In order to create a box shape, you
only need to specify the three half extents dimensions of the box in the three X, Y and Z
directions.
For instance, if you want to create a box shape with dimensions of 4 meters, 6 meters
and 10 meters along the X, Y and Z axis respectively, you need to use the following code:
The SphereShape class describes a sphere collision shape centered at the
origin of the collider. You only need to specify the radius of the sphere to create it.
For instance, if you want to create a sphere shape with a radius of 2 meters, you need to
use the following code:
The CapsuleShape class describes a capsule collision shape around the local Y axis
and centered at the origin of the collider. It is the convex hull of two spheres. It can also be
seen as an elongated sphere. In order to create it, you only need to specify the radius of the
two spheres and the height of the capsule (distance between the centers of the two
spheres).
For instance, if you want to create a capsule shape with a radius of 1 meter and the
height of 2 meters, you need to use the following code:
The ConvexMeshShape class can be used to describe the shape of a convex mesh centered
at the origin of the collider.  You also need to have an
array with the vertices coordinates and an array with the vertex indices of each face of you
mesh. Then, you have to create a PolygonVertexArray with your vertices coordinates and
indices array. You also need to specify your array of PolygonFace. Then, you have to create
a PolyhedronMesh with your PolygonVertexArray. Once this is done, you can
create the ConvexMeshShape by passing your PolyhedronMesh in parameter.
The following example shows how to create a convex mesh shape. In this example, we
create a cube as a convex mesh shape. Of course, this is only for the example. If
you really need a cube collision shape, you should use the BoxShape instead.
Note that the vertex coordinates and indices array are not copied and therefore you need
to make sure that they exist until the collision shape exists. This is also true for the all
the PolygonFace, the PolygonVertexArray and the PolyhedronMesh objects.
You need to make sure that the mesh you provide is indeed convex. Secondly, you
should provide the simplest possible convex mesh. It means that you need to avoid coplanar
faces in your convex mesh shape. Coplanar faces have to be merged together. Remember
that convex meshes are not limited to triangular faces, you can create faces with more than
three vertices.
When you specify the vertices for each face of your convex mesh, be careful with their
order. The vertices of a face must be specified in counter clockwise order as seen from the
outside of your convex mesh.
You also need to make sure that the origin of your mesh is inside the convex mesh. A
mesh with an origin outside the convex mesh is not currently supported by the library.
You can also specify a scaling factor in the PhysicsCommon::createConvexMeshShape()
method when you create a ConvexMeshShape. All the vertices of your mesh will be scaled
from the origin by this factor when used in the collision shape. It means that you can use the
same PolyhedronMesh for multiple ConvexMeshShape with a different scaling factor each
time.
Note that collision detection with a ConvexMeshShape is more expensive than with a
SphereShape or a CapsuleShape.
The ConcaveMeshShape class can be used for a static concave triangular mesh. It can
be used to describe an environment for instance. Note that it cannot be used with a dynamic
body that is allowed to move. Moreover, make sure to use a ConcaveMeshShape only when
you are not able to use a convex shape and also try to limit the number of triangles of that
mesh because collision detection with ConcaveMeshShape is quite expensive compared to
convex shapes.
In order to create a concave mesh shape, you need to supply a pointer to a
TriangleMesh. A TriangleMesh class describes a mesh made of triangles. It may
contain several parts (submeshes). Each part is a set of triangles represented by a
TriangleVertexArray object. A TriangleVertexArray represents a continuous array of
vertices and indexes for a triangular mesh. When you create a TriangleVertexArray, no
data is copied into the array. It only stores a pointer to the data. The idea is to allow the user
to share vertices data between the physics engine and the rendering part. Therefore, make
sure that the data pointed by a TriangleVertexArray remains valid during the whole
TriangleVertexArray life.
The following code shows how to create a TriangleVertexArray:
Now that we have a TriangleVertexArray, we need to create a TriangleMesh and
add the TriangleVertexArray into it as a subpart. Once this is done, we can create the
actual ConcaveMeshShape.
Note that the TriangleMesh object also needs to exist during the whole life of the
collision shape because its data is not copied into the collision shape.
When you specify the vertices for each triangle face of your mesh, be careful with the
order of the vertices. They must be specified in counter clockwise order as seen from the
outside of your mesh.
You can also specify a scaling factor in the PhysicsCommon::createConcaveMeshShape()
method when you create a ConcaveMeshShape. All the vertices of your mesh will be scaled
from the origin by this factor when used in the collision shape. It means that you can use the
same TriangleMesh for multiple ConcaveMeshShape with a different scaling factor each
time.
In the previous example, the vertex normals that are needed for collision detection are
automatically computed. However, if you want to specify your own vertex normals, you can
do it by using another constructor for the TriangleVertexArray.
The HeightFieldShape is a collision shape that can be used to represent a static terrain
for instance. You can define a heightfield with a two dimensional grid that has a given height
value at each point.
In order to create a HeightFieldShape, you need to have an array with all the height
values of your field. You can have height values of type int, float or double. You
need to give the number of rows and columns of your two dimensional grid. Note
that the height values in your array must be organized such that the value at row
indexRow and column indexColumn is located at the following position in the array:
Moreover, you need to provide the minimum and maximum height values of your height
field.
Here is an example that shows how to create a HeightFieldShape:
Note that the array of height values are not copied into the HeightFieldShape.
Therefore, you need to make sure they exist during the lifetime of the HeightFieldShape
and you must not forget to release their memory when you destroy the collision shape or at
the end of your application.
You can also specify a scaling factor in the PhysicsCommon::createHeightShape()
method when you create a HeightFieldShape. All the vertices of your mesh will be scaled
from the origin by this factor when used in the collision shape.
When creating a HeightFieldShape, the origin of the shape will be at the center of its bounding volume. Therefore, if you create a HeightFieldShape with a minimum height of 100 and a maximum height of 500, the maximum coordinates of the shape on the Y axis will be 200 and the minimum coordinates will be -200.
By default all the colliders of the bodies are able to collide with each other in the world.
However, sometimes we want a body to collide only with a given group of bodies and not
with other bodies. This is called collision filtering. The idea is to group the colliders of bodies
into categories. Then we can specify for each collider against which categories of colliders it
will be able to collide.
ReactPhysics3D uses bits masks to represent categories. The first thing to do is to
assign a category to the colliders of your body. To do this, you need to call the
Collider::setCollisionCategoryBits() method on the corresponding collider as in the
following example. Here we consider that we have four bodies where each one has a single
collider.
As you can see, the collider of body 1 will be part of the category 1, the collider of body 2
will be part of the category 2 and the colliders of bodies 3 and 4 will be part of the category
3.
Now, for each collider, we need to specify with which categories it is allowed to collide
with. To do this, you need to use the Collider::setCollideWithMaskBits() method.
Note that you can specify one or more categories using the bitwise OR operator. The
following example shows how to specify with which categories the collider can collide.
As you can see, we specify that the body 1 will be allowed to collide with bodies from the
categorie 3. We also indicate that the body 2 will be allowed to collide with bodies
from the category 1 and 3 (using the bitwise OR operator). Finally, we specify
that bodies 3 and 4 will be allowed to collide against bodies of the category 2.
A collider is able to collide with another only if you have specify that the category mask of
the first collider is part of the collide with mask of the second collider. It is also important to
understand that this condition must be satisfied in both directions. For instance
in the previous example, the body 1 (of category 1) says that it wants to collide
against bodies of the category 3 (for instance against body 3). However, body 1 and
body 3 will not be able to collide because the body 3 does not say that it wants to
collide with bodies from category 1. Therefore, in the previous example, the body
2 is allowed to collide against bodies 3 and 4 but no other collision is allowed.
In the same way, you can perform this filtering for ray casting (described in section 13). For instance, you can perform a ray cast test against a given subset of categories of colliders only.
The material of a rigid body is used to describe the physical properties it is made of. This is
represented by the Material class. Each body that you create will have a default material.
You can get the material of the rigid body using the RigidBody::getMaterial() method.
You can use the material to set those physical properties.
For instance, you can change the bounciness of the rigid body. The bounciness is a
value between 0 and 1. The value 1 is used for a very bouncy object and the value 0 means
that the body will not be bouncy at all. To change the bounciness of the material, you can
use the Material::setBounciness() method.
It is also possible to set the mass density of the collider which has a default value of 1.
As described in section 10.8, the mass density of a collider can be used to automatically
compute the mass, center of mass and inertia tensor of a rigid body. In order to change the
mass density of a collider, you need to use the Material::setMassDensity() method.
You are also able to change the friction coefficient of the body. This value needs to be
between 0 and 1. If the value is 0, no friction will be applied when the body is in contact with
another body. However, if the value is 1, the friction force will be high. You can change the
friction coefficient of the material with the Material::setFrictionCoefficient() method.
You can use the material to add rolling resistance to a rigid body. Rolling resistance can
be used to stop a rolling object on a flat surface for instance. You should use this only with
SphereShape or CapsuleShape collision shapes. By default, rolling resistance is zero but
you can set a positive value using the Material::setRollingResistance() method to
increase resistance.
Here is how to get the material of a rigid body and how to modify some of its properties:
A trigger, is a collider that cannot collide with any other colliders but can only report when it
is overlapping with another collider. For instance, consider a game where a player moves
around and has to avoid touching some bombs. The player has a rigid body with a capsule
collider for instance and the bombs are rigid bodies where each one has a sphere collider.
Now, you do not want the player to bump against the bombs but you only want to know when
the collider of the player rigid body overlaps with a collider of a bomb. In this case, you can
set bombs colliders as being triggers. In this case, no rigid bodies in the world will
be able to collide against the bombs colliders but you can receive notifications
when a collider (the player body collider for instance) overlaps a bomb collider.
Therefore, you can use this to know when the player touches a bomb of the world.
To set a collider as being a trigger, you need to use the Collider::setIsTrigger()
method as in the following example:
The section 15.2 describes how to use the EventListener class to receive notifications when colliders overlap with some triggers.
Joints are used to constrain the motion of the rigid bodies between each other. A single joint
represents a constraint between two rigid bodies. When the motion of the first
body of the joint is known, the relative motion of the second body has at most six
degrees of freedom (three for the translation and three for the rotation). The different
joints can reduce the number of degrees of freedom between two rigid bodies.
Some joints have limits to control the range of motion and some joints have motors to
automatically move the bodies of the joint at a given speed.
The BallAndSocketJoint class describes a ball and socket joint between two bodies. In a
ball and socket joint, the two bodies cannot translate with respect to each other.
However, they can rotate freely around a common anchor point. This joint has three
degrees of freedom and can be used to simulate a chain of bodies for instance.
In order to create a ball and socket joint, you first need to create an instance of the
BallAndSocketJointInfo class with the necessary information. You need to provide the
pointers to the two rigid bodies and also the coordinates of the anchor point (in
world-space). At the joint creation, the world-space anchor point will be converted into the
local-space of the two rigid bodies and then, the joint will make sure that the two local-space
anchor points match in world-space. Therefore, the two bodies need to be in a correct
position at the joint creation.
Here is the code to create the BallAndSocketJointInfo object:
Now, it is time to create the actual joint in the physics world using the
PhysicsWorld::createJoint() method. Note that this method will also return a pointer to
the BallAndSocketJoint object that has been created internally. You will then be able to
use that pointer to change properties of the joint and also to destroy it at the end.
Here is how to create the joint in the world:
The HingeJoint class describes a hinge joint (or revolute joint) between two rigid bodies.
The hinge joint only allows rotation around an anchor point and around a single axis (the
hinge axis). This joint can be used to simulate doors or pendulums for instance.
In order to create a hinge joint, you first need to create a HingeJointInfo object with
the necessary information. You need to provide the pointers to the two rigid bodies, the
coordinates of the anchor point (in world-space) and also the hinge rotation axis (in
world-space). The two bodies need to be in a correct position when the joint is created.
Here is the code to create the HingeJointInfo object:
Now, it is time to create the actual joint in the physics world using the
PhysicsWorld::createJoint() method. Note that this method will also return a pointer to
the HingeJoint object that has been created internally. You will then be able to use
that pointer to change properties of the joint and also to destroy it at the end.
Here is how to create the joint in the world:
With the hinge joint, you can constrain the motion range using limits. The limits of the hinge
joint are the minimum and maximum angle of rotation allowed with respect to the initial
angle between the bodies when the joint is created. The limits are disabled by default. If you
want to use the limits, you first need to enable them by setting the isLimitEnabled variable
of the HingeJointInfo object to true before you create the joint. You also have to specify
the minimum and maximum limit angles (in radians) using the minAngleLimit and
maxAngleLimit variables of the joint info object. Note that the minimum limit angle must be
in the range [-2π; 0] and the maximum limit angle must be in the range [0; 2π].
For instance, here is the way to use the limits for a hinge joint when the joint is created:
It is also possible to use the HingeJoint::enableLimit(), HingeJoint::setMinAngleLimit() and HingeJoint::setMaxAngleLimit() methods to specify the limits of the joint after its creation. See the API documentation for more information.
A motor is also available for the hinge joint. It can be used to rotate the bodies around the
hinge axis at a given angular speed and such that the torque applied to rotate the bodies
does not exceed a maximum allowed torque. The motor is disabled by default. If you want to
use it, you first have to activate it using the isMotorEnabled boolean variable of the
HingeJointInfo object before you create the joint. Then, you need to specify the angular
motor speed (in radians/seconds) using the motorSpeed variable and also the
maximum allowed torque (in Newton ⋅ meters) with the maxMotorTorque variable.
For instance, here is how to enable the motor of the hinge joint when the joint is created:
It is also possible to use the HingeJoint::enableMotor(), HingeJoint::setMotorSpeed() and HingeJoint::setMaxMotorTorque() methods to enable the motor of the joint after its creation. See the API documentation for more information.
The SliderJoint class describes a slider joint (or prismatic joint) that only allows relative
translation along a single direction. It has a single degree of freedom and allows no relative
rotation. In order to create a slider joint, you first need to specify the anchor point (in
world-space) and the slider axis direction (in world-space). The constructor of the
SliderJointInfo object needs two pointers to the bodies of the joint, the anchor point and
the axis direction. Note that the two bodies have to be in a correct initial position when the
joint is created.
You can see in the following code how to specify the information to create a slider joint:
Now, it is possible to create the actual joint in the physics world using the
PhysicsWorld::createJoint() method. Note that this method will also return a pointer to
the SliderJoint object that has been created internally. You will then be able to use
that pointer to change properties of the joint and also to destroy it at the end.
Here is how to create the joint in the world:
It is also possible to control the range of the slider joint motion using limits. The limits are
disabled by default. In order to use the limits when the joint is created, you first need to
activate them using the isLimitEnabled variable of the SliderJointInfo class. Then, you
need to specify the minimum and maximum translation limits (in meters) using the
minTranslationLimit and maxTranslationLimit variables. Note that the initial position of
the two bodies when the joint is created corresponds to a translation of zero. Therefore, the
minimum limit must be smaller or equal to zero and the maximum limit must be larger or
equal to zero.
You can see in the following example how to set the limits when the slider joint is
created:
You can also use the SliderJoint::enableLimit(), SliderJoint::setMinTranslationLimit() and SliderJoint::setMaxTranslationLimit() methods to enable the limits of the joint after its creation. See the API documentation for more information.
The slider joint also has a motor. You can use it to translate the bodies along the slider axis
at a given linear speed and such that the force applied to move the bodies does not exceed
a maximum allowed force. The motor is disabled by default. If you want to use it when the
joint is created, you first have to activate it using the isMotorEnabled boolean variable of
the SliderJointInfo object before you create the joint. Then, you need to specify
the linear motor speed (in meters/seconds) using the motorSpeed variable and
also the maximum allowed force (in Newtons) with the maxMotorForce variable.
For instance, here is how to enable the motor of the slider joint when the joint is created:
It is also possible to use the SliderJoint::enableMotor(), SliderJoint::setMotorSpeed() and SliderJoint::setMaxMotorForce() methods to enable the motor of the joint after its creation. See the API documentation for more information.
The FixedJoint class describes a fixed joint between two bodies. In a fixed joint, there is
no degree of freedom, the bodies are not allowed to translate or rotate with respect to each
other. In order to create a fixed joint, you simply need to specify an anchor point (in
world-space) to create the FixedJointInfo object.
For instance, here is how to create the joint info object for a fixed joint:
Now, it is possible to create the actual joint in the physics world using the
PhysicsWorld::createJoint() method. Note that this method will also return a pointer to
the FixedJoint object that has been created internally. You will then be able to use
that pointer to change properties of the joint and also to destroy it at the end.
Here is how to create the joint in the world:
By default, the two bodies involved in a joint are able to collide with each other. However, it is
possible to disable the collision between the two bodies that are part of the joint. To do it,
you simply need to set the variable isCollisionEnabled of the joint info object to false
when you create the joint.
For instance, when you create a HingeJointInfo object in order to construct a hinge
joint, you can disable the collision between the two bodies of the joint as in the following
example:
In order to destroy a joint, you simply need to call the PhysicsWorld::destroyJoint()
method using the pointer to a previously created joint object as argument as shown in the
following code:
It is important that you destroy all the joints that you have created at the end of the simulation. Also note that destroying a rigid body involved in a joint will automatically destroy that joint.
You can use ReactPhysics3D to test intersection between a ray and the bodies of the world
you have created. Ray casting can be performed against multiple bodies, a single body or
any collider of a given body. Note that ray casting only works from the outside of the
bodies. If the origin of a ray is inside a collision shape, no hit will be reported.
The first thing you need to do is to create a ray using the Ray class of ReactPhysics3D.
As you can see in the following example, this is very easy. You simply need to specify the
point where the ray starts and the point where the ray ends (in world-space coordinates).
Any ray casting test that will be described in the following sections returns a
RaycastInfo object in case of intersection with the ray. This structure contains the following
attributes:
Note that you can also use collision filtering with ray casting in order to only test ray intersection with specific colliders. Collision filtering is described in section 11.2.
This section describes how to get all the colliders of all bodies in the world that are intersected by a given ray.
First, you have to implement your own class that inherits from the RaycastCallback class.
Then, you need to override the RaycastCallback::notifyRaycastHit() method in your
own class. An instance of your class have to be provided as a parameter of the raycast
method and the notifyRaycastHit() method will be called for each collider that is hit by
the ray. You will receive, as a parameter of this method, a RaycastInfo object that will
contain the information about the raycast hit (hit point, hit surface normal, hit body, hit
collider, …).
In your notifyRaycastHit() method, you need to return a fraction value that will
specify the continuation of the ray cast after a hit. The return value is the next maxFraction
value to use. If you return a fraction of 0.0, it means that the raycast should terminate. If you
return a fraction of 1.0, it indicates that the ray is not clipped and the ray cast should
continue as if no hit occurred. If you return the fraction in the parameter (hitFraction value in
the RaycastInfo object), the current ray will be clipped to this fraction in the next queries. If
you return -1.0, it will ignore this collider and continue the ray cast. Note that no assumption
can be done about the order of the calls of the notifyRaycastHit() method.
Here is an example about creating your own raycast callback class that inherits from the
RaycastCallback class and how to override the notifyRaycastHit() method:
Now that you have your own raycast callback class, you can use the PhysicsWorld::raycast()
method to perform a ray casting test on a physics world.
The first parameter of this method is a reference to the Ray object representing the ray you
need to test intersection with. The second parameter is a pointer to the object of your
raycast callback object. You can specify an optional third parameter which is the bit mask for
collision filtering. It can be used to raycast only against selected categories of colliders as
described in section 11.2.
You can also perform ray casting against a single specific collision body or rigid body of
the world. To do this, you need to use the CollisionBody::raycast() method.
This method takes two parameters. The first one is a reference to the Ray object
and the second one is a reference to the RaycastInfo object that will contain hit
information if the ray hits the body. This method returns true if the ray hits the body. The
RaycastInfo object will only be valid if the returned value is true (a hit occured).
The following example shows how test ray intersection with a body:
You can also perform ray casting against a single specific collider of a collision body or rigid
body of the world. To do this, you need to use the Collider::raycast() method of the
given collider. This method takes two parameters. The first one is a reference to the Ray
object and the second one is a reference to the RaycastInfo object that will contain hit
information if the ray hits the body. This method returns true if the ray hits the body. The
RaycastInfo object will only be valid if the returned value is true (a hit occured).
The following example shows how to test ray intersection with a given collider:
The testbed application contains a graphical interface where you can select and see
several demo scenes using the ReactPhysics3D library.
As described in section 4, you can enable a CMake option to build the testbed
application when you build the library. Note that OpenGL is required to compile it.
The testbed application can be found in the testbed/ folder of the ReactPhysics3D
library. Do not hesitate to take a look at the code of the demo scenes to better understand
how to use the library in your application.
The following subsections describe the demo scenes that can be found in the testbed application.
In this scene, you will see how to create a floor and some cubes using the Box Shape for collision detection. Because of gravity, the cubes will fall down on the floor. After falling down, the cubes will come to rest and start sleeping (become inactive). In this scene, the cubes will become red as they get inactive (sleeping).
This scene has a physics world and a pyramid of cubes.
In this scene, you will learn how to create different joints (ball and socket, hinge, slider, fixed) into the physics world. You can also see how to set the motor or limits of the joints.
In this scene, you will see how to create a floor (using the Box Shape) and some other bodies using the different collision shapes available in the ReactPhysics3D library like capsules, spheres, boxes and convex meshes. Those bodies will fall down to the floor.
In this scene, you will see how to use the Height field collision shape of the library. Several bodies will fall down to the height field.
In this scene, you will see how to use the ray casting methods of the library. Several rays are thrown against the different collision shapes. It is possible to switch from a collision shape to another using the spacebar key.
This scene has a physics world and several collision bodies that can be move around with keyboard keys. This scene shows how to manually compute collision detection in a physics world.
In this scene, you will see how to use the static concave mesh collision shape of the library.
This demo is basically a pile of many bodies with different types of shapes.
Sometimes, you want to receive notifications from the physics engine when a given event
occurs. The EventListener class can be used for that purpose. In order to use it,
you need to create a new class that inherits from the EventListener class and
overrides some methods that will be called by the ReactPhysics3D library when some
events occur. You also need to register your class in the physics world using the
PhysicsWorld::setEventListener() as in the following code:
The EventListener contains a onContact() method. If you override this method
in your custom event listener class, this method will be called when you call the
PhysicsWorld::update() method if there are contacts to report during the current update.
The onContact() method will be called with a CollisionCallback::CallbackData object
in parameter. This object has a getNbContactPairs() and a getContactPair() methods
that will allow you to get each contact pair (class CollisionCallback::ContactPair) that
occured during the physics world update. Note that a contact pair contains a list of
contact points between two bodies. Once you get a contact pair, you can use the
getBody1() or getBody2() methods to get the bodies in contact, you can use the
getCollider1() or getCollider2() methods to get the colliders in contact and the
getNbContactPoints() and getContactPoint() methods to get the contact points (class
CollisionCallback::ContactPoint) of the contact pair. Note that the onContact()
method will report contacts after the collision detection phase and before the contact
resolution.
The contact pair also has a getEventType() method that gives information about the type
of contact event for the pair. It can be ContactStart if the two bodies of the contact pair
where not colliding in the previous call to PhysicsWorld::update() and are now colliding.
It can be ContactStay, if the two bodies where colliding in the previous frame and are still
colliding or it can be ContactExit if the two bodies where colliding in the previous frame but
are not colliding anymore. Note that in this last situation, there will be no contact points in
the contact pair.
In the following example, you can see how to override the EventListener::onContact()
method to get the current contact points of the physics world:
As described in section 11.4 it is possible to set a collider as being a trigger. You can do this
if you do not want any collision with this collider but you are only interested in knowing when
another collider enters or exit the volume of the collider. If you do this, you will need to
override the onTrigger() method of the EventListener. This method will be called and
report all the collision with your triggers when you call the PhysicsWorld::update()
method.
The onTrigger() method will be called with an OverlapCallback::CallbackData
object in parameter. This object has a getNbOverlappingPairs() and a
getOverlappingPair() methods that will allow you to get each overlapping pair (class
OverlapCallback::OverlapPair) that occured during the physics world update. Once you
get an overlapping pair, you can use the getBody1() or getBody2() methods to get
the bodies in contact and the getCollider1() or getCollider2() methods to
get the trigger colliders in contact. Note that the onTrigger() method will report
overlaping triggers after the collision detection phase and before the contact resolution.
The overlapping pair also has a getEventType() method that gives information about the type of overlapping event for the pair. It can be OverlapStart if the two bodies of the pair where not overlapping in the previous call to PhysicsWorld::update() and are now overlapping. It can be OverlapStay, if the two bodies where overlapping in the previous frame and are still overlapping or it can be OverlapExit if the two bodies where overlapping in the previous frame but are not overlapping anymore.
Note that the onTrigger() method is only called for colliders that you have set as triggers using the Collider::setIsTrigger() method.
If you build the library with the RP3D_PROFILING_ENABLED variable enabled (see section
4.4), a real-time profiler will collect information while the application is running. Then, at the
end of your application, when the destructor of the PhysicsWorld class is called,
information about the running time of the library will written to a file. This can be useful to
know where time is spent in the different parts of the ReactPhysics3D library in case your
application is too slow.
Each physics world has its own profiler. By default, the profiling report wil be written in a
text file next to the executable. If you have multiple worlds in your application, there will be
one profile file for each world. The profile files will be named after the name of the worlds.
By defaults worlds will have names: world, world1, world2, world3, …You can change the
name of the world by setting it into the WorldSettings object when you create the world
(see section 8).
ReactPhysics3D has an internal logger that can be used to get logs while running the
application. This can be useful for debugging for instance.
The logger is part of the PhysicsCommon class. By default there is no logger set.
If you want to create your custom logger to receive logs from ReactPhysics3D,
you can inherit the Logger class and override the Logger::log() method. Then,
you have to use the PhysicsCommon::setLogger() method to set the logger.
If you don’t want to create your custom logger class, you can use the default logger of
ReactPhysics3D (class DefaultLogger). With this logger, you can output the logs into a file
or a std::stream. The logs can have different format like raw text of HTML. In order to create
a default logger, you need to call the PhysicsCommon::createDefaultLogger() method.
Then, you can customize this default logger and finally, you need to set this logger using the
PhysicsCommon::setLogger() method.
The following code shows how to create a default logger that will output logs (warning
and errors) in HTML into a file:
For debugging purpose, it can be useful to display the physics objects of ReactPhysics3D
on top of your simulation. This is possible using the DebugRenderer class of the
library that allows you to display the colliders shapes, the AABB of the colliders
or the contact points for instance. This can help you to check for instance if the
physics collider of ReactPhysics3D is correctly aligned with the object you are
rendering. When debug rendering is enabled, ReactPhysics3D will generate each time
you call the PhysicsWorld::update() method (each frame), some rendering
primitives (lines and triangles) that you will be able to retrieve and display on you
simulation (with OpenGL or DirectX for instance). Note that ReactPhysics3D will only
generate the arrays of lines and triangles but you are responsible to draw them.
By default, the debug rendering is disabled. You can activate it using the
PhysicsWorld::setIsDebugRenderingEnabled() method. Note that you should
disable it for the final release because this can be quite expensive to compute.
You can get a reference to DebugRenderer of the physics world using the
PhysicsWorld::getDebugRenderer() method. Then, you need to select the debug items
(class DebugRenderer:DebugItem) you want to display. For instance, you might want to
display the shapes of the colliders (DebugItem::COLLISION_SHAPE), the broad-phase
AABBs of the colliders (DebugItem::COLLIDER_BROADPHASE_AABB), the colliders AABBs
(DebugItem::COLLIDER_AABB), the contact points (DebugItem::CONTACT_POINT) or
the contact normals (DebugItem::CONTACT_NORMAL). You need to use the
DebugRenderer::setIsDebugItemDisplayed() method to select if you want or not a given
debug item to be displayed.
The following code shows how to enable debug rendering in order to display contact
points and contact normals:
Now each time you call the PhysicsWorld::update() method, ReactPhysics3D will generate arrays with lines and triangles so that you can draw them in your application. You can use the DebugRenderer::getNbLines() and DebugRenderer::getNbTriangles() methods to know the number of lines and triangles to draw. Then, you need to call the DebugRenderer::getLinesArray() and DebugRenderer::getTrianglesArray() methods to get pointers to the beginning of the lines and triangles arrays. The lines array contain elements of type DebugRenderer:DebugLine with the two points of a line and their colors and the triangles array has elements of type DebugRenderer:DebugTriangle with the three points of each triangle and their colors. Note that the vertices of the lines and triangles are defined in world-space coordinates of the physics world.
ReactPhysics3D contains Doxygen documentation for its API.
The API reference documentation is also available online here:
http://www.reactphysics3d.com/documentation/api/html/
You can also find it in the library archive in the folder /documentation/API/html/. You just need to open the index.html file with your favorite web browser.
If you find some bugs, do not hesitate to report them on our issue tracker here:
https://github.com/DanielChappuis/reactphysics3d/issues
Thanks a lot for reporting the issues that you find. It will help us correct and improve the library.


--- layout: post title: Surrender on Both Sides date: 2008-01-06 23:04:36.000000000 -08:00 type: post published: true status: publish categories: - reviews - singles tags: [] meta: _publicize_pending: '1' original_post_id: '4' _wp_old_slug: '4' author: login: falsefridays email<EMAIL_ADDRESS>display_name: Jim Withington first_name: '' last_name: '' excerpt: |- The new Mountain Goats album, Heretic Pride, drops (as the kids say)(if their slang lags behind) shortly after my thirtieth birthday, and right after that the boys will be playing two shows at the best venue in the world. If "Sax Rohmer #1," the leadoff single that the Goats made available for download recently, indicates anything (and let's face it--of course it does; main Goat Darnielle's own music fan/thinker status doesn't make me feel like he's the kind of guy to decide such a thing lightly), this album will be exactly what I've been waiting for. ---
The new Mountain Goats album, Heretic Pride, drops (as the kids say)(if their slang lags behind) shortly after my thirtieth birthday, and right after that the boys will be playing two shows at the best venue in the world.
If "Sax Rohmer #1," the leadoff single that the Goats made available for download recently, indicates anything (and let's face it--of course it does; main Goat Darnielle's own music fan/thinker status doesn't make me feel like he's the kind of guy to decide such a thing lightly), this album will be exactly what I've been waiting for.
As albums go, 2006's Get Lonely was a red wine-buzz of a good one: creeping up, spreading fuzzily, a bit warm and with a little bit of "what did I do to myself?" later on. It wasn't--and isn't--an easy listen, quiet where we were used to Darnielle roaring. Perhaps that was the biggest strength of an album made up of things left unsaid.
This new track, though, seems likely to break at any moment into the "hungry for love--ready to drown" chorus from "Linda Blair Was Born Innocent" off of We Shall All Be Healed. It's similar in cadence, and his "shouty" register has returned.
And that's what we want our music to do, isn't it?  It's a fine line, and a powerful one, because your audience will love you forever if you succeed--and that's why this band deserves attention.
What an amazing birthday present this album, and tour, will be.
[audio:01_Sax_Rohmer_1.mp3]
(audio included because this track is already freely available)
****
Mountain Goats Tour Dates
4AD's Heretic Pride page: February 18th release
My Mountain Goats Feature, March 2007, Portland Mercury
themountaingoats.net


[OPINION] The irony of National Students' Day
Threats and intimidation against progressives continue to exist. The state's guns are still trained on social activists.
by Karl Patrick Wilfred M. SuyatSubscribe
Email Address
Newsletters
- Glenda Gloria's Take this Tuesday
- Huddle by Miriam Grace Go
- The Newsbreak Agenda by Chay Hofileña
- Sometimes, all you need is video by Lilibeth Frondoso


Frames:
Seconds:
Framerate:
Coordinates:
Mouse coordinates: (0, 0)
Ballspeed:
Directions: Select any of the 4 choices to begin.


--- layout: home title: Government of British Columbia Bootstrap Theme ---
BC Government look-and-feel for Bootstrap 4.3. See a simple demonstration of all common styles.


Guides The following guides are available globally. Validation Layer EntryField DateField Getting Started PickerField Field AreaField © 2019 Alexandru Barbulescu. All rights reserved. (Last updated: 2019-06-03) Generated by jazzy ♪♫ v0.9.6, a Realm project.


| GET |
/params/demo1 |
|
| GET |
/params/demo2 |
|
| GET |
/params/demo3 |
|
| GET |
/params/demo4 |
|
| POST |
/params/demo5 |
|
| GET |
/params/demo6 |
|
| GET |
/hook/demo1 |
|
| GET |
/hook/demo2 |
|
| POST |
/entity/demo1 |
|
| POST |
/entity/demo2 |
|
| POST |
/entity/demo3 |
|
| POST |
/entity/demo4 |
|
| POST |
/entity/demo5 |
|
| POST |
/entity/demo6 |
|
| GET |
GET /db/find/{userId} |
|
| GET |
/db/list |
|
| POST |
/db/ |
|
| PUT |
/db/ |
|
| DELETE |
/db/{userId} |
|
| GET |
GET /orm/{userId} |
|
| POST |
/orm/ |
|
| PUT |
/orm/ |
|
| DELETE |
/orm/{userId} |
|


Wama Software
New Street, near past colony, UA
04-07-1994
New-York
Male
San Francisco
94107
<EMAIL_ADDRESS>9876543210
- Cisco -
- Database -
- Microsoft's -
- Networking
This is About the Author section, author himself can add this from his edit profile section. They can write about their experiences with your site.


13.7. Release 0.234
General Changes
- Fix query failure for cross-joining bucketed tables with
COALESCE
when the bucket counts are compatible but mismatched.
- Fix an issue where
IGNORE NULLS
is not respected for window functions.
- Fix scheduling regression by setting the default scheduler to legacy scheduler.
- Improve coordinator reliability by adding support to cap the number of total tasks running in a coordinator by pausing scheduling.
This can be enabled by the configuration property
experimental.max-total-running-task-count-to-not-execute-new-query
.
- Improve the scale writer heuristics by considering overall producer buffer utilization. This can be enabled by the session property
optimized_scale_writer_producer_buffer
and the configuration property optimized-scale-writer-producer-buffer
.
- Improve end point
v1/resourceGroupState
to supporting filtering of resource groups that are dynamically generated.
- Improve connection pooling to avoid running out of sockets.
- Add KHyperLogLog type and related functions.
- Add support for forcing streaming exchange for Mark Distinct even if materialized exchange is enabled.
This can be enabled by the session property
use_stream_exchange_for_mark_distinct
and the configuration property query.use-streaming-exchange-for-mark-distinct
. (#14216).
Geospatial Changes
- Improve storage efficiency for Bing tiles by storing Bing tiles as
BIGINT
. This also reduces bucket skew in certain cases.
- Add support for spatial joins for join condition
ST_Distance(p1, p2) < r
.
Hive Changes
- Add
ZSTD
support for writing ORC
and DWRF
files. This can be enabled by setting session property hive.compression_codec
to ZSTD
.
Verifier Changes
- Add support for verifying
SELECT
queries that produce DATE
or UNKNOWN
(null) columns, or structured typed columns with DATE
or UNKNOWN
.
- Add support for auto-resolving control check query failures due to
EXCEEDED_TIME_LIMIT
.
- Add determinism analysis support for simple queries with top-level
ORDER BY LIMIT
clause. (#14181).
SPI Changes
- Add parameter
AccessControlContext
to all methods in SystemAccessControl
.
- Add
firstDynamicSegmentPosition
to SelectionContext.
Druid Changes
- Add support for aggregation pushdown.
- Add support for
LIMIT
evaluation pushdown.