Compare commits

...

64 Commits

Author SHA1 Message Date
9e8835c1a9 Fixed typo in function OVERLAY_angular_limits 2022-02-15 22:36:12 +05:30
f5dd77d290 Added comments to RB_dworld_get_impulse to better explain the bullet terminologies 2022-02-15 22:05:47 +05:30
ad35f6181e Added comments to explain the calculations in hinge constraint debug drawing functions 2022-02-15 22:02:48 +05:30
e1846b874b Fixed issues caused by merge 2022-02-10 13:00:16 +05:30
211ac7b94b merge conflict helper removed 2022-02-09 16:11:34 +05:30
6c0987a2d5 Merge branch 'master' into soc-2021-simulation-display 2022-02-09 14:01:15 +05:30
17ffc6c140 Cleanup: remove unnecessary print statements 2022-01-07 18:20:16 +05:30
ccddbec168 Merge branch 'master' into soc-2021-simulation-display 2021-12-01 12:22:06 +05:30
e9ab60e092 Fix: incorrect force vector locations
While taking the weighted average of vector locations, the net normal
force was being used as the denominator. The correct value to use is
the sum of the magnitudes of all normal forces in the timestep.
2021-09-16 19:24:41 +05:30
eef2698182 Fix error while freeing non primitive collisions shape mesh in rigidbody
The function name was changed in master and caused an error during merge
Now it uses a different function to clear the geometry
2021-09-14 16:26:38 +05:30
dacfa8fb23 Merge branch 'master' into soc-2021-simulation-display 2021-09-14 16:24:18 +05:30
3cb9c6efad make format 2021-09-14 14:38:06 +05:30
b31083a008 Constraints: visualisation works with kinematic objects
Used the transforms obtained from bullet instead of creating them using
rigidbody/ object data, which only worked for active rigidbodies
2021-09-14 14:31:40 +05:30
d7dc751a94 Fix memory leak in non primitive collision shape
- The previous commit didn't fix the leak as the mesh data was not being freed every draw call
- Now the mesh is generated during evaluation along with the physics shape.
- The collisions shape draw data mesh is stored in the shared struct, along with the physics references
2021-09-11 11:57:40 +05:30
12e5b9420e Fix: Memory leak in non primitive collision shape drawing functions
The ojects containing the non primitive collision shape meshes are stored in
a GSet along with other draw cache shapes and the meshes are freed using these
object pointers
2021-09-01 18:52:35 +05:30
cfaaf58023 Cleanup: Forces 2021-08-19 01:17:08 +05:30
d4f44e67c4 Fix: Incorrect acceleration. Store velocities of only the last substep, subtract previous velocity from current 2021-08-18 23:47:53 +05:30
b4aafcc368 Cleanup: Constraints and panels 2021-08-18 23:04:29 +05:30
e53880a122 Constraints:Added functions to get transforms from bullet.
- These should be used in the constraint visualisation functions so that they can be drawn for kinematic objects as well
2021-08-18 15:58:16 +05:30
c79955fd28 Fix: Error while storing effectors forces, upto 3 effectors' forces can be stored now. 2021-08-18 12:57:35 +05:30
8be22e2ef1 Fix: Memory issue in store_convex_hull_draw_data: delete the convex hull computer. 2021-08-18 10:14:43 +05:30
e789dd4d4c Cleanup: collision display: faces of box, cone and cylinder
-Moved code for checking for faces of cone and cylinder to same function as the box
-Cached colliding faces
-Removed unneccesary shader files and used GPU batches instead, for drawing  faces
2021-08-17 11:57:31 +05:30
da57f6eb66 Fix: transform matrix for drawing colliding walls on box shape 2021-08-16 22:12:24 +05:30
9b9ff57095 Cleanup: Changed the place of non primitive collision shapes functions to draw_cache.c 2021-08-16 18:43:03 +05:30
045e7b58e4 Fix: Check for colliding faces after stepping through the simulation instead of in the draw engine
-This is a more accurate way to find colliding faces
-Store just the faces instead of the forces
2021-08-16 18:24:18 +05:30
0d04e138b1 Cleanup: Changed the place of the store_draw_data functions of convex hull and trimesh so that they are called from the draw engine instead. 2021-08-15 23:09:24 +05:30
ea208f067f Cleanup: Constraint linear limits visualisation
-created option to enable/disable fading of walls
-simplified variable names and transform matrices
2021-08-15 00:06:02 +05:30
012445eb14 Fix memmory error in function for storing convex hull collision shape mesh data. 2021-08-14 23:40:17 +05:30
94de2bf12c Physics: Changed hinge constraint visualisation so that it uses the transform matrices in the format obtained from bullet, created functions to get transforms from bullet 2021-08-13 18:23:39 +05:30
dc15562b7c Cleanup: Correct variable name while storing effectors force.
No functional changes.
2021-08-12 08:19:42 +05:30
96e5a771fb Cleanup: Hinge constraint visualisation, non primitive collision shape drawing 2021-08-12 07:59:31 +05:30
8256bfacee Cleanup: new function for getting debug draw data after step_simulation is called 2021-08-10 07:06:08 +05:30
0d09f5e486 Fix incorrect position of disks in hinge constraint 2021-08-09 09:23:20 +05:30
5a7f89354b Cleanup: Panels for drawing constraints 2021-08-09 09:12:44 +05:30
ccdb32ab7a Modified slider and hinge constraint and added visualisation for the piston constraint 2021-08-06 13:11:04 +05:30
d6e15033da Fixed error with point cache 2021-08-06 13:10:29 +05:30
f82df13492 Fixed error in python UI code, and error in caching acceleration. 2021-08-05 09:10:16 +05:30
2980e9791f Merge branch 'master' into soc-2021-simulation-display 2021-08-01 19:34:34 +05:30
083082fcc9 make format 2021-08-01 19:33:54 +05:30
fddc6bc5e9 Physics: Implemented caching previous velocity of rigid bodies so that acceleration can be calculated. 2021-08-01 19:31:03 +05:30
1109e900ce Physics: Added visualisation for slider and hinge constraints. 2021-08-01 13:28:46 +05:30
ea2406f249 Physics: Added visualisation for the slider constraint. 2021-07-26 17:27:20 +05:30
ca154310a6 Cleanup: Fixed missed forces bug by taking the average of all forces applied in one timestep. 2021-07-15 14:45:08 +05:30
0ccbeb64f8 Physics: Added visualisation for trimesh collision shape type 2021-07-11 10:22:25 +05:30
3c14b78dac Physics: Implemented darwing convex hull collisions shapes using mesh_batch_cache functions 2021-07-07 13:12:26 +05:30
16cddb290e Physics: enabled drawing for convex hull collision shape and corrected scale of compound child shapes 2021-07-04 12:16:58 +05:30
f36974123b Merge branch 'master' into soc-2021-simulation-display 2021-06-27 20:27:50 +05:30
c604a944df make format 2021-06-27 20:25:02 +05:30
b9903c78c1 Physics: Added visualisation for rigid body states and a small fix for forces 2021-06-27 20:12:46 +05:30
aad804bac0 Cleanup: fixed some issues with collision display and formatted the code
No functional changes
2021-06-22 11:13:53 +05:30
5cb618f828 No new features, just some cleanups to collision display code 2021-06-21 14:55:57 +05:30
1ddeff9999 Physics: Added basic visualisation for collisions, plus some cleanups to the Forces code 2021-06-19 22:59:17 +05:30
b1d04825e0 No new features implemented, added comments to overlay/shaders/vector_vert.glsl 2021-06-16 14:26:27 +05:30
244fab5876 Physics: Added visualisation for rigid bodies' velocities. 2021-06-14 16:00:25 +05:30
337eb4306c Physics: Added visualisation for frictional forces, plus some clean-ups to previous commit 2021-06-14 16:00:25 +05:30
63c8bf807d Pysics: Added visualisation for forces due to effectors, normal forces and gravity. 2021-06-14 16:00:25 +05:30
5f5b1e51a4 learnt basic arrow, ui panels 2021-06-14 16:00:25 +05:30
93f6db102d Merge branch 'master' of https://git.blender.org/blender 2021-06-14 15:59:15 +05:30
fbd14c1c75 Merge branch 'master' of https://git.blender.org/blender 2021-05-21 12:12:28 +05:30
9545f3ec67 Merge branch 'master' of https://git.blender.org/blender 2021-04-28 18:26:14 +05:30
cfe1f39b5f Merge branch 'master' of https://git.blender.org/blender 2021-04-28 16:20:52 +05:30
87e6e4d3ad Merge branch 'master' of https://git.blender.org/blender 2021-04-28 10:07:11 +05:30
4bc0ec4dda Merge branch 'master' of https://git.blender.org/blender 2021-04-27 13:09:13 +05:30
b826df8aa1 make format 2021-04-27 12:44:53 +05:30
35 changed files with 2659 additions and 407 deletions

View File

@@ -51,7 +51,8 @@ typedef struct {
// 7.8.1 Macros for format specifiers // 7.8.1 Macros for format specifiers
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 # if !defined(__cplusplus) || \
defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
// The fprintf macros for signed integers are: // The fprintf macros for signed integers are:
# define PRId8 "d" # define PRId8 "d"
@@ -277,8 +278,7 @@ static
# else // STATIC_IMAXDIV ][ # else // STATIC_IMAXDIV ][
_inline _inline
# endif // STATIC_IMAXDIV ] # endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) {
{
imaxdiv_t result; imaxdiv_t result;
result.quot = numer / denom; result.quot = numer / denom;
@@ -301,5 +301,4 @@ imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
# define wcstoimax _wcstoi64 # define wcstoimax _wcstoi64
# define wcstoumax _wcstoui64 # define wcstoumax _wcstoui64
#endif // _MSC_INTTYPES_H_ ] #endif // _MSC_INTTYPES_H_ ]

View File

@@ -56,14 +56,14 @@ extern "C" {
// Define _W64 macros to mark types changing their size, like intptr_t. // Define _W64 macros to mark types changing their size, like intptr_t.
# ifndef _W64 # ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 # if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && \
_MSC_VER >= 1300
# define _W64 __w64 # define _W64 __w64
# else # else
# define _W64 # define _W64
# endif # endif
# endif # endif
// 7.18.1 Integer types // 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types // 7.18.1.1 Exact-width integer types
@@ -89,7 +89,6 @@ extern "C" {
typedef __int64 int64_t; typedef __int64 int64_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types // 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t; typedef int8_t int_least8_t;
typedef int16_t int_least16_t; typedef int16_t int_least16_t;
@@ -123,10 +122,11 @@ typedef uint64_t uint_fast64_t;
typedef int64_t intmax_t; typedef int64_t intmax_t;
typedef uint64_t uintmax_t; typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types // 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 # if !defined(__cplusplus) || \
defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and
// footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types // 7.18.2.1 Limits of exact-width integer types
# define INT8_MIN ((int8_t)_I8_MIN) # define INT8_MIN ((int8_t)_I8_MIN)
@@ -220,10 +220,10 @@ typedef uint64_t uintmax_t;
# endif // __STDC_LIMIT_MACROS ] # endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types // 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 # if !defined(__cplusplus) || \
defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants // 7.18.4.1 Macros for minimum-width integer constants
@@ -243,5 +243,4 @@ typedef uint64_t uintmax_t;
# endif // __STDC_CONSTANT_MACROS ] # endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ] #endif // _MSC_STDINT_H_ ]

View File

@@ -81,6 +81,16 @@ void RB_dworld_set_solver_iterations(rbDynamicsWorld *world, int num_solver_iter
/* Split Impulse */ /* Split Impulse */
void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse); void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse);
/* Get latest applied impulse */
void RB_dworld_get_impulse(rbDynamicsWorld *world,
rbRigidBody *rbo,
float timeSubStep,
float norm_forces[3][3],
float fric_forces[3][3],
float vec_locations[3][3],
bool norm_flag,
bool fric_flag);
/* Simulation ----------------------- */ /* Simulation ----------------------- */
/* Step the simulation by the desired amount (in seconds) with extra controls on substep sizes and /* Step the simulation by the desired amount (in seconds) with extra controls on substep sizes and
@@ -264,6 +274,10 @@ void RB_shape_trimesh_update(rbCollisionShape *shape,
int vert_stride, int vert_stride,
float min[3], float min[3],
float max[3]); float max[3]);
/* Get scale data */
void RB_box_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents);
void RB_cone_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents);
void RB_cylinder_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents);
/* ********************************** */ /* ********************************** */
/* Constraints */ /* Constraints */
@@ -361,6 +375,20 @@ void RB_constraint_set_target_velocity_motor(rbConstraint *con,
float velocity_lin, float velocity_lin,
float velocity_ang); float velocity_ang);
/* Get object transforms */
void RB_constraint_get_transforms_hinge(rbConstraint *con,
float r_ob1_basis[3][3],
float r_ob2_basis[3][3],
float r_ob1_orig[3],
float r_ob2_orig[3]);
void RB_constraint_get_transforms_slider(rbConstraint *con,
float r_ob1_basis[3][3],
float r_ob2_basis[3][3],
float r_ob1_orig[3],
float r_ob2_orig[3],
float r_initial_dist[]);
/* Set number of constraint solver iterations made per step, this overrided world setting /* Set number of constraint solver iterations made per step, this overrided world setting
* To use default set it to -1 */ * To use default set it to -1 */
void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations); void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations);

View File

@@ -204,6 +204,103 @@ void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse)
info.m_splitImpulse = split_impulse; info.m_splitImpulse = split_impulse;
} }
/* Get last applied impulse at contact points */
/* TODO: this may not be the most efficient way to do it. get all forces at once and store in a
* lookup table. */
void RB_dworld_get_impulse(rbDynamicsWorld *world,
rbRigidBody *rbo,
float timeSubStep,
float norm_forces[3][3],
float fric_forces[3][3],
float vec_locations[3][3],
bool norm_flag,
bool fric_flag)
{
int numManifolds = world->dispatcher->getNumManifolds();
int num_norm_forces = 0;
int num_fric_forces = 0;
/* Loop through all persisent contact manifolds. The persistant manifold contains all contact points between
* 2 overlapping objects in the world. It can contain between 0 and 4 points. This is the contact point cache
* after reduction of the contact manifold. */
for (int i = 0; i < numManifolds; i++) {
btPersistentManifold *contactManifold = world->dispatcher->getManifoldByIndexInternal(i);
/* The 2 overlapping obejcts. */
const void *obA = contactManifold->getBody0();
const void *obB = contactManifold->getBody1();
/* Break if we cannot store any more forces. upperlimit is 3 */
/* Friction cannot exist without a normal force, so counting number of normal forces stored is enough. */
if (num_norm_forces > 2) {
break;
}
/* Continue to next manifold if this one does not invlove the current rigid body. */
if (obA != rbo->body && obB != rbo->body) {
continue;
}
else {
btVector3 tot_impulse = btVector3(0.0, 0.0, 0.0);
btVector3 final_loc = btVector3(0.0, 0.0, 0.0);
btScalar tot_impulse_magnitude = 0.f;
btVector3 tot_lat_impulse = btVector3(0.0, 0.0, 0.0);
int numContacts = contactManifold->getNumContacts();
int num_impulse_points = 0;
/* Find points where impulse was appplied. */
for (int j = 0; j < numContacts; j++) {
btManifoldPoint &pt = contactManifold->getContactPoint(j);
if (pt.getAppliedImpulse() > 0.f || -pt.getAppliedImpulse() > 0.f) {
num_impulse_points++;
}
}
/* Loop throught contact points and add impulses applied at each point.
* Devide by time to get the equivilant force. */
for (int j = 0; j < numContacts; j++) {
btManifoldPoint &pt = contactManifold->getContactPoint(j);
if (pt.getAppliedImpulse() > 0.f || -pt.getAppliedImpulse() > 0.f) {
const btVector3 &loc = pt.getPositionWorldOnB();
const btVector3 imp = (rbo->body == obB) ?
-pt.m_normalWorldOnB * pt.getAppliedImpulse() / timeSubStep :
pt.m_normalWorldOnB * pt.getAppliedImpulse() / timeSubStep;
tot_impulse_magnitude += pt.getAppliedImpulse() > 0.f? pt.getAppliedImpulse() : -pt.getAppliedImpulse();
tot_impulse += imp;
final_loc += num_impulse_points > 1 ? loc * pt.getAppliedImpulse() : loc;
if (fric_flag) {
const btVector3 lat_imp1 = (rbo->body == obB) ?
-pt.m_appliedImpulseLateral1 *
pt.m_lateralFrictionDir1 / timeSubStep :
pt.m_appliedImpulseLateral1 * pt.m_lateralFrictionDir1 /
timeSubStep;
const btVector3 lat_imp2 = (rbo->body == obB) ?
-pt.m_appliedImpulseLateral2 *
pt.m_lateralFrictionDir2 / timeSubStep :
pt.m_appliedImpulseLateral2 * pt.m_lateralFrictionDir2 /
timeSubStep;
tot_lat_impulse += lat_imp1 + lat_imp2;
}
}
}
/* If impulse was applied at more than one point, the location of the force is taken as average of points
* weighted by the magnitude of impulse applied at each point. */
if(fabsf(tot_impulse_magnitude)==0.0f){
continue;
}
if (num_impulse_points > 1) {
final_loc = final_loc / tot_impulse_magnitude;
}
copy_v3_btvec3(vec_locations[num_norm_forces], final_loc);
if (norm_flag) {
copy_v3_btvec3(norm_forces[num_norm_forces], tot_impulse);
num_norm_forces++;
}
if (fric_flag) {
copy_v3_btvec3(fric_forces[num_fric_forces], tot_lat_impulse);
num_fric_forces++;
}
}
}
}
/* Simulation ----------------------- */ /* Simulation ----------------------- */
void RB_dworld_step_simulation(rbDynamicsWorld *world, void RB_dworld_step_simulation(rbDynamicsWorld *world,
@@ -930,6 +1027,25 @@ void RB_shape_set_margin(rbCollisionShape *shape, float value)
shape->cshape->setMargin(value); shape->cshape->setMargin(value);
} }
/* Get scale data--------------------------- */
void RB_box_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents)
{
btBoxShape *box = (btBoxShape*)shape->cshape;
copy_v3_btvec3(r_half_extents, box->getHalfExtentsWithMargin());
}
void RB_cone_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents)
{
btConeShapeZ *cone = (btConeShapeZ*)shape->cshape;
copy_v3_btvec3(r_half_extents, btVector3(cone->getRadius(), cone->getRadius(), cone->getHeight()*0.5));
}
void RB_cylinder_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents)
{
btCylinderShapeZ *box = (btCylinderShapeZ*)shape->cshape;
copy_v3_btvec3(r_half_extents, box->getHalfExtentsWithMargin());
}
/* ********************************** */ /* ********************************** */
/* Constraints */ /* Constraints */
@@ -1302,4 +1418,51 @@ void RB_constraint_set_target_velocity_motor(rbConstraint *con,
constraint->getRotationalLimitMotor(0)->m_targetVelocity = velocity_ang; constraint->getRotationalLimitMotor(0)->m_targetVelocity = velocity_ang;
} }
void RB_constraint_get_transforms_hinge(rbConstraint *con,
float r_ob1_basis[3][3],
float r_ob2_basis[3][3],
float r_ob1_orig[3],
float r_ob2_orig[3]) {
btHingeConstraint *constraint = reinterpret_cast<btHingeConstraint *>(con);
btTransform transform1;
btTransform transform2;
transform1 = constraint->getAFrame();
transform2 = constraint->getBFrame();
for(int i=0; i<3; i++) {
copy_v3_btvec3(r_ob1_basis[i], btVector3(transform1.getBasis()[0][i],transform1.getBasis()[1][i], transform1.getBasis()[2][i]));
copy_v3_btvec3(r_ob2_basis[i], btVector3(transform2.getBasis()[0][i],transform2.getBasis()[1][i], transform2.getBasis()[2][i]));
}
copy_v3_btvec3(r_ob1_orig, btVector3(transform1.getOrigin().x(),transform1.getOrigin().y(), transform1.getOrigin().z()));
copy_v3_btvec3(r_ob2_orig, btVector3(transform2.getOrigin().x() ,transform2.getOrigin().y(), transform2.getOrigin().z()));
}
void RB_constraint_get_transforms_slider(rbConstraint *con,
float r_ob1_basis[3][3],
float r_ob2_basis[3][3],
float r_ob1_orig[3],
float r_ob2_orig[3],
float r_initial_dist[3]) {
btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint *>(con);
btTransform transform1;
btTransform transform2;
transform1 = constraint->getFrameOffsetA();
transform2 = constraint->getFrameOffsetB();
for(int i=0; i<3; i++) {
copy_v3_btvec3(r_ob1_basis[i], btVector3(transform1.getBasis()[0][i],transform1.getBasis()[1][i], transform1.getBasis()[2][i]));
copy_v3_btvec3(r_ob2_basis[i], btVector3(transform2.getBasis()[0][i],transform2.getBasis()[1][i], transform2.getBasis()[2][i]));
}
copy_v3_btvec3(r_ob1_orig, btVector3(transform1.getOrigin().x(),transform1.getOrigin().y(), transform1.getOrigin().z()));
copy_v3_btvec3(r_ob2_orig, btVector3(transform2.getOrigin().x() ,transform2.getOrigin().y(), transform2.getOrigin().z()));
if(r_initial_dist) {
btTransform transform3 = transform1 * transform2.inverse();
copy_v3_btvec3(r_initial_dist, btVector3(transform3.getOrigin().x() ,transform3.getOrigin().y(), transform3.getOrigin().z()));
}
}
/* ********************************** */ /* ********************************** */

View File

@@ -307,6 +307,72 @@ class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Pa
# TODO: other params such as time? # TODO: other params such as time?
class PHYSICS_PT_rigid_body_display_options(PHYSICS_PT_rigidbody_panel, Panel):
bl_label = "Display Options"
bl_parent_id = 'PHYSICS_PT_rigid_body'
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
@classmethod
def poll(cls, context):
obj = context.object
if obj.parent is not None and obj.parent.rigid_body is not None:
return False
return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
def draw(self, context):
layout = self.layout
layout.use_property_split = True
ob = context.object
rbo = ob.rigid_body
if rbo is None:
rigid_body_warning(layout, "Object does not have a Rigid Body")
return
col = layout.column()
if rbo.type == 'ACTIVE' and not rbo.kinematic:
col.prop(rbo, "display_acceleration")
col.prop(rbo, "display_velocity")
col.prop(rbo, "display_collisions")
col.prop(rbo, "display_data_text")
col.prop(rbo, "display_state")
class PHYSICS_PT_rigid_body_display_force_types(PHYSICS_PT_rigidbody_panel, Panel):
bl_label = "Forces"
bl_parent_id = 'PHYSICS_PT_rigid_body_display_options'
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
@classmethod
def poll(cls, context):
obj = context.object
if obj.parent is not None and obj.parent.rigid_body is not None:
return False
return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
def draw_header(self, context):
ob = context.object
rbo = ob.rigid_body
self.layout.prop(rbo, "display_forces", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
ob = context.object
rbo = ob.rigid_body
col = layout.column()
col.active = rbo.display_forces
col.prop(rbo, "show_gravity")
col.prop(rbo, "show_effectors_force")
col.prop(rbo, "show_normal_force")
col.prop(rbo, "show_frictional_force")
col.prop(rbo, "show_net_force")
classes = ( classes = (
PHYSICS_PT_rigid_body, PHYSICS_PT_rigid_body,
PHYSICS_PT_rigid_body_settings, PHYSICS_PT_rigid_body_settings,
@@ -316,10 +382,13 @@ classes = (
PHYSICS_PT_rigid_body_collisions_collections, PHYSICS_PT_rigid_body_collisions_collections,
PHYSICS_PT_rigid_body_dynamics, PHYSICS_PT_rigid_body_dynamics,
PHYSICS_PT_rigid_body_dynamics_deactivation, PHYSICS_PT_rigid_body_dynamics_deactivation,
PHYSICS_PT_rigid_body_display_options,
PHYSICS_PT_rigid_body_display_force_types,
) )
if __name__ == "__main__": # only for live edit. if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class from bpy.utils import register_class, unregister_class
for cls in classes: for cls in classes:
register_class(cls) register_class(cls)

View File

@@ -474,6 +474,34 @@ class PHYSICS_PT_rigid_body_constraint_springs_linear(PHYSICS_PT_rigidbody_const
sub.prop(rbc, "spring_stiffness_z", text="Stiffness") sub.prop(rbc, "spring_stiffness_z", text="Stiffness")
sub.prop(rbc, "spring_damping_z", text="Damping") sub.prop(rbc, "spring_damping_z", text="Damping")
class PHYSICS_PT_rigid_body_constraint_debug_draw(PHYSICS_PT_rigidbody_constraint_panel, Panel):
bl_label = "Debug draw"
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
@classmethod
def poll(cls, context):
ob = context.object
rbc = ob.rigid_body_constraint
return (ob and rbc
and (rbc.type in {'SLIDER', 'HINGE', 'PISTON'})
and context.engine in cls.COMPAT_ENGINES)
def draw(self, context):
layout = self.layout
layout.use_property_split = True
flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
ob = context.object
rbc = ob.rigid_body_constraint
col = flow.column()
col.prop(rbc, "debug_draw_limits", text="Debug draw")
if rbc.type in {'PISTON', 'SLIDER'}:
col = flow.column()
col.prop(rbc, "debug_draw_fade_walls", text="Fade walls")
classes = ( classes = (
PHYSICS_PT_rigid_body_constraint, PHYSICS_PT_rigid_body_constraint,
@@ -489,6 +517,7 @@ classes = (
PHYSICS_PT_rigid_body_constraint_springs, PHYSICS_PT_rigid_body_constraint_springs,
PHYSICS_PT_rigid_body_constraint_springs_angular, PHYSICS_PT_rigid_body_constraint_springs_angular,
PHYSICS_PT_rigid_body_constraint_springs_linear, PHYSICS_PT_rigid_body_constraint_springs_linear,
PHYSICS_PT_rigid_body_constraint_debug_draw,
) )

View File

@@ -140,7 +140,8 @@ void BKE_effectors_apply(struct ListBase *effectors,
struct EffectedPoint *point, struct EffectedPoint *point,
float *force, float *force,
float *wind_force, float *wind_force,
float *impulse); float *impulse,
float r_eff_forces[3][3]);
void BKE_effectors_free(struct ListBase *lb); void BKE_effectors_free(struct ListBase *lb);
void pd_point_from_particle(struct ParticleSimulationData *sim, void pd_point_from_particle(struct ParticleSimulationData *sim,

View File

@@ -25,6 +25,7 @@
#include "DNA_boid_types.h" /* for #BoidData */ #include "DNA_boid_types.h" /* for #BoidData */
#include "DNA_pointcache_types.h" /* for #BPHYS_TOT_DATA */ #include "DNA_pointcache_types.h" /* for #BPHYS_TOT_DATA */
#include "DNA_rigidbody_types.h"
#include <stdio.h> /* for #FILE */ #include <stdio.h> /* for #FILE */
@@ -103,6 +104,12 @@ typedef struct PTCacheData {
float size; float size;
float times[3]; float times[3];
struct BoidData boids; struct BoidData boids;
struct sim_data_vec eff_forces[3];
struct sim_data_vec norm_forces[3];
struct sim_data_vec fric_forces[3];
struct sim_data_vec vec_locations[3];
float pvel[3];
int colliding_faces[3];
} PTCacheData; } PTCacheData;
typedef struct PTCacheFile { typedef struct PTCacheFile {

View File

@@ -244,6 +244,12 @@ void BKE_rigidbody_object_sync_transforms(struct Depsgraph *depsgraph,
struct Scene *scene, struct Scene *scene,
struct Object *ob); struct Object *ob);
/* -------------------- */
/* Debug draw collision shapes */
/* -------------------- */
void BKE_rigidbody_store_convex_hull_draw_data(struct Object *ob);
void BKE_rigidbody_store_trimesh_draw_data(struct Object *ob);
/** \} */ /** \} */
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -1374,6 +1374,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
&epoint, &epoint,
force, force,
NULL, NULL,
NULL,
NULL); NULL);
if (ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) { if (ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {

View File

@@ -5082,7 +5082,8 @@ static void dynamic_paint_prepare_effect_cb(void *__restrict userdata,
EffectedPoint epoint; EffectedPoint epoint;
pd_point_from_loc(scene, realCoord[bData->s_pos[index]].v, vel, index, &epoint); pd_point_from_loc(scene, realCoord[bData->s_pos[index]].v, vel, index, &epoint);
epoint.vel_to_sec = 1.0f; epoint.vel_to_sec = 1.0f;
BKE_effectors_apply(effectors, NULL, surface->effector_weights, &epoint, forc, NULL, NULL); BKE_effectors_apply(
effectors, NULL, surface->effector_weights, &epoint, forc, NULL, NULL, NULL);
} }
/* if global gravity is enabled, add it too */ /* if global gravity is enabled, add it too */

View File

@@ -1135,7 +1135,8 @@ void BKE_effectors_apply(ListBase *effectors,
EffectedPoint *point, EffectedPoint *point,
float *force, float *force,
float *wind_force, float *wind_force,
float *impulse) float *impulse,
float r_eff_forces[3][3])
{ {
/* WARNING(@campbellbarton): historic comment? /* WARNING(@campbellbarton): historic comment?
* Many of these parameters don't exist! * Many of these parameters don't exist!
@@ -1173,6 +1174,8 @@ void BKE_effectors_apply(ListBase *effectors,
/* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */ /* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
/* Check for min distance here? (yes would be cool to add that, ton) */ /* Check for min distance here? (yes would be cool to add that, ton) */
int num_eff_forces = 0;
float out_force[3] = {0, 0, 0};
if (effectors) { if (effectors) {
for (eff = effectors->first; eff; eff = eff->next) { for (eff = effectors->first; eff; eff = eff->next) {
/* object effectors were fully checked to be OK to evaluate! */ /* object effectors were fully checked to be OK to evaluate! */
@@ -1187,7 +1190,7 @@ void BKE_effectors_apply(ListBase *effectors,
efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point); efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point);
} }
if (efd.falloff > 0.0f) { if (efd.falloff > 0.0f) {
float out_force[3] = {0, 0, 0}; zero_v3(out_force);
if (eff->pd->forcefield == PFIELD_TEXTURE) { if (eff->pd->forcefield == PFIELD_TEXTURE) {
do_texture_effector(eff, &efd, point, out_force); do_texture_effector(eff, &efd, point, out_force);
@@ -1214,6 +1217,11 @@ void BKE_effectors_apply(ListBase *effectors,
/* special case for harmonic effector */ /* special case for harmonic effector */
add_v3_v3v3(impulse, impulse, efd.vel); add_v3_v3v3(impulse, impulse, efd.vel);
} }
if (r_eff_forces != NULL && num_eff_forces < 3) {
copy_v3_v3(r_eff_forces[num_eff_forces], out_force);
num_eff_forces++;
}
} }
} }
} }

View File

@@ -3195,7 +3195,7 @@ static void update_effectors_task_cb(void *__restrict userdata,
/* Do effectors. */ /* Do effectors. */
pd_point_from_loc(data->scene, voxel_center, vel, index, &epoint); pd_point_from_loc(data->scene, voxel_center, vel, index, &epoint);
BKE_effectors_apply( BKE_effectors_apply(
data->effectors, NULL, fds->effector_weights, &epoint, retvel, NULL, NULL); data->effectors, NULL, fds->effector_weights, &epoint, retvel, NULL, NULL, NULL);
/* Convert retvel to local space. */ /* Convert retvel to local space. */
mag = len_v3(retvel); mag = len_v3(retvel);

View File

@@ -2572,6 +2572,7 @@ static void do_path_effectors(ParticleSimulationData *sim,
&epoint, &epoint,
force, force,
NULL, NULL,
NULL,
NULL); NULL);
mul_v3_fl(force, mul_v3_fl(force,

View File

@@ -2256,7 +2256,8 @@ static void basic_force_cb(void *efdata_v, ParticleKey *state, float *force, flo
&epoint, &epoint,
force, force,
NULL, NULL,
impulse); impulse,
NULL);
} }
mul_v3_fl(force, efdata->ptex.field); mul_v3_fl(force, efdata->ptex.field);

View File

@@ -127,6 +127,12 @@ static int ptcache_data_size[] = {
sizeof(float), /* BPHYS_DATA_SIZE */ sizeof(float), /* BPHYS_DATA_SIZE */
sizeof(float[3]), /* BPHYS_DATA_TIMES */ sizeof(float[3]), /* BPHYS_DATA_TIMES */
sizeof(BoidData), /* case BPHYS_DATA_BOIDS */ sizeof(BoidData), /* case BPHYS_DATA_BOIDS */
sizeof(sim_data_vec[3]), /* BPHYS_DATA_EFF_FORCES */
sizeof(sim_data_vec[3]), /* BPHYS_DATA_NORM_FORCES */
sizeof(sim_data_vec[3]), /* BPHYS_DATA_FRIC_FORCES */
sizeof(sim_data_vec[3]), /* BPHYS_DATA_VEC_LOCATIONS */
sizeof(float[3]), /* BHYS_DATA_PREV_VELOCITY */
sizeof(int[3]), /* BHYS_DATA_COLLIDING_FACES */
}; };
static int ptcache_extra_datasize[] = { static int ptcache_extra_datasize[] = {
@@ -781,6 +787,13 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUSE
#endif #endif
PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, rbo->pos); PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, rbo->pos);
PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, rbo->orn); PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, rbo->orn);
PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, rbo->vel);
PTCACHE_DATA_FROM(data, BPHYS_DATA_EFF_FORCES, rbo->eff_forces);
PTCACHE_DATA_FROM(data, BPHYS_DATA_NORM_FORCES, rbo->norm_forces);
PTCACHE_DATA_FROM(data, BPHYS_DATA_FRIC_FORCES, rbo->fric_forces);
PTCACHE_DATA_FROM(data, BPHYS_DATA_VEC_LOCATIONS, rbo->vec_locations);
PTCACHE_DATA_FROM(data, BPHYS_DATA_PREV_VELOCITY, rbo->pvel);
PTCACHE_DATA_FROM(data, BPHYS_DATA_COLLIDING_FACES, rbo->colliding_faces);
} }
} }
@@ -804,10 +817,24 @@ static void ptcache_rigidbody_read(
if (old_data) { if (old_data) {
memcpy(rbo->pos, data, sizeof(float[3])); memcpy(rbo->pos, data, sizeof(float[3]));
memcpy(rbo->orn, data + 3, sizeof(float[4])); memcpy(rbo->orn, data + 3, sizeof(float[4]));
memcpy(rbo->vel, data + 7, sizeof(float[3]));
memcpy(rbo->eff_forces, data + 10, sizeof(sim_data_vec[3]));
memcpy(rbo->norm_forces, data + 19, sizeof(sim_data_vec[3]));
memcpy(rbo->fric_forces, data + 28, sizeof(sim_data_vec[3]));
memcpy(rbo->vec_locations, data + 37, sizeof(sim_data_vec[3]));
memcpy(rbo->pvel, data + 46, sizeof(float[3]));
memcpy(rbo->colliding_faces, data + 49, sizeof(int[3]));
} }
else { else {
PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, rbo->pos); PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, rbo->pos);
PTCACHE_DATA_TO(data, BPHYS_DATA_ROTATION, 0, rbo->orn); PTCACHE_DATA_TO(data, BPHYS_DATA_ROTATION, 0, rbo->orn);
PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, rbo->vel);
PTCACHE_DATA_TO(data, BPHYS_DATA_EFF_FORCES, 0, rbo->eff_forces);
PTCACHE_DATA_TO(data, BPHYS_DATA_NORM_FORCES, 0, rbo->norm_forces);
PTCACHE_DATA_TO(data, BPHYS_DATA_FRIC_FORCES, 0, rbo->fric_forces);
PTCACHE_DATA_TO(data, BPHYS_DATA_VEC_LOCATIONS, 0, rbo->vec_locations);
PTCACHE_DATA_TO(data, BPHYS_DATA_PREV_VELOCITY, 0, rbo->pvel);
PTCACHE_DATA_TO(data, BPHYS_DATA_COLLIDING_FACES, 0, rbo->colliding_faces);
} }
} }
} }
@@ -1085,7 +1112,11 @@ void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *r
pid->write_header = ptcache_basic_header_write; pid->write_header = ptcache_basic_header_write;
pid->read_header = ptcache_basic_header_read; pid->read_header = ptcache_basic_header_read;
pid->data_types = (1 << BPHYS_DATA_LOCATION) | (1 << BPHYS_DATA_ROTATION); pid->data_types = (1 << BPHYS_DATA_LOCATION) | (1 << BPHYS_DATA_ROTATION) |
(1 << BPHYS_DATA_VELOCITY) | (1 << BPHYS_DATA_EFF_FORCES) |
(1 << BPHYS_DATA_NORM_FORCES) | (1 << BPHYS_DATA_FRIC_FORCES) |
(1 << BPHYS_DATA_VEC_LOCATIONS) | (1 << BPHYS_DATA_PREV_VELOCITY) |
(1 << BPHYS_DATA_COLLIDING_FACES);
pid->info_types = 0; pid->info_types = 0;
pid->stack_index = pid->cache->index; pid->stack_index = pid->cache->index;
@@ -1727,6 +1758,24 @@ static void ptcache_file_pointers_init(PTCacheFile *pf)
pf->cur[BPHYS_DATA_SIZE] = (data_types & (1 << BPHYS_DATA_SIZE)) ? &pf->data.size : NULL; pf->cur[BPHYS_DATA_SIZE] = (data_types & (1 << BPHYS_DATA_SIZE)) ? &pf->data.size : NULL;
pf->cur[BPHYS_DATA_TIMES] = (data_types & (1 << BPHYS_DATA_TIMES)) ? &pf->data.times : NULL; pf->cur[BPHYS_DATA_TIMES] = (data_types & (1 << BPHYS_DATA_TIMES)) ? &pf->data.times : NULL;
pf->cur[BPHYS_DATA_BOIDS] = (data_types & (1 << BPHYS_DATA_BOIDS)) ? &pf->data.boids : NULL; pf->cur[BPHYS_DATA_BOIDS] = (data_types & (1 << BPHYS_DATA_BOIDS)) ? &pf->data.boids : NULL;
pf->cur[BPHYS_DATA_EFF_FORCES] = (data_types & (1 << BPHYS_DATA_EFF_FORCES)) ?
&pf->data.eff_forces :
NULL;
pf->cur[BPHYS_DATA_NORM_FORCES] = (data_types & (1 << BPHYS_DATA_NORM_FORCES)) ?
&pf->data.norm_forces :
NULL;
pf->cur[BPHYS_DATA_FRIC_FORCES] = (data_types & (1 << BPHYS_DATA_FRIC_FORCES)) ?
&pf->data.fric_forces :
NULL;
pf->cur[BPHYS_DATA_VEC_LOCATIONS] = (data_types & (1 << BPHYS_DATA_VEC_LOCATIONS)) ?
&pf->data.vec_locations :
NULL;
pf->cur[BPHYS_DATA_PREV_VELOCITY] = (data_types & (1 << BPHYS_DATA_PREV_VELOCITY)) ?
&pf->data.pvel :
NULL;
pf->cur[BPHYS_DATA_COLLIDING_FACES] = (data_types & (1 << BPHYS_DATA_COLLIDING_FACES)) ?
&pf->data.pvel :
NULL;
} }
int BKE_ptcache_mem_index_find(PTCacheMem *pm, unsigned int index) int BKE_ptcache_mem_index_find(PTCacheMem *pm, unsigned int index)
@@ -3781,6 +3830,12 @@ static const char *ptcache_data_struct[] = {
"", // BPHYS_DATA_SIZE: "", // BPHYS_DATA_SIZE:
"", // BPHYS_DATA_TIMES: "", // BPHYS_DATA_TIMES:
"BoidData", // case BPHYS_DATA_BOIDS: "BoidData", // case BPHYS_DATA_BOIDS:
"sim_data_vec", //BPHYS_DATA_EFF_FORCES:
"sim_data_vec", //BPHYS_DATA_NORM_FORCES:
"sim_data_vec", //BPHYS_DATA_FRIC_FORCES:
"sim_data_vec", //BPHYS_DATA_VEC_LOCATIONS:
"", //BPHYS_DATA_PREV_VELOCITY:
"", //BPHYS_DATA_COLLIDING_FACES
}; };
static const char *ptcache_extra_struct[] = { static const char *ptcache_extra_struct[] = {
"", "",

View File

@@ -35,9 +35,11 @@
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_math.h" #include "BLI_math.h"
#include "BLI_ghash.h"
#ifdef WITH_BULLET #ifdef WITH_BULLET
# include "RBI_api.h" # include "RBI_api.h"
# include "RBI_hull_api.h"
#endif #endif
#include "DNA_ID.h" #include "DNA_ID.h"
@@ -198,6 +200,12 @@ void BKE_rigidbody_free_object(Object *ob, RigidBodyWorld *rbw)
rbo->shared->physics_shape = NULL; rbo->shared->physics_shape = NULL;
} }
if (rbo->shared->col_shape_draw_data) {
BKE_mesh_clear_geometry(rbo->shared->col_shape_draw_data);
BKE_id_free(NULL, rbo->shared->col_shape_draw_data);
rbo->shared->col_shape_draw_data = NULL;
}
MEM_freeN(rbo->shared); MEM_freeN(rbo->shared);
} }
@@ -478,7 +486,6 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
else { else {
CLOG_ERROR(&LOG, "cannot make Triangular Mesh collision shape for non-Mesh object"); CLOG_ERROR(&LOG, "cannot make Triangular Mesh collision shape for non-Mesh object");
} }
return shape; return shape;
} }
@@ -628,7 +635,20 @@ static void rigidbody_validate_sim_shape(RigidBodyWorld *rbw, Object *ob, bool r
if (rbo->shared->physics_shape) { if (rbo->shared->physics_shape) {
RB_shape_delete(rbo->shared->physics_shape); RB_shape_delete(rbo->shared->physics_shape);
} }
/* Delete old debug drawing mesh data if it exists. */
if (rbo->shared->col_shape_draw_data) {
BKE_mesh_clear_geometry(rbo->shared->col_shape_draw_data);
BKE_id_free(NULL, rbo->shared->col_shape_draw_data);
rbo->shared->col_shape_draw_data = NULL;
}
rbo->shared->physics_shape = new_shape; rbo->shared->physics_shape = new_shape;
if(rbo->shape == RB_SHAPE_CONVEXH) {
BKE_rigidbody_store_convex_hull_draw_data(ob);
}
if(rbo->shape == RB_SHAPE_TRIMESH) {
BKE_rigidbody_store_trimesh_draw_data(ob);
}
} }
} }
@@ -1273,6 +1293,28 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
rbo->col_groups = 1; rbo->col_groups = 1;
zero_v3(rbo->eff_forces[0].vector);
zero_v3(rbo->eff_forces[1].vector);
zero_v3(rbo->eff_forces[2].vector);
zero_v3(rbo->norm_forces[0].vector);
zero_v3(rbo->norm_forces[1].vector);
zero_v3(rbo->norm_forces[2].vector);
zero_v3(rbo->fric_forces[0].vector);
zero_v3(rbo->fric_forces[1].vector);
zero_v3(rbo->fric_forces[2].vector);
zero_v3(rbo->vec_locations[0].vector);
zero_v3(rbo->vec_locations[1].vector);
zero_v3(rbo->vec_locations[2].vector);
rbo->colliding_faces[0] = -1;
rbo->colliding_faces[1] = -1;
rbo->colliding_faces[2] = -1;
zero_v3(rbo->pvel);
zero_v3(rbo->vel);
rbo->shared->col_shape_draw_data = NULL;
/* use triangle meshes for passive objects /* use triangle meshes for passive objects
* use convex hulls for active objects since dynamic triangle meshes are very unstable * use convex hulls for active objects since dynamic triangle meshes are very unstable
*/ */
@@ -1754,7 +1796,14 @@ static void rigidbody_update_sim_ob(
/* Calculate net force of effectors, and apply to sim object: /* Calculate net force of effectors, and apply to sim object:
* - we use 'central force' since apply force requires a "relative position" * - we use 'central force' since apply force requires a "relative position"
* which we don't have... */ * which we don't have... */
BKE_effectors_apply(effectors, NULL, effector_weights, &epoint, eff_force, NULL, NULL); float eff_forces[3][3] = {{0.0}};
BKE_effectors_apply(
effectors, NULL, effector_weights, &epoint, eff_force, NULL, NULL, eff_forces);
if (rbo->sim_display_options & RB_SIM_FORCES) {
for (int i = 0; i < 3; i++) {
copy_v3_v3(rbo->eff_forces[i].vector, eff_forces[i]);
}
}
if (G.f & G_DEBUG) { if (G.f & G_DEBUG) {
printf("\tapplying force (%f,%f,%f) to '%s'\n", printf("\tapplying force (%f,%f,%f) to '%s'\n",
eff_force[0], eff_force[0],
@@ -2034,6 +2083,215 @@ static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBod
FOREACH_COLLECTION_OBJECT_RECURSIVE_END; FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
} }
static void rigidbody_debug_draw_get_colliding_face(Object *ob, const float points[3][3], const float forces[3][3]) {
/* Unit Box vertices. */
float box_shape[8][3] = {
{1.0f, -1.0f, 1.0f},
{1.0f, -1.0f, -1.0f},
{-1.0f, -1.0f, -1.0f},
{-1.0f, -1.0f, 1.0f},
{1.0f, 1.0f, 1.0f},
{1.0f, 1.0f, -1.0f},
{-1.0f, 1.0f, -1.0f},
{-1.0f, 1.0f, 1.0f},
};
/* Triangles that make up the faces of the box. */
uint box_shape_tris[12][3] = {
{0, 1, 2},
{0, 2, 3},
{0, 1, 5},
{0, 5, 4},
{1, 2, 6},
{1, 6, 5},
{2, 3, 7},
{2, 7, 6},
{3, 0, 4},
{3, 4, 7},
{4, 5, 6},
{4, 6, 7},
};
float transform_mat[4][4] = {{0.0f}};
float size[3] = {1.0f};
float pos[3] = {0.0f};
float rot[4] = {0.0f};
float isect_co[3] ={0.0f};
float point[3] = {0.0f};
float dir[3];
int stored_faces = 0;
int max_faces = 0;
RigidBodyOb *rbo = ob->rigidbody_object;
if(rbo->shared->physics_object) {
RB_body_get_position(rbo->shared->physics_object, pos);
RB_body_get_orientation(rbo->shared->physics_object, rot);
}
switch(rbo->shape) {
case RB_SHAPE_BOX:
max_faces = 3;
if(rbo->shared->physics_shape) {
RB_box_shape_get_half_extents(rbo->shared->physics_shape, size);
}
break;
case RB_SHAPE_CYLINDER:
max_faces = 2;
if(rbo->shared->physics_shape) {
RB_cylinder_shape_get_half_extents(rbo->shared->physics_shape, size);
}
break;
case RB_SHAPE_CONE:
max_faces = 1;
if(rbo->shared->physics_shape) {
RB_cone_shape_get_half_extents(rbo->shared->physics_shape, size);
}
break;
}
loc_quat_size_to_mat4(transform_mat, pos, rot, size);
/* Transform the box to correct location, orientaion and scale. */
for (int i = 0; i < 8; i++) {
mul_m4_v3(transform_mat, box_shape[i]);
}
if(ELEM(rbo->shape, RB_SHAPE_BOX, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
for(int i=0; i<3; i++) {
if(stored_faces >= max_faces) {
break;
}
copy_v3_v3(point, points[i]);
normalize_v3_v3(dir, forces[i]);
/* If face has already collided don't overwrite. */
if(rbo->colliding_faces[i] > -1) {
stored_faces++;
}
for (int j = 0; j < 6; j++) {
/* The cylinder and cone have fewer faces. */
if(rbo->shape == RB_SHAPE_CYLINDER) {
if(!ELEM(j, 2, 4)) {
continue;
}
}
if(rbo->shape == RB_SHAPE_CONE) {
if(j!=2) {
continue;
}
}
if (isect_point_tri_v3(point,
box_shape[box_shape_tris[2 * j][0]],
box_shape[box_shape_tris[2 * j][1]],
box_shape[box_shape_tris[2 * j][2]],
isect_co) ||
isect_point_tri_v3(point,
box_shape[box_shape_tris[2 * j + 1][0]],
box_shape[box_shape_tris[2 * j + 1][1]],
box_shape[box_shape_tris[2 * j + 1][2]],
isect_co)) {
/* Find normal to the face. */
float edge1[3], edge2[3], norm[3];
sub_v3_v3v3(edge1, box_shape[box_shape_tris[2 * j][0]], box_shape[box_shape_tris[2 * j][1]]);
sub_v3_v3v3(edge2, box_shape[box_shape_tris[2 * j][2]], box_shape[box_shape_tris[2 * j][1]]);
cross_v3_v3v3(norm, edge1, edge2);
normalize_v3(norm);
/* Check that distance is small and force is perpendicular to the face. */
if ((len_v3v3(point, isect_co) <= rbo->margin) &&
(fabsf(dot_v3v3(norm, dir)) > 0.99))
{
if(ELEM(j, rbo->colliding_faces[0], rbo->colliding_faces[1], rbo->colliding_faces[2])) {
continue;
}
rbo->colliding_faces[stored_faces] = j;
stored_faces++;
break;
}
}
}
}
}
}
static void rigidbody_get_debug_draw_data(RigidBodyWorld *rbw, float substep, GHash *norm_forces_magnitudes, bool is_last_substep) {
/*Loop through all rigid bodies and get the forces being applied in the substep (for drawing debug info).
* Store average force acting on objects during all substeps.
* We store the average of the forces and not the forces themselves, because storing forces
* would mean that only the force applied in the last substep is displayed on the screen.
* Average is a better representation of what happened during the whole timestep.*/
for (int j = 0; j < rbw->numbodies; j++) {
float num_substeps = (float)rbw->substeps_per_frame;
float norm_forces[3][3] = {{0.0f}};
float fric_forces[3][3] = {{0.0f}};
float vec_locations[3][3] = {{0.0f}};
Object *ob = rbw->objects[j];
float *norm_forces_mag = (float *)BLI_ghash_lookup(norm_forces_magnitudes, ob);
if (ob->rigidbody_object != NULL) {
rbRigidBody *rbo = (rbRigidBody *)(ob->rigidbody_object->shared->physics_object);
if(((ob->rigidbody_object->sim_display_options & RB_SIM_VELOCITY) ||
(ob->rigidbody_object->sim_display_options & RB_SIM_ACCELERATION)) &&
is_last_substep)
{
/* Get velocity. */
copy_v3_v3(ob->rigidbody_object->pvel, ob->rigidbody_object->vel);
RB_body_get_linear_velocity(rbo, ob->rigidbody_object->vel);
}
bool norm_flag = (ob->rigidbody_object->display_force_types & RB_SIM_NORMAL) ||
(ob->rigidbody_object->display_force_types & RB_SIM_NET_FORCE) ||
(ob->rigidbody_object->sim_display_options & RB_SIM_COLLISIONS);
bool fric_flag = (ob->rigidbody_object->display_force_types & RB_SIM_FRICTION) ||
(ob->rigidbody_object->display_force_types & RB_SIM_NET_FORCE);
if (norm_flag || fric_flag) {
RB_dworld_get_impulse(rbw->shared->physics_world,
rbo,
substep,
norm_forces,
fric_forces,
vec_locations,
norm_flag,
fric_flag);
if(!is_zero_v3(norm_forces[0])) {
rigidbody_debug_draw_get_colliding_face(ob, vec_locations, norm_forces);
}
for(int k=0; k<3; k++){
if (norm_flag || fric_flag) {
mul_v3_fl(norm_forces[k], 1/num_substeps);
norm_forces_mag[k] += len_v3(norm_forces[k]);
add_v3_v3(ob->rigidbody_object->norm_forces[k].vector, norm_forces[k]);
mul_v3_fl(vec_locations[k], len_v3(norm_forces[k]));
add_v3_v3(ob->rigidbody_object->vec_locations[k].vector, vec_locations[k]);
}
if (fric_flag) {
mul_v3_fl(fric_forces[k], 1/num_substeps);
add_v3_v3(ob->rigidbody_object->fric_forces[k].vector, fric_forces[k]);
}
if(is_last_substep) {
if(norm_forces_mag[k]>0.0f) {
mul_v3_fl(ob->rigidbody_object->vec_locations[k].vector, (1.0f/norm_forces_mag[k]));
}
else {
zero_v3(ob->rigidbody_object->vec_locations[k].vector);
}
}
}
}
}
}
}
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
{ {
return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->shared->pointcache->startframe); return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->shared->pointcache->startframe);
@@ -2251,11 +2509,49 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
const float interp_step = 1.0f / rbw->substeps_per_frame; const float interp_step = 1.0f / rbw->substeps_per_frame;
float cur_interp_val = interp_step; float cur_interp_val = interp_step;
GHash *norm_forces_magnitudes = BLI_ghash_ptr_new(__func__);
/* Set all contact forces and their locations to zero. (for drawing debug info) */
for (int i = 0; i < rbw->numbodies; i++) {
Object *ob = rbw->objects[i];
for(int j=0; j<3; j++) {
zero_v3(ob->rigidbody_object->norm_forces[j].vector);
zero_v3(ob->rigidbody_object->vec_locations[j].vector);
zero_v3(ob->rigidbody_object->fric_forces[j].vector);
ob->rigidbody_object->colliding_faces[j] = -1;
}
if((ob->rigidbody_object->display_force_types & RB_SIM_NORMAL) ||
(ob->rigidbody_object->display_force_types & RB_SIM_FRICTION) ||
(ob->rigidbody_object->sim_display_options & RB_SIM_COLLISIONS)) {
float *arr = MEM_callocN(sizeof(float) * 3 ,__func__);
BLI_ghash_insert(norm_forces_magnitudes, ob, arr);
}
}
for (int i = 0; i < rbw->substeps_per_frame; i++) { for (int i = 0; i < rbw->substeps_per_frame; i++) {
rigidbody_update_kinematic_obj_substep(&substep_targets, cur_interp_val); rigidbody_update_kinematic_obj_substep(&substep_targets, cur_interp_val);
RB_dworld_step_simulation(rbw->shared->physics_world, substep, 0, substep); RB_dworld_step_simulation(rbw->shared->physics_world, substep, 0, substep);
cur_interp_val += interp_step; cur_interp_val += interp_step;
if(i == rbw->substeps_per_frame-1) {
rigidbody_get_debug_draw_data(rbw, substep, norm_forces_magnitudes, true);
} }
else {
rigidbody_get_debug_draw_data(rbw, substep, norm_forces_magnitudes, false);
}
}
if (norm_forces_magnitudes) {
GHashIterator gh_iter;
GHASH_ITER(gh_iter, norm_forces_magnitudes) {
float *arr = BLI_ghashIterator_getValue(&gh_iter);
MEM_SAFE_FREE(arr);
}
BLI_ghash_free(norm_forces_magnitudes, NULL, NULL);
}
rigidbody_free_substep_data(&substep_targets); rigidbody_free_substep_data(&substep_targets);
rigidbody_update_simulation_post_step(depsgraph, rbw); rigidbody_update_simulation_post_step(depsgraph, rbw);
@@ -2267,6 +2563,151 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
rbw->ltime = ctime; rbw->ltime = ctime;
} }
} }
void BKE_rigidbody_store_convex_hull_draw_data(Object *ob) {
Mesh *hull_draw_data;
Mesh *mesh = NULL;
MVert *mvert = NULL;
int totvert = 0;
if (ob->type == OB_MESH && ob->data) {
mesh = rigidbody_get_mesh(ob);
mvert = (mesh) ? mesh->mvert : NULL;
totvert = (mesh) ? mesh->totvert : 0;
}
else {
CLOG_ERROR(&LOG, "cannot make Convex Hull collision shape for non-Mesh object");
}
float (*verts)[3] = (float(*)[3])MEM_malloc_arrayN(sizeof(float[3]), totvert, __func__);
for(int i=0; i<totvert; i++){
// verts[i] = (float*)MEM_malloc_arrayN(sizeof(float), 3, __func__);
copy_v3_v3(verts[i], mvert[i].co);
}
plConvexHull hull = plConvexHullCompute((float(*)[3])verts, totvert);
MEM_freeN(verts);
const int num_verts = plConvexHullNumVertices(hull);
const int num_faces = num_verts <= 2 ? 0 : plConvexHullNumFaces(hull);
const int num_loops = num_verts <= 2 ? 0 : plConvexHullNumLoops(hull);
const int num_edges = num_verts == 2 ? 1 : num_verts < 2 ? 0 : num_loops / 2;
hull_draw_data = BKE_mesh_new_nomain(num_verts, num_edges, 0, num_loops, num_faces);
for (int i=0; i<num_verts; i++) {
float co[3];
int original_index;
plConvexHullGetVertex(hull, i, co, &original_index);
if (original_index >= 0 && original_index < totvert) {
copy_v3_v3(hull_draw_data->mvert[i].co, co);
}
else {
BLI_assert(!"Unexpected new vertex in hull output");
}
}
MLoop *mloop_src = MEM_mallocN(num_loops * sizeof(MLoop), __func__);
uint edge_index = 0;
for (int i=0; i<num_loops; i++) {
int v_from;
int v_to;
plConvexHullGetLoop(hull, i, &v_from, &v_to);
mloop_src[i].v = v_from;
if (v_from < v_to) {
hull_draw_data->medge[edge_index].v1 = v_from;
hull_draw_data->medge[edge_index].v2 = v_to;
hull_draw_data->medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER;
int reverse_index = plConvexHullGetReversedLoopIndex(hull, i);
mloop_src[i].e = edge_index;
mloop_src[reverse_index].e = edge_index;
edge_index++;
}
}
/* Copy faces. */
int *loops;
int j = 0;
MLoop *loop = hull_draw_data->mloop;
for (int i=0; i<num_faces; i++) {
const int len = plConvexHullGetFaceSize(hull, i);
BLI_assert(len > 2);
/* Get face loop indices. */
loops = MEM_mallocN(sizeof(int)*len, __func__);
plConvexHullGetFaceLoops(hull, i, loops);
MPoly *face = &(hull_draw_data->mpoly[i]);
face->loopstart = j;
face->totloop = len;
for (int k=0; k<len; k++) {
MLoop src_loop = mloop_src[loops[k]];
loop->v = src_loop.v;
loop->e = src_loop.e;
loop++;
}
j += len;
MEM_freeN(loops);
}
MEM_freeN(mloop_src);
plConvexHullDelete(hull);
ob->rigidbody_object->shared->col_shape_draw_data = hull_draw_data;
}
void BKE_rigidbody_store_trimesh_draw_data(Object *ob) {
Mesh *mesh = NULL;
Mesh *trimesh_draw_data;
MLoop *mloop;
const MLoopTri *looptri;
int tottri;
int num_verts;
int num_loops;
mesh = rigidbody_get_mesh(ob);
if(mesh != NULL) {
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = mesh->runtime.looptris.len;
num_verts = mesh->totvert;
num_loops = tottri*3;
mloop = mesh->mloop;
trimesh_draw_data = BKE_mesh_new_nomain(num_verts, 0, tottri, num_loops, 0);
for(int i=0; i<num_verts; i++){
MVert *vert = &(trimesh_draw_data->mvert[i]);
copy_v3_v3(vert->co, mesh->mvert[i].co);
}
for (int i = 0; i < tottri; i++) {
/* add first triangle - verts 1,2,3 */
const MLoopTri *lt = &looptri[i];
MFace *face = &(trimesh_draw_data->mface[i]);
face->v1 = mloop[lt->tri[0]].v;
face->v2 = mloop[lt->tri[1]].v;
face->v3 = mloop[lt->tri[2]].v;
}
BKE_mesh_convert_mfaces_to_mpolys(trimesh_draw_data);
BKE_mesh_calc_edges(trimesh_draw_data, false, false);
ob->rigidbody_object->shared->col_shape_draw_data = trimesh_draw_data;
}
}
/* ************************************** */ /* ************************************** */
#else /* WITH_BULLET */ #else /* WITH_BULLET */

View File

@@ -1479,7 +1479,7 @@ static void _scan_for_ext_spring_forces(
mid_v3_v3v3(vel, sb->bpoint[bs->v1].vec, sb->bpoint[bs->v2].vec); mid_v3_v3v3(vel, sb->bpoint[bs->v1].vec, sb->bpoint[bs->v2].vec);
pd_point_from_soft(scene, pos, vel, -1, &epoint); pd_point_from_soft(scene, pos, vel, -1, &epoint);
BKE_effectors_apply( BKE_effectors_apply(
effectors, NULL, sb->effector_weights, &epoint, force, NULL, speed); effectors, NULL, sb->effector_weights, &epoint, force, NULL, speed, NULL);
mul_v3_fl(speed, windfactor); mul_v3_fl(speed, windfactor);
add_v3_v3(vel, speed); add_v3_v3(vel, speed);
@@ -2107,7 +2107,8 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene,
float eval_sb_fric_force_scale = sb_fric_force_scale(ob); float eval_sb_fric_force_scale = sb_fric_force_scale(ob);
pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint - bp, &epoint); pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint - bp, &epoint);
BKE_effectors_apply(effectors, NULL, sb->effector_weights, &epoint, force, NULL, speed); BKE_effectors_apply(
effectors, NULL, sb->effector_weights, &epoint, force, NULL, speed, NULL);
/* Apply force-field. */ /* Apply force-field. */
mul_v3_fl(force, fieldfactor * eval_sb_fric_force_scale); mul_v3_fl(force, fieldfactor * eval_sb_fric_force_scale);

View File

@@ -444,6 +444,7 @@ set(GLSL_SRC
engines/overlay/shaders/armature_wire_vert.glsl engines/overlay/shaders/armature_wire_vert.glsl
engines/overlay/shaders/background_frag.glsl engines/overlay/shaders/background_frag.glsl
engines/overlay/shaders/clipbound_vert.glsl engines/overlay/shaders/clipbound_vert.glsl
engines/overlay/shaders/constraint_angular_limits_vert.glsl
engines/overlay/shaders/depth_only_vert.glsl engines/overlay/shaders/depth_only_vert.glsl
engines/overlay/shaders/edit_curve_handle_geom.glsl engines/overlay/shaders/edit_curve_handle_geom.glsl
engines/overlay/shaders/edit_curve_handle_vert.glsl engines/overlay/shaders/edit_curve_handle_vert.glsl
@@ -513,6 +514,7 @@ set(GLSL_SRC
engines/overlay/shaders/particle_frag.glsl engines/overlay/shaders/particle_frag.glsl
engines/overlay/shaders/sculpt_mask_vert.glsl engines/overlay/shaders/sculpt_mask_vert.glsl
engines/overlay/shaders/sculpt_mask_frag.glsl engines/overlay/shaders/sculpt_mask_frag.glsl
engines/overlay/shaders/vector_vert.glsl
engines/overlay/shaders/volume_velocity_vert.glsl engines/overlay/shaders/volume_velocity_vert.glsl
engines/overlay/shaders/volume_gridlines_vert.glsl engines/overlay/shaders/volume_gridlines_vert.glsl
engines/overlay/shaders/wireframe_vert.glsl engines/overlay/shaders/wireframe_vert.glsl
@@ -581,6 +583,14 @@ if(WITH_GTESTS)
endif() endif()
endif() endif()
if(WITH_BULLET)
list(APPEND INC
../../../intern/rigidbody
)
add_definitions(-DWITH_BULLET)
endif()
blender_add_lib(bf_draw "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") blender_add_lib(bf_draw "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

File diff suppressed because it is too large Load Diff

View File

@@ -695,6 +695,7 @@ GPUShader *OVERLAY_shader_armature_stick(void);
GPUShader *OVERLAY_shader_armature_wire(void); GPUShader *OVERLAY_shader_armature_wire(void);
GPUShader *OVERLAY_shader_background(void); GPUShader *OVERLAY_shader_background(void);
GPUShader *OVERLAY_shader_clipbound(void); GPUShader *OVERLAY_shader_clipbound(void);
GPUShader *OVERLAY_shader_constraint_angular_limits(void);
GPUShader *OVERLAY_shader_depth_only(void); GPUShader *OVERLAY_shader_depth_only(void);
GPUShader *OVERLAY_shader_edit_curve_handle(void); GPUShader *OVERLAY_shader_edit_curve_handle(void);
GPUShader *OVERLAY_shader_edit_curve_point(void); GPUShader *OVERLAY_shader_edit_curve_point(void);
@@ -740,6 +741,7 @@ GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
GPUShader *OVERLAY_shader_outline_prepass_gpencil(void); GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void); GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void);
GPUShader *OVERLAY_shader_extra_grid(void); GPUShader *OVERLAY_shader_extra_grid(void);
GPUShader *OVERLAY_shader_vector(void);
GPUShader *OVERLAY_shader_outline_detect(void); GPUShader *OVERLAY_shader_outline_detect(void);
GPUShader *OVERLAY_shader_paint_face(void); GPUShader *OVERLAY_shader_paint_face(void);
GPUShader *OVERLAY_shader_paint_point(void); GPUShader *OVERLAY_shader_paint_point(void);

View File

@@ -50,6 +50,7 @@ extern char datatoc_armature_wire_frag_glsl[];
extern char datatoc_armature_wire_vert_glsl[]; extern char datatoc_armature_wire_vert_glsl[];
extern char datatoc_background_frag_glsl[]; extern char datatoc_background_frag_glsl[];
extern char datatoc_clipbound_vert_glsl[]; extern char datatoc_clipbound_vert_glsl[];
extern char datatoc_constraint_angular_limits_vert_glsl[];
extern char datatoc_depth_only_vert_glsl[]; extern char datatoc_depth_only_vert_glsl[];
extern char datatoc_edit_curve_handle_geom_glsl[]; extern char datatoc_edit_curve_handle_geom_glsl[];
extern char datatoc_edit_curve_handle_vert_glsl[]; extern char datatoc_edit_curve_handle_vert_glsl[];
@@ -91,6 +92,7 @@ extern char datatoc_extra_wire_frag_glsl[];
extern char datatoc_extra_wire_vert_glsl[]; extern char datatoc_extra_wire_vert_glsl[];
extern char datatoc_facing_frag_glsl[]; extern char datatoc_facing_frag_glsl[];
extern char datatoc_facing_vert_glsl[]; extern char datatoc_facing_vert_glsl[];
extern char datatoc_vector_vert_glsl[];
extern char datatoc_grid_background_frag_glsl[]; extern char datatoc_grid_background_frag_glsl[];
extern char datatoc_grid_frag_glsl[]; extern char datatoc_grid_frag_glsl[];
extern char datatoc_grid_vert_glsl[]; extern char datatoc_grid_vert_glsl[];
@@ -158,6 +160,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *armature_wire; GPUShader *armature_wire;
GPUShader *background; GPUShader *background;
GPUShader *clipbound; GPUShader *clipbound;
GPUShader *constraint_angular_limits;
GPUShader *depth_only; GPUShader *depth_only;
GPUShader *edit_curve_handle; GPUShader *edit_curve_handle;
GPUShader *edit_curve_point; GPUShader *edit_curve_point;
@@ -197,6 +200,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *extra_lightprobe_grid; GPUShader *extra_lightprobe_grid;
GPUShader *extra_loose_point; GPUShader *extra_loose_point;
GPUShader *facing; GPUShader *facing;
GPUShader *force_vector;
GPUShader *gpencil_canvas; GPUShader *gpencil_canvas;
GPUShader *grid; GPUShader *grid;
GPUShader *grid_background; GPUShader *grid_background;
@@ -1467,6 +1471,34 @@ struct GPUShader *OVERLAY_shader_uniform_color(void)
return sh_data->uniform_color; return sh_data->uniform_color;
} }
struct GPUShader *OVERLAY_shader_vector()
{
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
if (!sh_data->force_vector) {
sh_data->force_vector = DRW_shader_create_with_lib(
datatoc_vector_vert_glsl,
NULL,
datatoc_gpu_shader_flat_color_frag_glsl,
datatoc_common_view_lib_glsl,
"#define blender_srgb_to_framebuffer_space(a) a\n");
}
return sh_data->force_vector;
}
struct GPUShader *OVERLAY_shader_constraint_angular_limits()
{
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
if (!sh_data->constraint_angular_limits) {
sh_data->constraint_angular_limits = DRW_shader_create_with_lib(
datatoc_constraint_angular_limits_vert_glsl,
NULL,
datatoc_gpu_shader_flat_color_frag_glsl,
datatoc_common_view_lib_glsl,
"#define blender_srgb_to_framebuffer_space(a) a\n");
}
return sh_data->constraint_angular_limits;
}
struct GPUShader *OVERLAY_shader_volume_velocity(bool use_needle, bool use_mac) struct GPUShader *OVERLAY_shader_volume_velocity(bool use_needle, bool use_mac)
{ {
OVERLAY_Shaders *sh_data = &e_data.sh_data[0]; OVERLAY_Shaders *sh_data = &e_data.sh_data[0];

View File

@@ -0,0 +1,42 @@
uniform vec4 mat_vecs[4];
uniform float offset;
uniform float angle;
uniform vec3 color;
flat out vec4 finalColor;
const float PI = 3.141592653589;
const float segment_angular_width = PI * 10/180;
int n_segments = int(floor(angle/segment_angular_width));
int indices[74];
void main(void)
{
for(int i=0; i<=(n_segments); i++) {
indices[2*i] = i;
indices[2*i+1] = i+1;
}
indices[2*(n_segments+1)] = n_segments+1;
indices[2*(n_segments+1)+1] = 0;
vec4 p[37];
p[0] = vec4(0.0, 0.0, 0.0, 1.0);
for (int i = 0; i < n_segments; i++) {
p[i+1] = vec4(cos((angle * i / n_segments)+ offset), sin((angle * i / n_segments)+offset), 0.0, 1.0);
}
p[n_segments+1] = vec4(cos(angle + offset), sin(angle + offset), 0.0, 1.0);
int ind = indices[gl_VertexID%74];
vec4 transform;
mat4 mat;
mat = mat4(mat_vecs[0], mat_vecs[1], mat_vecs[2], mat_vecs[3]);
transform = mat * p[ind];
vec3 pos = transform.xyz;
finalColor = vec4(color, 1.0);
vec3 world_pos = point_object_to_world(pos);
gl_Position = point_world_to_ndc(world_pos);
}

View File

@@ -0,0 +1,39 @@
uniform vec3 objPosition;
uniform vec3 vector;
uniform float scale;
uniform float min_clamp;
uniform vec3 colour;
flat out vec4 finalColor;
vec3 verts[5] = vec3[5](vec3(0.0, 0.0, 0.0), // origin of arrow
vec3(0.0, 0.0, 0.0), // neck
vec3(0.0, 0.0, 0.0), // point on the right
vec3(0.0, 0.0, 0.0), // topmost point
vec3(0.0, 0.0, 0.0)); // point on the left
const int indices[6] = int[6](0, 3, 3, 2, 3, 4);
void main()
{
GPU_INTEL_VERTEX_SHADER_WORKAROUND
vec3 pos = vec3(0.0, 0.0, 0.0);
vec3 v = normalize(vector);
vec4 dir = ViewMatrixInverse * vec4(0.0, 0.0, -1.0, 0.0); // viewing direction
vec3 dir1 = normalize(cross(dir.xyz, v)); // perpendicular to view dir. and length of arrow
if (gl_VertexID % 6 != 0) {
verts[3] = v * length(vector) * scale + v * min_clamp; // topmost point
verts[1] = v * length(vector) * scale + v * min_clamp - v * 0.2; // neck
verts[2] = verts[1] + dir1 * 0.0866; // right side point of head
verts[4] = verts[1] - dir1 * 0.0866; // left side point of head
}
pos += verts[indices[gl_VertexID % 6]];
pos += objPosition;
finalColor = vec4(colour, 1.0);
vec3 world_pos = point_object_to_world(pos);
gl_Position = point_world_to_ndc(world_pos);
}

View File

@@ -32,6 +32,7 @@
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_node_types.h" #include "DNA_node_types.h"
#include "DNA_rigidbody_types.h"
#include "GPU_uniform_buffer.h" #include "GPU_uniform_buffer.h"
@@ -49,7 +50,6 @@ void workbench_material_ubo_data(WORKBENCH_PrivateData *wpd,
float metallic = 0.0f; float metallic = 0.0f;
float roughness = 0.632455532f; /* sqrtf(0.4f); */ float roughness = 0.632455532f; /* sqrtf(0.4f); */
float alpha = wpd->shading.xray_alpha; float alpha = wpd->shading.xray_alpha;
switch (color_type) { switch (color_type) {
case V3D_SHADING_SINGLE_COLOR: case V3D_SHADING_SINGLE_COLOR:
copy_v3_v3(data->base_color, wpd->shading.single_color); copy_v3_v3(data->base_color, wpd->shading.single_color);
@@ -74,7 +74,36 @@ void workbench_material_ubo_data(WORKBENCH_PrivateData *wpd,
default: default:
if (mat) { if (mat) {
alpha *= mat->a; alpha *= mat->a;
if(ob && ob->rigidbody_object) {
if(ob->rigidbody_object->sim_display_options & RB_SIM_STATE) {
float rbo_color_active[4] = {0.8f, 0.8f, 0.8f, 1.0f};
float rbo_color_passive[4] = {0.3f, 0.3f, 0.3f, 1.0f};
float *rbo_color;
if(ob->rigidbody_object->type == RBO_TYPE_ACTIVE){
rbo_color = rbo_color_active;
if(ob->rigidbody_object->flag & RBO_FLAG_KINEMATIC) {
rbo_color[2] += 0.2f;
rbo_color[0] -= 0.1f;
rbo_color[1] -= 0.1f;
}
}
else if(ob->rigidbody_object->type == RBO_TYPE_PASSIVE){
rbo_color = rbo_color_passive;
if(ob->rigidbody_object->flag & RBO_FLAG_KINEMATIC) {
rbo_color[2] += 0.2f;
}
}
copy_v3_v3(data->base_color, rbo_color);
}
else {
copy_v3_v3(data->base_color, &mat->r); copy_v3_v3(data->base_color, &mat->r);
}
}
else {
copy_v3_v3(data->base_color, &mat->r);
}
metallic = mat->metallic; metallic = mat->metallic;
roughness = sqrtf(mat->roughness); /* Remap to Disney roughness. */ roughness = sqrtf(mat->roughness); /* Remap to Disney roughness. */
} }
@@ -177,7 +206,6 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
color_type = V3D_SHADING_MATERIAL_COLOR; color_type = V3D_SHADING_MATERIAL_COLOR;
} }
} }
switch (color_type) { switch (color_type) {
case V3D_SHADING_TEXTURE_COLOR: { case V3D_SHADING_TEXTURE_COLOR: {
return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, sampler, datatype); return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, sampler, datatype);
@@ -200,8 +228,15 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
DRWShadingGroup **grp_mat = NULL; DRWShadingGroup **grp_mat = NULL;
/* A hash-map stores material shgroups to pack all similar drawcalls together. */ /* A hash-map stores material shgroups to pack all similar drawcalls together. */
if (BLI_ghash_ensure_p(prepass->material_hash, ma, (void ***)&grp_mat)) { if (BLI_ghash_ensure_p(prepass->material_hash, ma, (void ***)&grp_mat)) {
if(ob){
if(!ob->rigidbody_object){
return *grp_mat; return *grp_mat;
} }
}
if(!ob){
return *grp_mat;
}
}
uint32_t mat_id, id = wpd->material_index++; uint32_t mat_id, id = wpd->material_index++;
@@ -209,12 +244,14 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
workbench_material_ubo_data(wpd, ob, ma, &wpd->material_ubo_data_curr[mat_id], color_type); workbench_material_ubo_data(wpd, ob, ma, &wpd->material_ubo_data_curr[mat_id], color_type);
DRWShadingGroup *grp = prepass->common_shgrp; DRWShadingGroup *grp = prepass->common_shgrp;
*grp_mat = grp = DRW_shgroup_create_sub(grp); *grp_mat = grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_block(grp, "materials_data", wpd->material_ubo_curr); DRW_shgroup_uniform_block(grp, "materials_data", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", mat_id); DRW_shgroup_uniform_int_copy(grp, "materialIndex", mat_id);
return grp; return grp;
} }
case V3D_SHADING_VERTEX_COLOR: { case V3D_SHADING_VERTEX_COLOR: {
printf("b\n");
const bool transp = wpd->shading.xray_alpha < 1.0f; const bool transp = wpd->shading.xray_alpha < 1.0f;
DRWShadingGroup *grp = wpd->prepass[transp][infront][datatype].vcol_shgrp; DRWShadingGroup *grp = wpd->prepass[transp][infront][datatype].vcol_shgrp;
return grp; return grp;

View File

@@ -22,11 +22,13 @@
#include "DNA_curves_types.h" #include "DNA_curves_types.h"
#include "DNA_lattice_types.h" #include "DNA_lattice_types.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h" #include "DNA_meta_types.h"
#include "DNA_modifier_types.h" #include "DNA_modifier_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "DNA_particle_types.h" #include "DNA_particle_types.h"
#include "DNA_pointcloud_types.h" #include "DNA_pointcloud_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
#include "DNA_volume_types.h" #include "DNA_volume_types.h"
@@ -37,6 +39,8 @@
#include "BKE_object.h" #include "BKE_object.h"
#include "BKE_paint.h" #include "BKE_paint.h"
#include "BKE_mesh.h"
#include "BKE_lib_id.h"
#include "GPU_batch.h" #include "GPU_batch.h"
#include "GPU_batch_utils.h" #include "GPU_batch_utils.h"
@@ -113,6 +117,8 @@ static struct DRWShapeCache {
GPUBatch *drw_single_arrow; GPUBatch *drw_single_arrow;
GPUBatch *drw_cube; GPUBatch *drw_cube;
GPUBatch *drw_circle; GPUBatch *drw_circle;
GPUBatch *drw_solid_cylinder_face;
GPUBatch *drw_solid_cone_face;
GPUBatch *drw_normal_arrow; GPUBatch *drw_normal_arrow;
GPUBatch *drw_empty_cube; GPUBatch *drw_empty_cube;
GPUBatch *drw_empty_sphere; GPUBatch *drw_empty_sphere;
@@ -171,6 +177,7 @@ void DRW_shape_cache_free(void)
GPU_BATCH_DISCARD_SAFE(*batch); GPU_BATCH_DISCARD_SAFE(*batch);
batch++; batch++;
} }
} }
/** \} */ /** \} */
@@ -761,6 +768,8 @@ GPUBatch *DRW_cache_circle_get(void)
#undef CIRCLE_RESOL #undef CIRCLE_RESOL
} }
GPUBatch *DRW_cache_normal_arrow_get(void) GPUBatch *DRW_cache_normal_arrow_get(void)
{ {
if (!SHC.drw_normal_arrow) { if (!SHC.drw_normal_arrow) {
@@ -1180,6 +1189,78 @@ GPUBatch *DRW_cache_empty_cylinder_get(void)
#undef NSEGMENTS #undef NSEGMENTS
} }
GPUBatch *DRW_cache_cylinder_face_get(void)
{
#define NSEGMENTS 12
if (!SHC.drw_solid_cylinder_face) {
GPUVertFormat format = extra_vert_format();
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 3);
/* a single ring of vertices */
int v = 0;
int flag = VCLASS_EMPTY_SCALED;
float p[NSEGMENTS][2];
for (int i = 0; i < NSEGMENTS; i++) {
float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
p[i][0] = cosf(angle);
p[i][1] = sinf(angle);
}
for (int i = 0; i < NSEGMENTS; i++) {
float cv[2], pv[2];
cv[0] = p[(i) % NSEGMENTS][0];
cv[1] = p[(i) % NSEGMENTS][1];
pv[0] = p[(i + 1) % NSEGMENTS][0];
pv[1] = p[(i + 1) % NSEGMENTS][1];
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{cv[0], cv[1], 0.0f}, flag});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0f, 0.0f, 0.0f}, flag});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{pv[0], pv[1], 0.0f}, flag});
}
SHC.drw_solid_cylinder_face = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
return SHC.drw_solid_cylinder_face;
#undef NSEGMENTS
}
GPUBatch *DRW_cache_cone_face_get(void)
{
#define NSEGMENTS 8
if (!SHC.drw_solid_cone_face) {
GPUVertFormat format = extra_vert_format();
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 3);
/* a single ring of vertices */
int v = 0;
int flag = VCLASS_EMPTY_SCALED;
float p[NSEGMENTS][2];
for (int i = 0; i < NSEGMENTS; i++) {
float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
p[i][0] = cosf(angle);
p[i][1] = sinf(angle);
}
for (int i = 0; i < NSEGMENTS; i++) {
float cv[2], pv[2];
cv[0] = p[(i) % NSEGMENTS][0];
cv[1] = p[(i) % NSEGMENTS][1];
pv[0] = p[(i + 1) % NSEGMENTS][0];
pv[1] = p[(i + 1) % NSEGMENTS][1];
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{cv[0], cv[1], 0.0f}, flag});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0f, 0.0f, 0.0f}, flag});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{pv[0], pv[1], 0.0f}, flag});
}
SHC.drw_solid_cone_face = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
return SHC.drw_solid_cone_face;
#undef NSEGMENTS
}
GPUBatch *DRW_cache_empty_capsule_body_get(void) GPUBatch *DRW_cache_empty_capsule_body_get(void)
{ {
if (!SHC.drw_empty_capsule_body) { if (!SHC.drw_empty_capsule_body) {
@@ -3374,6 +3455,24 @@ GPUBatch *DRW_cache_cursor_get(bool crosshair_lines)
return *drw_cursor; return *drw_cursor;
} }
GPUBatch *DRW_cache_non_primitive_col_shape_get(Object *ob)
{
GPUBatch *geom = NULL;
if(ob->rigidbody_object->shared->col_shape_draw_data != NULL){
const DRWContextState *draw_ctx = DRW_context_state_get();
DRW_mesh_batch_cache_validate(ob, ob->rigidbody_object->shared->col_shape_draw_data);
geom = DRW_mesh_batch_cache_get_all_edges(ob->rigidbody_object->shared->col_shape_draw_data);
struct TaskGraph *task_graph = BLI_task_graph_create();
DRW_mesh_batch_cache_create_requested(task_graph, ob, ob->rigidbody_object->shared->col_shape_draw_data, draw_ctx->scene, false, false);
BLI_task_graph_work_and_wait(task_graph);
BLI_task_graph_free(task_graph);
}
return geom;
}
/** \} */ /** \} */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */

View File

@@ -97,7 +97,9 @@ struct GPUBatch *DRW_cache_empty_cube_get(void);
struct GPUBatch *DRW_cache_circle_get(void); struct GPUBatch *DRW_cache_circle_get(void);
struct GPUBatch *DRW_cache_empty_sphere_get(void); struct GPUBatch *DRW_cache_empty_sphere_get(void);
struct GPUBatch *DRW_cache_empty_cylinder_get(void); struct GPUBatch *DRW_cache_empty_cylinder_get(void);
struct GPUBatch *DRW_cache_cylinder_face_get(void);
struct GPUBatch *DRW_cache_empty_cone_get(void); struct GPUBatch *DRW_cache_empty_cone_get(void);
struct GPUBatch *DRW_cache_cone_face_get(void);
struct GPUBatch *DRW_cache_empty_capsule_cap_get(void); struct GPUBatch *DRW_cache_empty_capsule_cap_get(void);
struct GPUBatch *DRW_cache_empty_capsule_body_get(void); struct GPUBatch *DRW_cache_empty_capsule_body_get(void);
@@ -304,6 +306,8 @@ struct bGPDstroke *DRW_cache_gpencil_sbuffer_stroke_data_get(struct Object *ob);
*/ */
void DRW_cache_gpencil_sbuffer_clear(struct Object *ob); void DRW_cache_gpencil_sbuffer_clear(struct Object *ob);
/* Non primitive collision shapes */
struct GPUBatch *DRW_cache_non_primitive_col_shape_get(Object *ob);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -45,8 +45,14 @@ extern "C" {
#define BPHYS_DATA_SIZE 5 #define BPHYS_DATA_SIZE 5
#define BPHYS_DATA_TIMES 6 #define BPHYS_DATA_TIMES 6
#define BPHYS_DATA_BOIDS 7 #define BPHYS_DATA_BOIDS 7
#define BPHYS_DATA_EFF_FORCES 8
#define BPHYS_DATA_NORM_FORCES 9
#define BPHYS_DATA_FRIC_FORCES 10
#define BPHYS_DATA_VEC_LOCATIONS 11
#define BPHYS_DATA_PREV_VELOCITY 12
#define BPHYS_DATA_COLLIDING_FACES 13
#define BPHYS_TOT_DATA 8 #define BPHYS_TOT_DATA 14
#define BPHYS_EXTRA_FLUID_SPRINGS 1 #define BPHYS_EXTRA_FLUID_SPRINGS 1
#define BPHYS_EXTRA_CLOTH_ACCELERATION 2 #define BPHYS_EXTRA_CLOTH_ACCELERATION 2
@@ -63,7 +69,7 @@ typedef struct PTCacheMem {
unsigned int data_types, flag; unsigned int data_types, flag;
/** BPHYS_TOT_DATA. */ /** BPHYS_TOT_DATA. */
void *data[8]; void *data[14];
struct ListBase extradata; struct ListBase extradata;
} PTCacheMem; } PTCacheMem;

View File

@@ -26,6 +26,7 @@
#include "DNA_listBase.h" #include "DNA_listBase.h"
#include "DNA_object_force_types.h" #include "DNA_object_force_types.h"
#include "DNA_mesh_types.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -100,6 +101,10 @@ typedef enum eRigidBodyWorld_Flag {
RBW_FLAG_USE_SPLIT_IMPULSE = (1 << 2), RBW_FLAG_USE_SPLIT_IMPULSE = (1 << 2),
} eRigidBodyWorld_Flag; } eRigidBodyWorld_Flag;
typedef struct sim_data_vec {
float vector[3];
} sim_data_vec;
/* ******************************** */ /* ******************************** */
/* RigidBody Object */ /* RigidBody Object */
@@ -115,6 +120,8 @@ typedef struct RigidBodyOb_Shared {
void *physics_object; void *physics_object;
/** Collision shape used by physics sim (i.e. btCollisionShape). */ /** Collision shape used by physics sim (i.e. btCollisionShape). */
void *physics_shape; void *physics_shape;
/** Mesh used to store non pprimitive collision shapes for debug drawing. */
Mesh *col_shape_draw_data;
} RigidBodyOb_Shared; } RigidBodyOb_Shared;
/* RigidBodyObject (rbo) /* RigidBodyObject (rbo)
@@ -129,7 +136,6 @@ typedef struct RigidBodyOb {
short type; short type;
/** (eRigidBody_Shape) collision shape to use. */ /** (eRigidBody_Shape) collision shape to use. */
short shape; short shape;
/** (eRigidBodyOb_Flag). */ /** (eRigidBodyOb_Flag). */
int flag; int flag;
/** Collision groups that determines which rigid bodies can collide with each other. */ /** Collision groups that determines which rigid bodies can collide with each other. */
@@ -165,9 +171,30 @@ typedef struct RigidBodyOb {
/** Rigid body position. */ /** Rigid body position. */
float pos[3]; float pos[3];
char _pad1[4]; char _pad1[4];
/** This pointer is shared between all evaluated copies. */ /** This pointer is shared between all evaluated copies. */
struct RigidBodyOb_Shared *shared; struct RigidBodyOb_Shared *shared;
/** Options for debug drawing. */
int sim_display_options;
int display_force_types;
/** Force vectors. */
sim_data_vec eff_forces[3];
char _pad2[4];
sim_data_vec norm_forces[3];
char _pad3[4];
sim_data_vec fric_forces[3];
char _pad4[4];
sim_data_vec vec_locations[3];
/** For box, cyllinder and cone shapes. */
int colliding_faces[3];
/** Velocity */
float vel[3];
/** Previous velocity, to calculate acceleration. */
float pvel[3];
} RigidBodyOb; } RigidBodyOb;
/** #RigidBodyOb.type */ /** #RigidBodyOb.type */
@@ -220,6 +247,34 @@ typedef enum eRigidBody_Shape {
RB_SHAPE_COMPOUND = 7, RB_SHAPE_COMPOUND = 7,
} eRigidBody_Shape; } eRigidBody_Shape;
enum {
/** Display forces. */
RB_SIM_FORCES = (1 << 0),
/** Display acceleration. */
RB_SIM_ACCELERATION = (1 << 1),
/** Display velocity. */
RB_SIM_VELOCITY = (1 << 2),
/** Display magnitude as text */
RB_SIM_TEXT = (1 << 3),
/** Indicate when collisions occur. */
RB_SIM_COLLISIONS = (1 << 4),
/** Display states of rigid body. */
RB_SIM_STATE = (1 << 5),
};
enum {
/** Display gravity force. */
RB_SIM_GRAVITY = (1 << 0),
/** Display force due to effectors. */
RB_SIM_EFFECTORS = (1 << 1),
/** Display contact normal forces. */
RB_SIM_NORMAL = (1 << 2),
/** Display contact normal frictional. */
RB_SIM_FRICTION = (1 << 3),
/** Display resultant force. */
RB_SIM_NET_FORCE = (1 << 4),
};
typedef enum eRigidBody_MeshSource { typedef enum eRigidBody_MeshSource {
/* base mesh */ /* base mesh */
RBO_MESH_BASE = 0, RBO_MESH_BASE = 0,
@@ -369,6 +424,10 @@ typedef enum eRigidBodyCon_Flag {
RBC_FLAG_USE_SPRING_ANG_X = (1 << 16), RBC_FLAG_USE_SPRING_ANG_X = (1 << 16),
RBC_FLAG_USE_SPRING_ANG_Y = (1 << 17), RBC_FLAG_USE_SPRING_ANG_Y = (1 << 17),
RBC_FLAG_USE_SPRING_ANG_Z = (1 << 18), RBC_FLAG_USE_SPRING_ANG_Z = (1 << 18),
/* Debug draw constraint limits */
RBC_FLAG_DEBUG_DRAW_LIMITS = (1 << 19),
/* Fade linear limit walls when object is not close to hitting the limit. */
RBC_FLAG_DEBUG_DRAW_FADE_WALLS = (1 << 20),
} eRigidBodyCon_Flag; } eRigidBodyCon_Flag;
/* ******************************** */ /* ******************************** */

View File

@@ -591,6 +591,7 @@ extern StructRNA RNA_ShapeKeyCurvePoint;
extern StructRNA RNA_ShapeKeyPoint; extern StructRNA RNA_ShapeKeyPoint;
extern StructRNA RNA_ShrinkwrapConstraint; extern StructRNA RNA_ShrinkwrapConstraint;
extern StructRNA RNA_ShrinkwrapModifier; extern StructRNA RNA_ShrinkwrapModifier;
extern StructRNA RNA_sim_data_vec;
extern StructRNA RNA_SimpleDeformModifier; extern StructRNA RNA_SimpleDeformModifier;
extern StructRNA RNA_SimplifyGpencilModifier; extern StructRNA RNA_SimplifyGpencilModifier;
extern StructRNA RNA_Simulation; extern StructRNA RNA_Simulation;

View File

@@ -861,6 +861,14 @@ static PointerRNA rna_RigidBodyWorld_PointCache_get(PointerRNA *ptr)
#else #else
static void rna_def_rigidbody_sim_data(BlenderRNA *brna)
{
StructRNA *srna;
srna = RNA_def_struct(brna, "sim_data_vec", NULL);
RNA_def_struct_sdna(srna, "sim_data_vec");
}
static void rna_def_rigidbody_world(BlenderRNA *brna) static void rna_def_rigidbody_world(BlenderRNA *brna)
{ {
StructRNA *srna; StructRNA *srna;
@@ -1203,6 +1211,63 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
prop, "Collision Collections", "Collision collections rigid body belongs to"); prop, "Collision Collections", "Collision collections rigid body belongs to");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset"); RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
/* sim data display options. */
prop = RNA_def_property(srna, "display_forces", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sim_display_options", RB_SIM_FORCES);
RNA_def_property_ui_text(prop, "Forces", "Display forces acting on rigid body");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "display_acceleration", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sim_display_options", RB_SIM_ACCELERATION);
RNA_def_property_ui_text(prop, "Acceleration", "Display acceleration of rigid body");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "display_velocity", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sim_display_options", RB_SIM_VELOCITY);
RNA_def_property_ui_text(prop, "Velocity", "Display velocity acting on rigid body");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "display_data_text", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sim_display_options", RB_SIM_TEXT);
RNA_def_property_ui_text(prop, "Text", "Display the magnitudes of the vectors as text");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "display_collisions", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sim_display_options", RB_SIM_COLLISIONS);
RNA_def_property_ui_text(prop, "Collisions", "Indicate when collisions occur");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "display_state", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sim_display_options", RB_SIM_STATE);
RNA_def_property_ui_text(prop, "State", "Active/Passive/sleeping");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "show_gravity", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "display_force_types", RB_SIM_GRAVITY);
RNA_def_property_ui_text(prop, "Gravity", "Display the force of gravity");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "show_effectors_force", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "display_force_types", RB_SIM_EFFECTORS);
RNA_def_property_ui_text(prop, "Effectors", "Display the forces aplied by effectors");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "show_normal_force", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "display_force_types", RB_SIM_NORMAL);
RNA_def_property_ui_text(prop, "Normal forces", "Display contact normal forces");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "show_frictional_force", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "display_force_types", RB_SIM_FRICTION);
RNA_def_property_ui_text(prop, "Frictional forces", "Display contact frcitional forces");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "show_net_force", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "display_force_types", RB_SIM_NET_FORCE);
RNA_def_property_ui_text(
prop, "Resultant force", "Display the net force acting on the rigid body");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
} }
static void rna_def_rigidbody_constraint(BlenderRNA *brna) static void rna_def_rigidbody_constraint(BlenderRNA *brna)
@@ -1369,6 +1434,16 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Linear Motor", "Enable linear motor"); RNA_def_property_ui_text(prop, "Linear Motor", "Enable linear motor");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "debug_draw_limits", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_DEBUG_DRAW_LIMITS);
RNA_def_property_ui_text(prop, "Visualise Limits", "Display the limits imposed by the constraint");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "debug_draw_fade_walls", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_DEBUG_DRAW_FADE_WALLS);
RNA_def_property_ui_text(prop, "Fade walls", "Fade the linear limit walls when object is not close to them");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "use_motor_ang", PROP_BOOLEAN, PROP_NONE); prop = RNA_def_property(srna, "use_motor_ang", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_MOTOR_ANG); RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_MOTOR_ANG);
RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_use_motor_ang_set"); RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_use_motor_ang_set");
@@ -1597,6 +1672,7 @@ void RNA_def_rigidbody(BlenderRNA *brna)
rna_def_rigidbody_world(brna); rna_def_rigidbody_world(brna);
rna_def_rigidbody_object(brna); rna_def_rigidbody_object(brna);
rna_def_rigidbody_constraint(brna); rna_def_rigidbody_constraint(brna);
rna_def_rigidbody_sim_data(brna);
} }
#endif #endif

View File

@@ -738,7 +738,8 @@ static void cloth_calc_force(
&epoint, &epoint,
forcevec[i], forcevec[i],
winvec[i], winvec[i],
nullptr); nullptr,
NULL);
has_wind = has_wind || !is_zero_v3(winvec[i]); has_wind = has_wind || !is_zero_v3(winvec[i]);
has_force = has_force || !is_zero_v3(forcevec[i]); has_force = has_force || !is_zero_v3(forcevec[i]);