Flexbodies are the models that get mapped to your nodes, and have deformation applied to them.
The game will calculate deformation by mapping every vertex to the nearby nodes, and moving them accordingly with the movement of those nodes.
Flexbodies are assigned to a set of nodes using groups, with the flexbodies only getting deformed by the movement of those specific nodes. See the nodes page for more information.
All the meshes should be in one or multiple dae files either in your car’s folder or the common folder. See the vehicle modelling page for more information.
An additional feature that can be used are deform groups. Those allow you to trigger a material change on a model when a defined set of beams get deformed. They are commonly used for lights and windows.
When one of the beams with the same deformGroup property as this flexbody deforms enough to meet its deformationTriggerRatio treshold, or the beam breaks, then the model’s material will be changed to the material named in the deformMaterialDamaged property.
Each mesh vertex gets mapped to 3 or 4 nodes - a center node, VX and VY nodes positioned in a way that imaginary lines (or beams) drawn from them to the center node form a roughly 90 degree angle, and if possible, a VZ node positioned in a way that a line drawn from it to the center node forms a roughly 90 degree angle with the other lines. The flexbody mapping system finds the closest possible nodes matching these criteria for each vertex, with some maximum distance constraints which can make some vertices map to nodes that form less than straight angles but are closer to them.
When VX or VY nodes cannot be found anywhere in the assigned group(s), the mesh will not be generated, and the console will shown an error:
VX node error means that only a center node can be found for all the vertices. This can only happen when the group consists of only 1 node.VY node error means that the flexbody system cannot find any node to form a 90 degree angle for some or all of the vertices. This can have multiple causes, which can be determined by the flexbody behavior in game:
flexbody help node. They are usually present on long, thin structures like antennas.
flexbody help node (if it exists in the first place), check the points below:
flexbody help node is not present, it should be added on the side that has a missing or stretched flexbody part.Sometimes, the flexbody system can map some vertices to less than ideal nodes, causing them to move into unexpected positions upon deformation, creating so called spikes in the mesh. To prevent this from happening, the nodes should be aligned in a grid of sorts, with no outliers that could cause unintentional vertex mapping. If extra nodes outside of the grid are needed for some other purpose, you can exclude them from the group. For a good example of good grid-like node positioning, you can take a look at vanilla vehicles with the Nodes and Triangles debug visualization modes on.
Notice the area around the rear wheel arch. The overall grid is aligned with the windows, but some nodes on the first and second row had to be repositioned to map to the rear fender flare instead. That on its own could have caused spikes, but it was fixed by moving the nodes right above them by half of this distance, so that they form straight, angled lines with the nodes above and below. Figuring out solutions like this takes some trial and error, prior experience helps speed up the process.
"flexbodies" :[
["mesh", "[group]:","nonFlexMaterials"],
["my_mesh", ["my_group"]],
],
“nonFlexMaterials” is a deprecated legacy feature that is not used or usable anymore. It was used with the old tire model to prevent the rigid wheel mesh from compressing with the tire.
"pos":{"x":0.0, "y":0.0, "z":0.0}
Uses the intrinsic Euler +Z +X +Y rotation system.
"rot":{"x":0.0, "y":0.0, "z":0.0}
"scale":{"x":1.0, "y":1.0, "z":1.0}
x, y, z degrees on XYZ axis, around the center point px, py, pzExample usage:
["part", ["group"], [],{"materialOverride":[
["originalMaterial1","replacementMaterial1"],
["originalMaterial2","replacementMaterial2"]
]}],
A mesh called “my_mesh” is assigned to nodes in group “my_group”.
"flexbodies" :[
["mesh", "[group]:","nonFlexMaterials"],
["my_mesh", ["my_group"]],
],
An example of headlights with deform groups.
"flexbodies": [
["mesh", "[group]:", "nonFlexMaterials"],
["pickup_headlightframe_R", ["pickup_fascia"]],
////lights
{"deformGroup":"headlightglass_R_break", "deformMaterialBase":"gavril_lights", "deformMaterialDamaged":"gavril_lights_dmg"},
["pickup_headlight_R", ["pickup_fascia"]],
//glass
{"deformGroup":"headlightglass_R_break", "deformMaterialBase":"pickup_glass", "deformMaterialDamaged":"pickup_glass_dmg"},
["pickup_headlightglass_R", ["pickup_fascia"],[]{"deformSound":"event:>Destruction>Vehicle>Glass>glassbreaksound4", "deformVolume":0.6}],
{"deformGroup":""},
],
An example of a flexbody using modifiers and multiple node groups.
"flexbodies": [
["mesh", "[group]:", "nonFlexMaterials"],
//wheels
["steelwheel_10a_13x5_5", ["wheel_FR","wheelhub_FR"], [], {"pos":{"x": -0.50, "y":-0.0, "z":0.0}, "rot":{"x":0, "y":0, "z":180}, "scale":{"x":1, "y":1, "z":1}}],
["steelwheel_10a_13x5_5", ["wheel_FL","wheelhub_FL"], [], {"pos":{"x": 0.50, "y":-0.0, "z":0.0}, "rot":{"x":0, "y":0, "z":0}, "scale":{"x":1, "y":1, "z":1}}],
],
Using materialOverride to define multiple parts with different color variants.
"us_semi_conventional_bullbar_type_bare": {
"information":{
"authors":"BeamNG",
"name":"Bare Metal",
"value":450,
},
"slotType" : "us_semi_conventional_bullbar_type",
"flexbodies": [
["mesh", "[group]:", "nonFlexMaterials"],
["longnose_bullbar", ["us_semi_bullbar"], [],{"materialOverride":[["us_semi_common","us_semi_common"]]}],
],
},
"us_semi_conventional_bullbar_type_chrome": {
"information":{
"authors":"BeamNG",
"name":"Polished",
"value":450,
},
"slotType" : "us_semi_conventional_bullbar_type",
"flexbodies": [
["mesh", "[group]:", "nonFlexMaterials"],
["longnose_bullbar", ["us_semi_bullbar"], [],{"materialOverride":[["us_semi_common","us_semi_common_chrome"]]}],
],
},
"us_semi_conventional_bullbar_type_painted": {
"information":{
"authors":"BeamNG",
"name":"Painted",
"value":450,
},
"slotType" : "us_semi_conventional_bullbar_type",
"flexbodies": [
["mesh", "[group]:", "nonFlexMaterials"],
["longnose_bullbar", ["us_semi_bullbar"], [],{"materialOverride":[["us_semi_common","us_semi_common_painted"]]}],
],
},
"us_semi_conventional_bullbar_type_black": {
"information":{
"authors":"BeamNG",
"name":"Black",
"value":450,
},
"slotType" : "us_semi_conventional_bullbar_type",
"flexbodies": [
["mesh", "[group]:", "nonFlexMaterials"],
["longnose_bullbar", ["us_semi_bullbar"], [],{"materialOverride":[["us_semi_common","us_semi_common_black"]]}],
],
},
Using materialOverride on multiple flexbodies at once.
"flexbodies": [
["mesh", "[group]:", "nonFlexMaterials"],
{"materialOverride":[
["us_trucklight_signal_R", "us_trucklight_amber_R"],
["us_trucklight_signal_L", "us_trucklight_amber_L"],
["us_trucklight_taillight_R", "us_trucklight_red_R2"],
["us_trucklight_taillight_L", "us_trucklight_red_L2"],
["us_trucklightglass_signal_R", "us_trucklightglass_amber_R"],
["us_trucklightglass_signal_L", "us_trucklightglass_amber_L"],
["us_trucklightglass_taillight_R", "us_trucklightglass_red_R2"],
["us_trucklightglass_taillight_L", "us_trucklightglass_red_L2"],
]},
["us_trucklight_taillight_R", ["schoolbus_body"],[],{"pos":{"x":-0.880,"y":-0.855,"z":2.661}}],
["us_trucklight_signal_R", ["schoolbus_body"],[],{"pos":{"x":-0.685,"y":-0.855,"z":2.661}}],
["us_trucklight_taillight_L", ["schoolbus_body"],[],{"pos":{"x": 0.880,"y":-0.855,"z":2.661}}],
["us_trucklight_signal_L", ["schoolbus_body"],[],{"pos":{"x": 0.685,"y":-0.855,"z":2.661}}],
["us_trucklightglass_taillight_R",["schoolbus_body"],[],{"pos":{"x":-0.880,"y":-0.855,"z":2.661}}],
["us_trucklightglass_signal_R", ["schoolbus_body"],[],{"pos":{"x":-0.685,"y":-0.855,"z":2.661}}],
["us_trucklightglass_taillight_L",["schoolbus_body"],[],{"pos":{"x": 0.880,"y":-0.855,"z":2.661}}],
["us_trucklightglass_signal_L", ["schoolbus_body"],[],{"pos":{"x": 0.685,"y":-0.855,"z":2.661}}],
{"materialOverride":[]},
],
Was this article helpful?