1
1

Compare commits

...

949 Commits

Author SHA1 Message Date
32b13c13af fix typo in last commit 2008-09-22 00:00:38 +00:00
9f802038b6 This should convert branch fluidcontrol files to trunk compatible ones 2008-09-21 23:50:36 +00:00
518b8fe018 svn merge -r 16593:16648 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-21 13:03:39 +00:00
92829e821f Bugfix #17656
- Changed order for applying atmosphere, it does it now before alpha-adding
  sky, giving correct transparency
- Added correction for de-premulling and premulling scatter color
2008-09-21 12:03:41 +00:00
f7a5288111 #bugfix #17337
FSA didn't work for atmosphere option.
2008-09-21 10:31:22 +00:00
a9988317c9 Added select grouped property (objects with shared property names will be selected)
(updated select group toolbox and header menu)

Added 2 copy property options - Replace All and Merge All, since there was no way to remove all properties, or set all objects game properties to be the same as the active objects.
Added set_ob_property(ob, prop) to property api.

bugfix in python api, copyAllPropertiesTo, it didnt check for duplicates or that it wasnt copying from/to the same object.
2008-09-21 10:12:33 +00:00
e11cd5a962 game engine now compiles with SDL disabled. CDROM and Joystick wont function in this case 2008-09-21 05:38:28 +00:00
2064f5542a set the visibility state based on the objects render option in the outliner.
- saves adding UV's to faces just to set the invisibility option or having an logic bricks to set the visibility state.
2008-09-21 04:39:40 +00:00
deba5ab9a7 encountered some issue with the btDbvtBroadphase, switch of a deferred collision feature. 2008-09-21 01:13:54 +00:00
2941f755f7 attempt to support negative local scaling for convex hull, box,sphere, cylinder, cone and btScaledBvhTriangleMeshShape in Bullet. 2008-09-20 23:45:45 +00:00
877d70b14a fixed sphere-sphere collision: contact points were not properly removed/refreshed. 2008-09-20 22:34:54 +00:00
a72b65011e BGE bug fix: dupligroup scale not correctly applied to bullet shape. 2008-09-20 22:19:59 +00:00
22a50402ef BGE patch: allow Bullet mesh shape sharing for objects copied with ALT-D. 2008-09-20 21:33:54 +00:00
768e12a064 Patch #17631 by Early Ehlinger
His log:
One of the calls to PIL_dynlib_get_error_as_string was assuming that 
it would return a valid string and not NULL (perhaps by converting
to std::string).
This patch simply changes it to always return a string, even when the 
error is not recognized.
2008-09-20 14:43:59 +00:00
0a364788c1 simple changes for bez point selection. use as a flag incase other flags are stored in bezt->f1,2,3 2008-09-20 13:21:10 +00:00
2bd6e1ae82 Patch #8461, by Rob Hausauer
This unifies all usage of FTOCHAR, putting it in utildefines.h
Submitter did several interesting tests for speed, check it here:
http://projects.blender.org/tracker/?func=detail&atid=127&aid=8461&group_id=9
2008-09-20 13:02:06 +00:00
63f10e6b55 Patch 17403, small gcc warning fixes. 2008-09-20 12:28:01 +00:00
9b9edad6b6 Patch 17403, small gcc warning fixes. 2008-09-20 12:26:18 +00:00
3dbdd8939b 16624 was incorrect. Blender wont always give the requested name for new datablocks or for renaming. scripts need to account for this. 2008-09-20 11:54:27 +00:00
f510057fef [#17600] char* -> const char*
Thanks to Sean Bartell (wtachi), was causing many many warnings which distracted from the real problems.
2008-09-20 11:08:35 +00:00
a12375cb4f PyAPI - *.insertkey()
Updated insertkey calls in PyAPI so that they behave like the new common_insertkey() behaviour.
2008-09-20 10:30:10 +00:00
224607982a Python api access to obcolor
Option to copy obcolor in the copy menu
Option to select same color in select grouped menu
console.py - mistake in last commit caused a python error
2008-09-20 10:11:42 +00:00
c282178411 Patch #17654: Fix for Scene.Get with input >20 chars
Patch by Darryl Pogue (paradox).

Blender cuts off datablock names at 20 chars, which causes issues if you're trying to access Scenes with a string longer
than 20 chars.

Ex.

s = 'GuildPub-Writers_GLOBAL'
Blender.Scene.New(s) #This creates the scene "GuildPub-Writers_GLOB"
Blender.Scene.Get(s) #This throws an error: the name and the string don't match

This patch cuts down the input of Scene.Get() to the 20 char limits, thus making the the above example return the correct
scene.
2008-09-20 10:10:50 +00:00
e7c62e9038 Bugfix #17652: "K" mode for controlling keys and drivers cause crashes
When using a transform and there didn't exist an IPO-channel for that transform's focus (i.e. no rot curves when rotating) and "K" mode was active, there would be a crash due to missing checks for such situations.
2008-09-20 10:02:13 +00:00
415868b5e2 Fix for gcc compiler warning about a call to do_lamp_tex() resulting in "overflow in implicit constant conversion" 2008-09-20 09:17:40 +00:00
4d551c0a0d Text.c
- calling Text_reset within C/Api funcs didnt decref the Py_None Text_reset returned.
 - Text_delete wasnt checking if the input was an int.
 - a number of functions wernt checking if the text was removed.
console.py
 - added clear output
 - command history leaves empty command before wrapping
 - add imports as dummy user input so commands written to a text file will run.
 - faster writing of output to a textblock.
2008-09-20 04:37:10 +00:00
5f3c4edb8f == Outliner ==
Commit patch #8195

New outliner mode: Sequence, it's show all the sequence and strip that
we have in the outliner, split it for type (particle, sound and so on..).

Some notes to take care:
 * The strip can be selected with LMB
 * The sequence can be deleted with XKEY (all the selected)
 * The "Meta" are stored in a single tree (Meta Strip)
   with all the sequence.
 * Duplicate sequence (with the same name) are store in a single tree
   and you can select all the Sequence with LMB in the "root" entry.
 * Also show the directory path.

[ As Ton point in the tracker, still need more work (and options, Luca made
  a really good list in the tracker), so move to the trunk and start
  working here, probably a good topic for next meeting. ]
2008-09-19 22:51:05 +00:00
a15296eff6 Small dependency debugging aid: now it also prints cycles for
the object depsgrah instead of only armatures.
2008-09-19 22:03:16 +00:00
4f737bafa7 == Render ==
Commit patch #7788, allow to set the render step, so it's
possible make render every N frames only.

The step is change in Scene buttons (F10), below start and
end frame buttons.

Also add a command line options (-j), so it's possible to
overwrite the file step (useful for renderfarm).

[ Brecht, this work with OpenGL renders and simulated
  the skipped frames, please double check ]
2008-09-19 21:57:15 +00:00
650ae3b4e6 Fix for bug #16662: modifiers on lattices were ignored sometimes
when rendering opengl previews, it unnecessarily cleared lattice
displists when it was really intended for shaded mode colors.
2008-09-19 21:52:15 +00:00
Ken Hughes
4693a5af48 Linux platforms
---------------
Patch to include freedesktop icons in linux release builds, contributed by
Ralf Hölzemer (cheleb).
2008-09-19 21:00:45 +00:00
a44177a401 BGE patch: new 'Advanced Settings' button to keep special Bullet options away from main UI.
Three features that were on the main UI interface are now 
moved to the Advanced Settings panel:
Margin, Actor (that becomes Sensor Actor) and No sleeping.

Sensor Actor is now a feature: it can be turned on and off
for all types of objects, and not just static objects.
Select the Sensor Actor button to make the object visible
to Near and Radar sensor.
The button is selected by default for dynamic objects
and unselected by default for static objects, to match
previous behavior.
2008-09-19 20:41:38 +00:00
00ed5a2cc9 Patch #17348 by Roger Wickes
Fix in Bake Constraints script, better naming for new object.
2008-09-19 20:22:54 +00:00
905983229a == Python Space Handlers ==
Patch #9673: "Short patch to make spacehandler event scripts work more like normal python gui script handlers" by Steven Truppe:
http://projects.blender.org/tracker/?func=detail&atid=127&aid=9673&group_id=9

This patch adds the Blender.eventValue variable available for space handlers, holding the event value (aka 1 for button and key presses, X or Y coordinate for mousex / mousey movement). Thanks, Steven. PS: this doesn't break existing scripts.
2008-09-19 18:53:05 +00:00
0f6fc0b207 Fix again for the NVidia driver bug. This time I'm just giving up
using linking together the precompiled library shader code and
material code and recompiling it all again for each material even
if it gives a performance hit, since the previous workaround only
worked on some driver versions still.
2008-09-19 16:09:26 +00:00
65ddef19b9 Patch #13422, By Roland Hess, Shadow Color
Finally, after a long time new render candy for the non-game peoples! :)

Good doc is here: (url splits in two)
http://www.harkyman.com/2008/08/06/controllable-shadow-intensity-
and-color/

Note the colorpicker for shadow is in "Shadow and Spot" panel. A bit
hidden, could get more attention. For later. :)
2008-09-19 16:01:22 +00:00
a0504ac922 Patch #8213 by Shunichi Fuji
Fixes crash with FT fonts in some cases, just removed unnused line of code.
2008-09-19 14:18:41 +00:00
6f9a254d61 PyConstraints:
Basic (non-python) target evaluation still occurs when scriptlinks are disabled.
2008-09-19 12:43:21 +00:00
ef8a1dccc7 Bugfix #17643: Action Editor buffer copy/paste not working
Removed superfluous check for destination IPO-block/IPO-curve which may not have existed. This meant that pasting keyframes into an "empty" Action Channel sometimes failed.
2008-09-19 12:41:26 +00:00
9c27e097df == IPO Defines Cleanup ==
Just a bit of tidyup for IPO header-files. 

Warning:
Moved IPO Curves + Drivers out of DNA_curve_types.h
2008-09-19 12:33:17 +00:00
15bce017df scons update, BF_NO_ELBEEM wasnt working, WITH_BF_SDL wasnt implimented, WITH_CCGSUBSURF isnt used anymore. 2008-09-19 01:39:34 +00:00
6ff74f4527 == Python Script Links ==
Bug #17599:
Summary: Python constraints, good in 2.46 not working anymore in 2.47
http://projects.blender.org/tracker/?func=detail&atid=125&aid=17599&group_id=9

Improved my old hack to avoid frame changed scriptlinks from running when rendering stills, should fix this bug. It also causes REDRAW scriptlinks to be executed during renders, but that conforms to how FRAMECHANGED ones work.

BTW: this can still be improved. The current system meant to disable all Python functionality at once needs imo to be replaced by one that allows to enable / disable per feature (scriptlinks, pyconstraints, pynodes, etc.). A better way to inform scriptlinks about what is going on (render, anim, render anim, etc.) would also help. Will discuss with others.
2008-09-18 22:33:49 +00:00
ec6bd008c1 fixing scons build. needed BoolOption in argument definition 2008-09-18 21:18:53 +00:00
5f25e52c20 [#7297] Fix knife visualization on MacMini Intel w/ Intel gfx 2008-09-18 20:37:11 +00:00
02a91ac784 BGE patch: change constraint location actuator to work in local coordinates. It won't change anything for root objects but will be of some use for child objects. 2008-09-18 19:28:28 +00:00
a283e7e4af A typo in my fix for bug #11740 caused problems with at least grid distributed particles. 2008-09-18 17:42:17 +00:00
f7113fd267 Reactor particles were born with incorrect timing. Some changes made could effect normal particles too, but after many tests I didn't notice any adverse effects. Be sure to poke me hard if there are some though :) 2008-09-18 17:19:40 +00:00
6b7b812208 This file did not compile, but is also not part of the build target...
Fixed neverheless, patch #6258 from Early Ehlinger
2008-09-18 16:43:31 +00:00
fc312fae98 svn merge -r 16454:16593 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-18 14:59:44 +00:00
423b053904 Grease Pencil - Stroke Sensitivity:
Sensitivity to mouse movement when drawing can now be customised in the User Prefs, under 'Edit Methods'.
2008-09-18 11:49:57 +00:00
8d1163c639 scons options BF_CXX, WITH_BF_STATICCXX, BF_CXX_LIB_STATIC for static linking to stdc++ because of problems running blender on some systems. 2008-09-18 03:05:02 +00:00
beb7738a29 Hopefully fixes crash in particle system with effector enabled 2008-09-18 01:55:43 +00:00
0a7767d597 Fix for bug #3858: the game engine mouse focus sensor did not work
correct if there was more than one camera. It shoots rays from the
active camera, but used the viewport from whichever camera was drawn
last, now it uses the correct vieport.
2008-09-18 01:46:28 +00:00
3bf0a6fed8 This adds support for the new-ish options:
QUATERNION
B_BONE_REST
INVERT_VERTGROUP
MULTIMODIFIER

to the bpy armature modifier API.

It also fixes a significant problem - In the docs, it refers to 
the 'VERTGROUP' field as being a string value, shared
by lattice, armature, etc, referring to the 'VGroup' field in the 
armature modifier that defines a vertex group 'mask'
which the armature's effect is restricted to.

However, previously, for some very mistaken reason, in processing 
the getters/setters for the armature modifier, the
VERTGROUP field was pointing to the quite different 'Vert. Groups' 
toggle in the armature modifier, that enables or
disables using vertex groups for deformation (as opposed to 
envelopes).

I've fixed this, so VERTGROUP points to the VGroup string, as is 
already defined in the docs and consistent with other
modifiers like Lattice. A new field: 'VGROUPS' has been added, 
which is the analog to the 'Vert Groups' toggle.
2008-09-18 00:51:51 +00:00
7e6c1e1091 needed these changes to get bullet building with cmake and linking with scons 2008-09-18 00:10:12 +00:00
067a890d82 BGE bug #17578: repair linV actuator in Add+Local mode. 2008-09-17 21:47:05 +00:00
0c1ec934c6 Update MSVC project file to include BulletSoftBody 2008-09-17 21:14:48 +00:00
80f22a9e60 added another missing file, btHashMap 2008-09-17 20:02:20 +00:00
8b73f35141 added src/LinearMath/btConvexHull.cpp 2008-09-17 19:58:16 +00:00
015a42079c Please add extern/bullet2/src/LinearMath/btConvexHull.cpp to your build system!
Reverted back to original Bullet version.
2008-09-17 19:47:26 +00:00
0a6d2e26a9 Fix for [#17642] Particule Hair - Vertex Group lenght don't works without Children
- This feature had been removed from the code! So this is how things work now:
For normal (non-child) hair particles the length vgroup is used if we're not in particle edit mode and if there are no child particles. So for example checking "Parents" in the visualization panel when children are in use will result in full length parent strands, this is a feature so that you can see how the parent's go to predict child behavior better, not a bug :)
2008-09-17 19:29:44 +00:00
0a43036701 Fix for [#17637] Children from "Faces" in Object without a face leads to crash
- a simple check for psys->child was missing
2008-09-17 17:59:29 +00:00
3ecbcb5848 Bugfix #14412
Outliner option 'unlink group' didn't remove its members, in case the
group members were local in file, a confusing situation happened. Now
it removes members.
2008-09-17 17:47:59 +00:00
b4e4ffc0b8 Fix for bug #17634: crash on automatically removing zero size window. 2008-09-17 16:59:52 +00:00
2b6aea2009 Added BulletSoftBody as target for Makefile installing of .h files 2008-09-17 11:31:03 +00:00
bbdcd3a082 rev 16569 broke building.
Looks like bullets Extras/ConvexDecomposition is missing from blenders source.
comment functions so it builds for now.
2008-09-17 11:23:28 +00:00
f0e0e6b1c9 * Some tweaks to the OBJ importer/exporter after chatting with Campbell
- renamed the 'morph target' option to 'keep vertex order'
- enabled 'keep vertex order' by default

This should improve usability for importing and exporting shape keys, point caches, mdds ,etc.
2008-09-17 04:07:58 +00:00
36e2004fca Delete Keyframe Tool:
* Changed hotkey to Alt-I. As a result, Remove IK is now Ctrl-Alt-I, though that shouldn't affect many people at all as it appears that hardly anyone uses it.

* Added menu entries for Delete Keyframe
2008-09-17 04:06:59 +00:00
4cd85aa61c Texture_getHFracDim was returning an int rather then a float (thanks zuegs for spotting)
removed unused var
2008-09-17 03:13:15 +00:00
651c0e4861 Applied some fixes from Bullet: issues with btDbvtBroadphase, and btSoftBody, and better fix for 64-bit issue in btCompoundCollisionAlgorithm. 2008-09-17 02:30:19 +00:00
ae418491dc Preparation for real-time soft bodies for the game engine, step 1 out of 3. This should be harmless/non-intrusive.
Please make sure each build system include extern/bullet2/src/BulletSoftBody/* and extern/bullet2/src/LinearMath/btConvexHull.*
2008-09-17 01:49:47 +00:00
9064ed8d6a Fix for bug #4192: game engine armatures that are dynamically added
but don't have an action got the pose of already added armatures, even
though they're not related. This also fixes an issue where the armature
in Blender would end up in the pose from the game after ESC, removes
unneeded copies made during armature evaluation, and also solves the
constraint copying hack.
2008-09-17 01:29:54 +00:00
9b7d40dbae BGE patch: bullet buttons UI change after discussion with Erwin: use a drop down instead of a series of buttons. Introduction of soft body option. 2008-09-16 22:52:42 +00:00
Nathan Letwory
73c8d76ba4 * make BulletSoftBody own small lib to make sure bullet libs don't grow too large for our beloved scons/mingw users. 2008-09-16 21:23:56 +00:00
0cae815127 Fix for [#17561] when i try to change the particle to hair I cant choose group or object as viz.
-Partly reverted Genscher's previous fix on the issue and added the idea he had as a special case
2008-09-16 21:16:32 +00:00
73fd800077 Fix for bug #5413: game engine armature actions and shapes keys
didn't work correct with scene suspend/resume, now works the same
as IPO's.
2008-09-16 21:11:38 +00:00
0c77a178da add BulletSoftBody to SConscript and Makefile 2008-09-16 21:09:24 +00:00
5941411839 add src/BulletSoftBody/* to cmake (other build systems also will need to do this soon) 2008-09-16 20:52:38 +00:00
99cd0dd5d5 Fix bug that broke editing vertices through python in the game engine. 2008-09-16 19:28:54 +00:00
c6d0be2a99 Fix (harmless) error print about GameLogic.globalDict being lost. Also
fixed some memory leaks in this code and simplified it.
2008-09-16 19:25:35 +00:00
75685a9ca8 == Transform Snap ==
Tighten test for excluding objects as snap target.

Now exclude all object that are themselves moving (that includes childs of selected objects) as well as objects with moving geometry (like hooked meshes).

The previous situation would cause unfrequent bugs, but especially present in alignment cases (those concerned will understand).
2008-09-16 19:10:58 +00:00
0922ecee93 "Fix" for #17636 Crashing bug - won't open a file
- The cause was indeed corrupted particle settings which should have caused a deletion of the whole particle system. However the particle modifier was still left and that led to the crash.
- A "fix" because there's really no way of knowing what caused the corruption of the particle settings. If anyone else gets this and can recreate I'd love to get a .blend. Now that there shouldn't be a crash anymore the symptom will be a missing particle system after file load in an object that had a particle system before.
2008-09-16 18:40:54 +00:00
80458f69b2 Added check for failing linking of a ID_PA block. 2008-09-16 16:20:51 +00:00
8cd673fdfb Bugfix #17633
Tiny feature: "Flip normals" in editmode also recalculates vertex normals.
2008-09-16 15:28:07 +00:00
7350d71b66 Bugfix #17630: objects are disappearing if you insert a layer key and then change time
Forgot to set type of data for inserting keyframes, so data was probably written as float or so.
2008-09-16 06:55:15 +00:00
18cda1583d Bugfix #17622: clicking on action IPO in outliner causes crash
In some cases, no action channels existed, but yet the Outliner displayed some that, when clicked on, would cause a crash.
2008-09-16 06:33:59 +00:00
0f39be9ce8 added static openal and openexr options for scons.
also added a target 'blenderlite' - turns almost everything off, compressed binary is ~3.4meg
2008-09-16 06:31:55 +00:00
5df9b4938e Bugfix #17627: Autokeyframe for Visual keying
Several months old typo! 'Visual keying' was not working for autokeyframing, as the test for it didn't even work.
2008-09-16 06:11:02 +00:00
9031ef3e87 Fix for bug #12028: background rendering on Mac OS X without
a window manager did not work anymore since 2.46.
2008-09-16 02:58:33 +00:00
4683cb34e4 Fix for #17618 Particles: changing RGB sliders snap back
-particle drawing was reading material ipos in a too invasive way
2008-09-15 22:08:30 +00:00
f807d3f303 BGE bug #17565 fixed: Constraint Actuator Location: GUI broken. Axis selection was not persistent, now it is. 2008-09-15 21:37:27 +00:00
95afafb5e5 BGE bug #17621 fixed: State Actuator GUI Flaw. State actuator didn't behave like the object state mask. Now it works the same: LMB select one state, deselects all others, multiple select with SHIFT-LMB 2008-09-15 21:10:51 +00:00
aae506aea7 Small fix in GHOST X11 system.
* Fix and a little of cleanup to the full screen, minimzed and
  maximized code.

* Fix bad argument in the ClientMessage event to support the
  _NET_ACTIVE_WINDOW property.

* Fix focus problem in some WM (like TWM), this is because Blender
  don't set the WM_PROTOCOLS list, now it does, a very basic list
  but it's what we need now.
2008-09-15 18:23:34 +00:00
35c269e395 Workaround for an Nvidia driver bug on 32 bit linux (maybe windows too).
I reversed the order of attaching shader objects for linking to solve an
issue in the driver before, but now it appears it needs to be the other
way around again? I don't know if these are the same cards that now want
it different again due to changes in the glsl code, but I found another
workaround for the first bug in a forum post (leaving out parameter names
in the declarations), so with some luck both cases work?

http://developer.nvidia.com/forums/index.php?showtopic=596
2008-09-15 18:15:11 +00:00
cffba77f50 Small tweak to get things compiling again.
Kent
2008-09-15 15:58:50 +00:00
dc2594c81b Added -d debug option for blenderplayer, and remove some
invalid/unnecessary opengl calls on shader errors.
2008-09-15 12:40:17 +00:00
fd3a40a129 Fix glsl vertex shader string that was not 0 terminated, no idea
if it caused any problems.
2008-09-15 11:39:49 +00:00
e5ce1e962d copy menu didnt copy visible and initial states, physics margin was also missing from "all physical attributes" option 2008-09-15 09:24:54 +00:00
a08b21263e tooltip improvements from dfelinto, some minor edits 2008-09-15 09:08:36 +00:00
ec30a3a470 Delete Key Tool - Bugfixes:
* Available option would crash
* 'Visual' options are now not available for this tool (are not relevant)
2008-09-15 04:15:37 +00:00
89721ec4de replaced static make_absolute_filename with BLI_convertstringcwd 2008-09-15 02:18:37 +00:00
ac86c04401 added BLI_convertstringcwd, used so command line blendfiles and python scripts can be relative to the current path.
- was alredy doing this for blendfiles, but better to have in its own function.

header_text.c - renamed PATH_MAX, was defined by system includes.
2008-09-15 01:32:53 +00:00
2c31cc4503 Fix for bug #17620: the motion blur actuator did not work correct
with an always sensor, it kept resettting the motion blur each frame.
2008-09-15 00:57:11 +00:00
a24960daa8 Fix for bug #4859: once a visibility actuator was set it was not
possible to change the visibility again through python for example.
This is because the actuator kept setting the visibility again each
frame, as a workaround for there being no separate visible and
viewport culling flag, but that was added some time ago.
2008-09-15 00:34:43 +00:00
3b153f887a Fix zoom level and clipping to be consistent with the viewport
when pressing P without a camera active, now it should match
the view exactly.

Fix an issue when setting a camera with an actuator and being
in orthographic mode in the viewport without an active camera,
it used a strange mix of the set camera and the viewport then.
2008-09-15 00:11:30 +00:00
f554f14329 Fix for bug #17617: GLSL shaders change vertex color unexpectedly. 2008-09-14 21:31:07 +00:00
41a0b56b70 BGE patch: new Physics button and margin parameter in Logic panel. Change subversion.
The Physics button controls the creation of a physics representation 
of the object when starting the game. If the button is not selected,
the object is a pure graphical object with no physics representation
and all the other physics buttons are hidden.
Selecting this button gives access to the usual physics buttons.
The physics button is enabled by default to match previous Blender
behavior.

The margin parameter allows to control the collision margin from
the UI. Previously, this parameter was only accessible through 
Python. By default, the collision margin is set to 0.0 on static 
objects and 0.06 on dynamic objects. 
To maintain compatibility with older games, the collision margin
is set to 0.06 on all objects when loading older blend file.

Note about the collision algorithms in Bullet 2.71
--------------------------------------------------
Bullet 2.71 handles the collision margin differently than Bullet 2.53
(the previous Bullet version in Blender). The collision margin is 
now kept "inside" the object for box, sphere and cylinder bound 
shapes. This means that two objects bound to any of these shape will
come in close contact when colliding. 
The static mesh, convex hull and cone shapes still have their
collision margin "outside" the object, which leaves a space of 1
or 2 times the collision margin between objects. 

The situation with Bullet 2.53 was more complicated, generally
leading to more space between objects, except for box-box collisions. 

This means that running a old game under Bullet 2.71 may cause
visual problems, especially if the objects are small. You can fix
these problems by changing some visual aspect of the objects: 
center, shape, size, position of children, etc.
2008-09-14 19:34:06 +00:00
7762100fcb Update MSVC project and fix compilation problem in VS2003 with keyframing.c 2008-09-14 19:07:57 +00:00
59b202fc32 Fix a game engine crash with mesh objects parented to an armature
without vertex groups.
2008-09-14 17:59:22 +00:00
0ad48b7332 scons option for linking python statically - useful for building a more compatible blenderplayer, where most games python scripts only use builtin modules anyway. 2008-09-14 17:56:15 +00:00
9444b314db fix for what looks like simple mistake, function wasnt returning any values (compiler warning) and the variable being checked to return a value was never assigned. 2008-09-14 17:19:59 +00:00
2eb8eb4e7e Bugfix: avoid crash with too long pathname. 2008-09-14 16:22:03 +00:00
Ken Hughes
6977816ff3 Python API
----------
Fix C90 mixed declarations and code.
2008-09-14 14:17:44 +00:00
4245aaed86 == Global 'Delete Key' Tool ==
The 'opposite' of the "Insert Key" tool. 
- Use the hotkey Ctrl-Alt-IKEY to activate.
- Only available in 3d-view and buttons window 

I've added an extra var to verify_ipo and verify_ipocurve to save having to make another duplicate of that code. Hopefully the gameengine compiles ok with this.
2008-09-14 12:41:42 +00:00
2bf26b93e1 Bugfix #17608
Fileselect window:
Pressing X to remove a file should not work in databrowse view.
2008-09-14 09:09:10 +00:00
375a6bbe41 More bugfixes:
* Added missing includes
* Fixed typos in header
* Added code to get ipo for 'Available' keyingsets to work
2008-09-14 05:52:57 +00:00
b25d0cc5cc game engine didnt compile with recent keyframing changes 2008-09-14 05:42:05 +00:00
1a917f50a6 running scripts in background mode would crash in some cases. (tested all scripts, none segfault now) 2008-09-14 05:10:45 +00:00
0f1a1a159f == Keyframing - Cleanup of API ==
* Moved all keyframing functions to their own file (keyframing.c)

* Merged all the different keyframing options (needed, visual, fast) into a single API call. The direct benefit of this is that it allows them to be used in conjunction with each other. Also, this means that when using the IKEY, autokeying settings for these are respected too.

* Implemented 'keyingsets' system (instead of directly calling insertkey on relevant channels), which is easier to maintain and cleaner. A keyingset basically defines all the channels that can be keyframed together. This paves the way for custom keyingsets sometime down the track (and also for quick-insert keyframes for previously used keyingset).

Menus for choosing the keying set to use are generated automatically from the definitions.
2008-09-14 04:32:17 +00:00
d111983064 Fix for bug #5758 and #17585: armatures with IK constraint did not
work in the game player, now the IK lib is linked into the player.

Makefiles/Scons/CMake buildsystems have been updated.

Fix materials nodes to work in the game player.
2008-09-14 03:51:51 +00:00
c4cde9a027 Fix for bug #7097: blender multitexture materials in the game engine
player did not enable mipmapping when falling back to texfaces.

Also commented out code that disabled mipmapping in the player on
Mac OS X. If that is a workaround for a bug it is a really poor one,
and hopefully fixed now since this code is from 2002 or earlier.
2008-09-14 01:10:45 +00:00
704fef314a Various game engine fixes:
* Fix issue with add transparency mode with blender materials.
* Possible fix at frontface flip in the game engine.
* Fix color buffering clearing for multiple viewports, it used
  to clear as if there was one.
* Fix for zoom level in user defined viewports, it was based on
  the full window before, now it is based on the viewport itself.
* For user defined viewports, always use Expose instead of
  Letterbox with bars, the latter doesn't make sense then.
2008-09-14 00:32:18 +00:00
06be41648f Fix for #11740 - Reactor particles do not render in animation.
- Particle data was deleted when the current frame was outside the baked range. Reactor particles need this data to store birth and death times.
2008-09-13 21:06:22 +00:00
fa825e70e3 Game engine: added Rasterizer.get/setMaterialMode to set texface,
multitexture or glsl materials. This does not affect existing
scenes, only newly created ones.
2008-09-13 19:19:51 +00:00
d2186508da Particle collisions upgrade:
- Particle now use the deflector objects collision modifier data to collide with deflectors and as a result can now use the velocity of the colliding object for more realistic collisions.
- Dynamic rotations are also quite a bit more realistic and are related to the friction setting of the deflector (to get any dynamic rotations there has to be some friction). This is largely due to the separate handling of rolling friction (approximated to be 1% of normal sliding friction).
- Collisions should be a bit faster on complex deflectors due to the tree structure used by the collision modifier.
- Collision should also generally be a bit more accurate.

To be noted: Only the average velocity of individual deflector faces is used, so collisions with rotating or deforming objects can't be handled accurately - this would require much more complex calculations. Subdividing the deflector object surface to smaller faces can help with this as the individual face velocities become more linear.
2008-09-13 18:09:41 +00:00
8925ae6042 BGE patch: use new btScaledBvhTriangleMeshShape to allow shape sharing between replicas and avoid BVH rebuild in case of scaling. This will save memory and speed up greatly the instantiation of static mesh. 2008-09-13 16:03:11 +00:00
63ecf9966e Fix to make blenderplayer compile with makefiles on Mac OS X. It worked
on Linux already, I think there is a difference in the linker.
2008-09-13 14:21:06 +00:00
ce41cfa40a bullet wasnt building on 64bit linux 2008-09-13 12:07:36 +00:00
ba9d3aa4ab BGE patch: fix transform bug on compound shape: child shape didn't take into account parent inverse node. Fix scaling bug on instantiation of compound shape: child shape didn't have correct shape. Note: global scaling doesn't work on compound shape (limitation of Bullet); don't set any scale on the top dynamic object. 2008-09-13 11:46:07 +00:00
dfb5ebb12e return dummy python values when no joystick is present 2008-09-13 11:43:01 +00:00
a9a8f74b80 Update MSVC project files for latest bullet revision 2008-09-13 11:41:52 +00:00
1c3043f011 32 sounds max would crash on windows because the openal limit is 24, tested an the to-frankie demo playes ok with 24, but would be good to make use of the sound lib's 'priority' option. 2008-09-13 08:22:55 +00:00
9a94620df0 Adapt MSVC project files for latest lib/windows configuration (update lib/windows first). 2008-09-13 08:10:50 +00:00
17478eeb23 Update MSVC project file for latest Bullet revision. Remove compound patch as it is now included in Bullet trunk. 2008-09-13 08:05:16 +00:00
7f293488d1 Upgrade to latest Bullet trunk, that is in sync with Blender/extern/bullet2. (except for one define 'WIN32_AVOID_SSE_WHEN_EMBEDDED_INSIDE_BLENDER')
In case someone reads those SVN logs: you can enable some extra broadphase SSE optimizations by replacing WIN32_AVOID_SSE_WHEN_EMBEDDED_INSIDE_BLENDER by WIN32 in extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h

Thanks to Benoit Bolsee for the upstream patch/contribution.
Removed some obsolete files, they were just intended for comparison/testing.
2008-09-13 07:06:43 +00:00
206cfe7955 avoid crash when game engine returns to Blender, and OpenAL sources haven't been initialized properly for some reason. 2008-09-13 05:24:52 +00:00
21d74deda6 Fixes for game engine runtime on Mac OS X, there were issues
working with relative paths. Still doesn't work optimal, since
paths are relative to game.blend which is in the app bundle
under Contents/Resources, so other files need to be moved there
manually at the moment.
2008-09-12 16:06:17 +00:00
6ebd6cfa73 Bugfixes in SDL joystick, apparently it gives NULLs in OSX. 2008-09-12 15:26:00 +00:00
ed0a0c704d merging bullet 2.71 to trunk --> svn merge -r16334:16486 https://svn.blender.org/svnroot/bf-blender/branches/sim_physics 2008-09-12 14:09:44 +00:00
f40aa6d13f typo in recent commit 2008-09-12 13:26:49 +00:00
b0d9994220 made max sounds playable at once 32 rather then 16. (demo release background music would turn off otherwise)
made selecting sound samples keep the relative path setting.
2008-09-12 13:24:22 +00:00
0795d01df4 Bugfix [#17609] Complex particles crash II - related to #17592 2008-09-12 13:15:52 +00:00
f274336f2f svn merge -r 16453:16485 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-12 12:58:08 +00:00
1adc2dce52 Correct half of rev16483, which does typecasts which are not nice on Win64 plattform 2008-09-12 12:33:55 +00:00
215828455a IPO Editor - Zoom view to area
The Shift-B hotkey can now be used to access this tool.
2008-09-12 05:54:39 +00:00
Ken Hughes
3e5549213c Add some typecasts for intptr_t and uintptr_t value to fix gcc warnings. 2008-09-12 05:27:02 +00:00
c45f1f504b Fix segmentation fault in ipo transform.
The NLA_IPO_SCALED define don't check if we have a Ipo Space open,
so in some case (like when you move a rig with locrot key) when
the function make_ipokey_transform is called, Blender crash.
2008-09-12 05:14:57 +00:00
Ken Hughes
d86c4c1004 Python API
----------
Patch #17481: added Material attributes for missing colorbands controls:
 * material.colorbandDiffuseInput
 * material.colorbandDiffuseMethod
 * material.colorbandDiffuseFactor
 * material.colorbandSpecularInput
 * material.colorbandSpecularMethod
 * material.colorbandSpecularFactor

Contributed by Emilio José Encinas Mir (asfhy).  Thanks!
2008-09-12 05:02:06 +00:00
Ken Hughes
4335811695 Python API
----------
Second and final part of MTex API changes.  Added support for new attributes for MTex World objects, stricter checking of attribute types for materia/lamp/world MTex objects, setters for lamp.textures and world.textures attributes, and updated documentation.
2008-09-12 02:23:52 +00:00
0dea748e01 save and load configuration actuator, (option in game actuator menu)
saves a marshal'd GameLogic.globalDict to the blendfile path with the blend extension replaced with bgeconf

Use this in YoFrankie to save keyboard layout and graphics quality settings.
2008-09-12 02:15:16 +00:00
Ken Hughes
75841bc97f Python API
----------
Add description for missing parameter in Mesh.MFaceSeq.extend() documentation.
2008-09-11 23:50:22 +00:00
b16b0f91ec Repair rayCast part 2: return correct polygon information and true normal 2008-09-11 20:16:30 +00:00
13b0cf94d5 Bullet patch for compound ray cast. The patch is filed in Bullet patch tracker for inclusion in later revision. If it is not included, apply manually extern/bullet2/bullet_compound_raycast.patch 2008-09-11 20:09:07 +00:00
3ac4cffdd0 Bugfix #14033
Option for Image render "Clip" gave wrong alphas on the edge of image.
2008-09-11 16:50:34 +00:00
d5839f21ab Bugfix 12478
Border render didnt work for ANIM render.
2008-09-11 16:37:53 +00:00
97178fecd9 BGE message python api could return a CList type or None which makes exception checks annoying. just return an empty CList rather then None. 2008-09-11 14:58:13 +00:00
729af67742 Bugfix: saved game engine runtimes failed to load library .blend
files with relative paths.
2008-09-11 13:00:54 +00:00
695c354b61 Fix for bug #17602: 32 bit bmp files were read with red and blue swapped. 2008-09-11 11:30:32 +00:00
5eb1d5e3dc Fix for bug #17593: glsl crash using a texture node without a
texture assigned.
2008-09-11 10:17:17 +00:00
7b98b5d34e Compiler warning fixes (mingw) 2008-09-11 06:17:21 +00:00
2af7083d75 BPY api addition material.freeNodes() - use to cleanup apricot files, since there is no way to remove a node tree via the UI, unused materials and duplicate images were hanging around.
buttons_logic - gave the name a but more room then the controller type, better for documentation screenshots.
2008-09-11 01:51:45 +00:00
Ken Hughes
9d7c56a7f2 Tools
---------
Fix user counting for particles.  id.us was not being decremented when using
the browser to replace current particle system.
2008-09-10 23:22:12 +00:00
dca6bd87ef removed debug print 2008-09-10 22:49:11 +00:00
Ken Hughes
0859141238 Scripts
-------
Removed empty parenthesis from class definitions, causes a syntax error in 
Python 2.4 (reported by Sanne on IRC, thanks!)
2008-09-10 21:37:22 +00:00
9e675e547e Bugfix [#17594] separated mesh crash 2008-09-10 15:51:10 +00:00
3bf182c4b4 Bugfix for [#17561] when i try to change the particle to hair I cant choose group or object as viz; Bugfix for mat[4][4] equal to zero resulting in no duplis --> Important: Janne could you check that fixes? 2008-09-10 15:25:06 +00:00
bd518b8de6 This is patch:
[#15135] imbuf DDS support: sync to nvidia texture tools revision 602 + fix for ATI2 compressed normal maps

It just updates the dds stuff.

Provided by Amorilia

Kent
2008-09-10 15:07:20 +00:00
90272dfdad Fix for bug #8132: on Mac OS X 10.5 with Nvidia cards drawing
background images and node previews goes wrong. The exact cause
of that is not sure, may be a driver bug, workaround is to fall
back to another slower function.
2008-09-10 13:02:58 +00:00
a42dd1482f Bugfix:
There were too many undo events being added for IPO Editor when selecting items with the mouse. Removed deselectall_editipo()'s undo push, as it was never called standalone anyway.
2008-09-10 12:04:20 +00:00
f5c19c2c35 Bugfix #17495: IPO curve handles go haywire
When editing IPO curve handles on a curve that belongs to a NLA-strip with repeat != 1 and 'AutoMerge Keyframes' on, the scaling correction was causing more problems than it was worth.
2008-09-10 11:45:42 +00:00
fdb057ff53 Implement softbody function for modifier_depeends_on_time() 2008-09-10 11:42:07 +00:00
1c44562d64 Bugfix [#12033] Cloth and Softbody don't work with Object Actions (fix pointed out by Aligorith. Ton: You might like to look over this) 2008-09-10 11:40:30 +00:00
dfd51ab5b6 Bugfix [#17592] Complex particle system crash 2008-09-10 11:38:19 +00:00
190aae27ae svn merge -r 16369:16454 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-10 11:04:07 +00:00
c40fe7b255 svn merge -r 16411:16453 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-10 10:53:38 +00:00
75078d62df Fix for bug #17589: removing a lamp in the game engine with glsl
materials did not work correct.
2008-09-10 09:51:06 +00:00
ecc5bdb8d7 2 gamelogic templates, one with example functions and comments, another minimal template for those who know the api. 2008-09-10 03:34:08 +00:00
eaf84d2c25 BPY merge from apricot branch.
work around non unix line endings using pythons execfile() function rather then loading the binary data and manually stripping the line endings.
2008-09-10 01:17:03 +00:00
74ab278d46 BGE bug #17549: fix crash on removeParent() with static mesh. Fix scaling bug on setParent(). Add python setWorldPosition() to allow setting object position in world coordinate regardless if it is a root or a child object. 2008-09-09 22:40:10 +00:00
aa10e1b11e Bugfix for [#17363] Edge selection mode + knife twice = latter cut doesn't do anything 2008-09-09 21:46:19 +00:00
f305bb22b7 Patch 17508: Blender Web Plugin - XEmbed. Enable XEmbed integration of blenderplayer, using -i as input parameter to pass embedder window id. create a minimal web plugin to embed blenderplayer on web pages (using gecko/mozilla as browser). Only for *nix. 2008-09-09 21:15:30 +00:00
Ken Hughes
fede495c07 Python API
----------
Bugfix #14425.  Particle.Get() could return a list of invalid items.  The API
still needs more work, but for now throw an NotImplemented exception.
2008-09-09 20:52:18 +00:00
f198acd5dd Fix for bug #14775: memorblock end corrupt print, needed to allocate
one byte more for the align menu string 0 terminator.
2008-09-09 20:19:00 +00:00
df1d59805f Fix for bug #17588: crash with ctrl+a and no active object. 2008-09-09 20:09:54 +00:00
84d7e2ea9c Fix for bug #17443: make bone heat weighting solve a bit less
sensitive to poorly shaped geometry, should succeed solving
in more cases now.
2008-09-09 20:00:57 +00:00
568ba15726 Bugfix for [#17329] Bevel Weights are lost after Subsurf 2008-09-09 18:44:10 +00:00
be19db6854 Fix for bug #12132: vector blur with fast moving objects does
not give a smooth fallof. there's no correct fix possible due
to a lack of information, but this manually adds a smoother
falloff, overestimating the contribution of foregroud pixels
instead of becoming transparent.
2008-09-09 17:27:01 +00:00
d9404adcd1 Bugfix #17562: array fit to curve isnt working 2008-09-09 16:38:08 +00:00
e9b08b64fa Fix for bug #17402: IK influence blending with pole targets
didn't give smooth transition. Now it blends the result of
IK solving in that case.
2008-09-09 15:15:01 +00:00
160c0de87b Fix for bug #17580: crash rendering instanced objects with
halo material attach to the object instead of the mesh.

Also for bug #13489: avoid a crash rendering with invalid
active vcol layer, most likely caused by a bug that was
already fixed.
2008-09-09 14:16:54 +00:00
68d7f0a3d1 Bugfix #13592
Sequencer, Time, Sound windows were drawing frame numbers double when
too far zoomed in.
2008-09-09 13:35:38 +00:00
7366834443 Bugfix #13596
Wrong popup on single-user particles, it said "make local".
2008-09-09 12:51:22 +00:00
4db3d6c595 Bugfix #13653
Autosave disable didn't work.

Note however that a disabled autosave only gets active on saving the 
user settings, and loading blender again. This is a timer that gets 
set on startup. I didn't code a kill timer. :)
2008-09-09 12:00:38 +00:00
ad31f6a4b3 Bugfix #13675
Edge render made star render disappear. Wrong Z value comparing...
(2 year old bug!)
2008-09-09 11:40:29 +00:00
0995466927 wasnt using icon buttons correctly 2008-09-09 10:58:58 +00:00
70be839859 Bugfix #13837
Tonemap didn't correctly accept any buffer type.
The coder who added this should check this fix! Any node coder maybe...
2008-09-09 10:16:09 +00:00
Ken Hughes
3f87319428 Python API
----------
Add access to MTex objects from Lamps and Worlds (first pass).  Since the
MTex structure is slightly difference between materials, lamps, and worlds,
a field is added to the BPy MTex object to distinquish which type it wraps.

Attempting to access attributes which are unique to materials for lamp or
world MTex objects throw an exception.  The next pass will implement MTex
attributes which are specific to Lamps and Worlds.

A new attribute (textures) is added to each module.  It is compatible with
the previous Material.getTextures(), which returns a tuple of either MTex
objects or None.  Surprised we never added an attribute for this before in
all the changes and refactoring.
2008-09-08 23:39:32 +00:00
de48280368 Bugfix #17566
Modifier buttons: now check properly for external lib data, modifiers are
on object only. Only "Apply" is locked now.
2008-09-08 15:15:00 +00:00
f7a6d032fc Bugfix #17375
Crash on converting object to other type, and replace object.
Deleting should trigger a new depsgraph.

Oldie bug!
2008-09-08 13:04:10 +00:00
2768ee67bd Grease Pencil - Defaults Cleanups:
* Made new layers default to having thickness of 3, and opacity of 0.9. These values seem to be used more often.
* Newly added Grease Pencil blocks will now be expanded by default in the Action Editor
* Added support for Image Editor grease-pencil blocks to the Action Editor
* Added version-patching for missing colours used by the info-string for GPencil.
2008-09-08 12:36:49 +00:00
e3172d8f4d Bugfix:
Grease Pencil panel now updates correctly in Sequencer
2008-09-08 12:06:40 +00:00
da474210de Bug #17317
Vertexpaint mode: option "paint mask" (Fkey) missed redraw for buttons
2008-09-08 11:13:34 +00:00
6a83746fb3 Bugfix #17305
3d window didn't refresh correctly when loading a new background image.
Fix by Ken Hughes. :)
2008-09-08 10:31:00 +00:00
ce7caf203d View 3D - Improvements for Info Drawing:
The little info string beside the mini-axis (in bottom left corner) is now more useful when animating fullscreen. ZanQdo feature request.

* Info string is drawn in yellow when there is a keyframe on this frame. 
Hopefully this doesn't introduce any major slowdowns, as it does do a search for keyframes for every redraw.
* Name of first marker that occurs on the current frame is now also shown (in angled brackets). No angle brackets are shown if no marker.
* Info string is also shown when there is no active object.
2008-09-08 06:49:19 +00:00
a9d334df67 Bugfix for #17572 Boids Particles Crash 2008-09-07 20:46:54 +00:00
26d8da99cc Bug [#17454] Wave modifier crash, fix provided by Banlu Kemiyatorn 2008-09-07 20:18:26 +00:00
f3fc5a8b61 BGE bug #17574 fixed: GE Text input doesn't register in 2.47. Force registration of keyboard sensor with no link as this is typically the setting for key logging. 2008-09-07 19:58:37 +00:00
44f9276b67 svn merge -r 16396:16411 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-07 19:47:15 +00:00
1d41c27625 Bugfix #17446
Two menu errors in Node Editor.
2008-09-07 18:18:50 +00:00
8569a78cbb bugfix 17527
Halo render: lines and rings were not using random anymore... got lost
in particle upgrade of pre-peach. Tsk!
2008-09-07 17:13:05 +00:00
d0b3ce3c48 Draw icons in the layer button to show used layers as well as layer of active object, this is a feature from apricot but used button color instead which was confusing. 2008-09-07 16:37:55 +00:00
91c8eea325 [#17579] Added support to VSE Python API for adding movie and audio HD sequences
from Rob Scott (spamagnet)
2008-09-07 14:02:58 +00:00
a14d7c9b7d Bugfix #17497
FSA didn't support "key alpha", fixed it.
Also noticed edge-enhance didnt work for FSA, added warning for that,
fixing it is too clumsy, this option belongs in compositor.
2008-09-07 13:15:44 +00:00
e0fad0e6a1 Grease Pencil - Stick to View for Sequencer:
The 'Stick to View' feature now works in the sequencer (image previews)
2008-09-07 11:36:52 +00:00
0bf03ef2f1 BGE patch: Simulate dupligroup operation when parent and child are not active/inactive at the same time: don't convert the child. This unusual situation is used in Apricot for testing. 2008-09-07 10:47:33 +00:00
7666666992 Bugfix #17490
Camera feature "DOF Object" was drawing the cross marker on wrong location
when camera scales. Simple fix by using Mat4Ortho()
2008-09-07 10:24:02 +00:00
eb9f4461ea Constraints - Space Conversions Code Tidyup:
Finished verifying that all possible combinations of space conversions were accounted for.
2008-09-07 04:43:31 +00:00
54a4b036a3 Some version were not merged from svn/missing --> svn merge -r 16370:16371 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-07 01:43:55 +00:00
667c8d83fb BGE patch: break parent relationship when child and parent are not active/inactive at the same time. This unusual situation is used in Apricot for test purposes. 2008-09-06 22:06:01 +00:00
9f05477ea1 svn merge -r 16371:16396 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-06 17:49:26 +00:00
c7fe2199a7 object_find, didnt get images from an objects material textures
KX_PythonInit.cpp - own error in recent commit.
2008-09-06 17:04:54 +00:00
601979fc15 Fix Windows compile error. Update MSVC project files 2008-09-06 16:53:44 +00:00
115cf18bed converted my gen_utils.h fix to PyObjectPlus.h
Also added a fix for PyMarshal_WriteObjectToString

Now I just need to figure out linking of the gameengine on my imac.

Kent
2008-09-06 14:13:31 +00:00
810f799660 Revert a commit from 5 years ago that added a glFinish call before swapping on Windows. This is really bad for performance and especially showed in the game engine. The purpose was to disable FSAA and fix some UI issue on Geforce 2 graphics cards, hopefully the drivers have been fixed by now? I have no way to test this, so we'll see if an issue pops up on those older cards, and a lot of code changed since then anyway so it might not even be needed anymore. 2008-09-06 13:24:42 +00:00
1bd365e112 find objects by texture name raised a python error 2008-09-06 12:50:22 +00:00
742e917c6a added ALPHASORT flag to the bpython api 2008-09-06 10:39:19 +00:00
8675ff6d1d Trying to keep things compiling on my imac (10.4.11)
I'm getting this error now:
GPG_Application.cpp: In member function 'void GPG_Application::stopEngine()':
/System/Library/Frameworks/Python.framework/Versions/2.3/include/python2.3/marshal.h:12: error: too many arguments to function 'PyObject* PyMarshal_WriteObjectToString(PyObject*)'
GPG_Application.cpp:720: error: at this point in file

Are we offically not supporint older versions of python now? :)

Kent
2008-09-06 02:46:11 +00:00
e279aadb97 Bugfix: game engine could crash with empty display arrays on
windows (caused by invisible faces for example).
2008-09-06 01:18:53 +00:00
61e6283657 treaded soft bodies final (hopefully)
bug fix [17428]
/*backward compatibility note:
G.rt==16 still activates 'old' code
fixing bug [17428] which forces adaptive step size to tiny steps in some situations .. keeping G.rt==17 0x11 option for old files 'needing' the bug*/
2008-09-05 23:28:28 +00:00
af42ff6aa2 Fix: compiling with cmake 2.4 didn't work anymore due to a
compatibility fix for cmake 2.6.
2008-09-05 21:57:34 +00:00
Ken Hughes
3f9d32783a Python API
----------
Add missing Textures.ExtendModes.CHECKER constant.
2008-09-05 20:41:09 +00:00
d8b9ca34a0 GLSL: small optimization if Use Alpha is disabled for textures. 2008-09-05 20:34:35 +00:00
5eab0da633 BGE set visible actuator, option to set visibility recursively to make managing visibility for collections of objects a lot easier.
BGE Python api's ob.setVisible() also takes an optional recursive arg thats off by default
2008-09-05 16:22:14 +00:00
2e653838c0 Bugfix for GLSL: no specular/diffuse + only shadow for lamps
didn't work correct.
2008-09-05 15:08:01 +00:00
f1415bca7e Missing header.
Kent
2008-09-05 14:42:03 +00:00
330aa94ecc * GLSL lamps now respect 3d viewport layers.
* Fix undo crash related to sound. Sounds still stop working in
  the game engine after undo, but seems to be a different issue.
2008-09-05 14:33:36 +00:00
5b6e9eec7b Two more apricot branch features:
* Auto Depth: use the depth buffer for improving pan/zoom/rotate
  in large scenes.
* The viewport drawtype for objects in groups now aren't just taken
  from the original object, but the minimum together with the parent
  drawtype is used.
2008-09-05 13:08:50 +00:00
d88b4acc9b Fixing non-working check for incompatible trees 2008-09-05 12:06:47 +00:00
b32036f5d6 bvh nodes got parent node reference again 2008-09-05 11:55:39 +00:00
e8621cf05e Grease Pencil - Available in Image Editor:
Grease Pencil is now available in the image editor. It is important to note that the strokes drawn WILL NOT become part of the image visible at the time.

Unfortunately, 'fancy' stroke drawing cannot be enabled for use with the 'Stick to View' setting here, as the scaling is wrong.
2008-09-05 07:12:04 +00:00
18fe6c27ff Compiling/Warning Fixes (for scons/mingw + "split sources hack") Part 1:
* Removed compiler warnings from texteditor work
* Added round brackets around the new defines for IPO channels for extra texture layers
* Tweaked priorities so that BLI_heap_* functions in blenlib can be found by linker (split-sources specific)

TODO:
* "monkey*" vars cannot be found still
2008-09-05 06:05:25 +00:00
18b5b4ff0c * Made the Ipo editor handle colours initialise from old files to the previously stored Ipo editor vertex colours, rather than the default pink and yellow. This keeps existing themes looking the same as they did before rather than turning them pink by default. 2008-09-05 05:17:26 +00:00
e3a1547eea BGE Py API
added exception messages for replaceMesh.setMesh() and allowed None as an argument.
added exception messages for other BGE module functions.
2008-09-05 02:53:12 +00:00
3c95d91a57 * corrective UV transformation - only works with UV edge slide right now. but should be extended so transforming dosnt distort UV's
* smooth respects mirror option (will move mirrored vert too)
2008-09-05 00:28:17 +00:00
d2c13039ed svn merge -r 16320:16369 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-05 00:12:01 +00:00
dd03596bfe svn merge -r 16351:16368 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-04 23:33:19 +00:00
2d50ead6b8 Partial repair of raycast system with Bullet 2.71. Still to be done: face and normal information 2008-09-04 23:07:43 +00:00
d682dc5bd5 svn merge -c 16350 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-09-04 23:05:00 +00:00
cb89decfdc Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:

* GLSL support in the viewport and game engine, enable in the game
  menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
  gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
  storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.

* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
  An extra texture slot shows up once the last slot is used.

* Memory limit for undo, not enabled by default yet because it
  needs the .B.blend to be changed.
* Multiple undo for image painting.

* An offset for dupligroups, so not all objects in a group have to
  be at the origin.
2008-09-04 20:51:28 +00:00
2167e5c341 Cleaned up some small warnings.
Kent
2008-09-04 16:40:20 +00:00
f0eaf424ab Added SDL headers so gamestuff compiles with Makefiles again.
Kent
2008-09-04 15:29:43 +00:00
05056f2e1d overlapping UI causing problems, forgot the label has a function assigned to it 2008-09-04 12:17:01 +00:00
e356c4d5d4 pin option for sensors and actuators,
this helps in cases where you want to use a logic brick in 2 states, linking the sensor to a second state's controller can be tricky.
This way you can pin a sensor or actuator, change the visible state and link it to another controller.

The pin button will only be displayed when states view is enabled and the logic brick is expanded or when it is alredy pinned.
2008-09-04 12:11:47 +00:00
7afc0ca600 Two compile fixes for msvc and cmake provided by broken 2008-09-04 10:29:41 +00:00
a7348dd43e Bugfix: yafray export crash if new hsv texture blend types were
used, the code here needed to be updated.
2008-09-04 00:27:05 +00:00
961a26d500 fix for 2 python refcounting errors 2008-09-03 23:51:55 +00:00
11ec880483 Clean up merging conflict 2008-09-03 16:10:20 +00:00
a9ffeb8cad Fixing debug output 2008-09-03 16:02:40 +00:00
c587252a78 Bugfix for sphere-in-control-object (reported by broken) 2008-09-03 16:01:25 +00:00
19d5a5da45 Update MSVC project files after GSoC merge 2008-09-03 12:54:46 +00:00
096b4638c4 Revert rev16344 on trunk, bullet work is done in sim_physics branch as discussed on sunday meeting 2008-09-03 11:11:11 +00:00
85deff9c30 svn merge -r 16334:16347 https://svn.blender.org/svnroot/bf-blender/trunk/blender + also added missing files from bullet-2.71alpha0 archiv + fixed compile errors 2008-09-03 10:55:46 +00:00
cfa07e8d2b BGE Py api, deleting properties didnt raise an error when the property wasnt there. also added some exception messages and renamed joystick getConnected() to isConnected() 2008-09-03 06:43:07 +00:00
b818b1a164 cleanup mesh materials option was setting incorrect material indicies 2008-09-03 03:24:01 +00:00
1926e84650 Finally upgraded to latest Bullet subversion, about to release 2.71. Some recent changes in extern/bullet2 need to be re-applied, will check with Benoit. Ray tests in 0_FPS_Template.blend is broken, didn't figure out why yet.
HELP BUILD SYSTEM MAINTAINERS: Please help with updating all build systems: the newly added files need to be added. Note that the src/SoftBody has been added for future extension of real-time soft bodies.
2008-09-03 02:27:16 +00:00
33ac84e888 Compile fixes (reported by broken) 2008-09-03 00:00:32 +00:00
fe93743518 BGE patch 17547 approved: Cleaned up pydoc for BGE, compiles now error free 2008-09-02 22:13:07 +00:00
Ken Hughes
bbf2ff410b Fix some more gcc warnings. 2008-09-02 21:09:29 +00:00
Ken Hughes
e4dbf0e7d6 Fix gcc compiler warnings. 2008-09-02 20:53:07 +00:00
0fe906f49e BGE patch: simple fix to synchronize sensor pulse mode with sensor state transitions. 2008-09-02 18:34:54 +00:00
dcbf8fbf76 Fix segmentation fault when try separate a mesh with the active face selected.
If the active face is part of the selection, Blender crash when
split the mesh because the act_face have an invalid pointer.

The solution is simple, check if the active face is part of the selection
and in that case, set it to NULL.

Campbell please double check this.
2008-09-02 17:50:54 +00:00
ead69661e8 -> Fix for 64 bit alignment of Vertex colors in bmesh
Vertex color structure in bmesh needed to be padded for
8 byte aligned memory access.
2008-09-02 16:39:03 +00:00
de493dacb3 New physics + related branch for Nils smoke stuff, Pablos volumetrics stuff and also Bullet work (Ben) 2008-09-02 15:21:05 +00:00
84dcfa181b BGE Bugfix, SDL joysticks arrow keys didnt work when 2 joysticks were being used at the same time.
The event queue was running for every joystick sensor without checking if the events were for that joystick.
seperating the event queue for each joystick is overkill so instead deal with all joysticks events in once function.

Also removed some unused functions
2008-09-02 06:12:19 +00:00
81ad271d15 BGE joystick sensor bugfix, was sending true events logic tick (as if the true pulse option was enabled). 2008-09-02 02:03:03 +00:00
aa4e4da8c3 Text Editor (GSOC 2008)
=======================
Merge of branch soc-2008-quorn to trunk:
Merged 14970:16308 to trunk@16307, updated to HEAD.
Merged 16318

Main features from this branch:
 - Python text plugins
 - Suggestions and documentation elements
 - Improved syntax highlighting
 - Word wrap
 - Additional editing tools
 - Various undo and clipboard fixes
 - File header info and modification checks
2008-09-01 14:04:22 +00:00
7b9ee57c0b BGE joystick sensor py api function 'getConnected()', returns true if the joystick is connected and working.
SCA_Joystick.h seemed to have twice as many newlines as needed.
2008-09-01 06:25:13 +00:00
6f3a8519da Bugfix #17557: Segfault when no active node and trying to insert keyframe
When there is no active node in the Composite Nodes, Blender crashes when trying to insert a keyframe using IKEY.
2008-09-01 04:09:07 +00:00
e8049903ac BGE python api for get/setting the joystick index, minor cleanup also. 2008-09-01 00:12:39 +00:00
234b616078 BGE bug #17459 fixed: action actuators depending on their order in the actuator list. 2008-08-31 21:53:39 +00:00
8cf385a93d svn merge -r 16222:16320 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-08-31 21:00:20 +00:00
7f257df5b4 BGE patch 17547 applied in trunk: Cleaned up pydoc for BGE, compiles now error free 2008-08-31 19:07:10 +00:00
74339c639a BGE patch approved: BGE Multiple Joysticks 2008-08-31 18:42:58 +00:00
062bf735e7 Minor tidying and commenting 2008-08-31 16:23:31 +00:00
a4e74c92f7 == Grease Pencil Conversions - Armature ==
Can now also convert active layer to a series of bone chains. Each stroke will be converted to a chain of connected bones.

At the moment, it is still necessary to manually recalculate roll angles after the armature has been created, as the bones are not assigned the correct roll angles yet.
2008-08-31 12:47:04 +00:00
6aee42daaf Bugfix #17551: AutoKey for Visual Keying non-functional
No VisualKeying checks were being done
2008-08-31 07:33:27 +00:00
9818b8a95c Fix for win64 building (gettextlib had wrong name) 2008-08-31 01:57:53 +00:00
25c116e80a Fixing typo to make compile working again 2008-08-30 23:12:01 +00:00
Nathan Letwory
ff0aab05b2 patch for bug #17553: material emit is allowed to go from 0.0 to 2.0; however curves only make it go to 1.0
reported and patched by slikdigit
2008-08-30 21:41:02 +00:00
3bab89cc1c Merge from trunk 16122-16307 2008-08-30 14:32:16 +00:00
bccce7e30e Fix for class variable parsing/listing bug. 2008-08-30 11:27:27 +00:00
4d888fb6c8 Added missing null check to convertmenu
Remported by alxarch.
If you remove the active object and then tried alt-c it would crash.

Kent
2008-08-29 14:19:34 +00:00
b77e130dd6 Grease Pencil:
* Added 'Convert To...' button for easy access to conversion tool. The hotkey has been mentioned in the tooltip. This replaces the 'Del Active Frame' button in 3d view only.

Armature Apply Pose:
* Added menu entry (beside Relax Pose)
* Bone-parented objects now get their parent inverse matrices correctly recalculated
* Changes for 'scale' code in previous commit wasn't correct... reverting
* IPO/anim flush protection is now set on bones to prevent them from being sprawled everywhere after applying
2008-08-29 12:24:07 +00:00
ff06fcfc33 Bugfix:
* Roll is now correctly calculated for Apply Armature
* Scale on x,z axes is no longer cleared (only scale on y axis needs to be)
2008-08-29 11:15:24 +00:00
bcff5afeb2 == Grease Pencil ==
Special request by Alxarch for Architecture:
Hold Ctrl-Key when 'Draw Mode' is enabled to draw straight lines. 
Although when drawing the stroke, the stroke will still be freehand, the final result will be a line between the endpoints of that stroke. This is useful for annotations of sectioning lines + site maps, etc.
2008-08-29 10:47:53 +00:00
e21b3d81c5 Use Py_ssize_t rather then int, broke building on 64bt linux 2008-08-29 06:32:42 +00:00
f60992daae BGE Py API - GameKeys.EventToString() utility function, makes key configuration menu's easier to write.
own error with blenderplayer, wasnt decreffing the GameLogic module, probably didnt matter since python was restarted anyway, but is incorrect.
2008-08-29 03:15:17 +00:00
272132888f BGE patch: add X-Ray option to ray sensor. The option is effective only if a property is set: the sensor will ignore the objects that don't have the property. 2008-08-28 19:37:49 +00:00
9f10007bfb == Apply Current Pose as New Restpose ==
In PoseMode, the Ctrl-A hotkey can now be used to apply the current pose as the new restpose for the armature. 

Notes:
* Roll correction may not be totally correct on bone chains, but is ok in most cases.
* Objects that are bone parented to the armature where this is applied are not correctly adjusted yet. 
* It is advisable to 'apply' the existing armature deformations to geometry deformed by the armature before applying this, to prevent unexpected results.
* No menu entry yet... will add in due course.
2008-08-28 12:22:55 +00:00
9f89f4cf34 compilation problem with gcc, memset undeclared 2008-08-28 12:12:56 +00:00
6a98b9215c final fix for compilation problem with KX_RayCast::Callback template in gcc 2008-08-28 11:13:04 +00:00
116001ac34 more fix for compilation problem with KX_RayCast::Callback template in gcc 2008-08-28 11:06:46 +00:00
bf7387b2d8 GPencil Bezier Curve Conversion:
Now sets vector/free handles by default
2008-08-28 10:43:17 +00:00
84d1dfb89b patch for compilation problem around KX_RayCast::Callback template with gcc 2008-08-28 10:28:06 +00:00
1032da67cc Grease Pencil - Curve Conversion Improvements:
* Changed hotkey from Alt-C to Alt-Shift-C so that it works when the active object cannot be deselected/deactivated.
* Added option to convert to bezier curves. Note that currently, the handles are simply placed to the same location as the point so that there is an exact match with the gpencil strokes. In future, it would be interesting to investigate using proper curve-fitting algos instead.
2008-08-28 10:19:34 +00:00
794ffdcd2c didnt build before committiong this small change :/
isLight() is apricot only. Add this back when GLSL is merged to avoid conflicts.
2008-08-28 09:02:04 +00:00
c8d0a540f5 BGE patch: fix division by 0 error when sound sample cannot be loaded in sound actuator. 2008-08-28 08:13:58 +00:00
f88c5d9721 BGE Bugfix, lights were not being removed when their gameobject was removed causing odd shadows to hang about the scene. 2008-08-28 07:03:23 +00:00
2934e78a86 remove more python functions from builtins that could allow scripts to do bad stuff.
- reload, file, execfile, compile
These are only removed when running in higher security mode thats not default in blender.
2008-08-28 05:45:20 +00:00
becd467be8 BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):

The face paremeter determines the orientation of the normal: 
  0 or omitted => hit normal is always oriented towards the ray origin (as if you casted the ray from outside)
  1 => hit normal is the real face normal (only for mesh object, otherwise face has no effect)
The ray has X-Ray capability if xray parameter is 1, otherwise the first object hit (other than self object) stops the ray.
The prop and xray parameters interact as follow:
    prop off, xray off: return closest hit or no hit if there is no object on the full extend of the ray.
    prop off, xray on : idem.
    prop on,  xray off: return closest hit if it matches prop, no hit otherwise.
    prop on,  xray on : return closest hit matching prop or no hit if there is no object matching prop on the full extend of the ray.
if poly is 0 or omitted, returns a 3-tuple with object reference, hit point and hit normal or (None,None,None) if no hit.
if poly is 1, returns a 4-tuple with in addition a KX_PolyProxy as 4th element.

The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.

Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v4: vertex index of the fourth vertex of the polygon, 0 if polygon has only 3 vertex
     use this to retrieve vertex proxy from mesh proxy
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy

New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.

More details in PyDoc.
2008-08-27 19:34:19 +00:00
f6bdba8351 Bullet patch: option to return true face normal, complete triangle information and broad phase filter. This patch is needed to support enhanced ray cast function in the BGE. I have proposed it to the Bullet forum for inclusion in the next Bullet version. 2008-08-27 19:16:21 +00:00
c6acbc3047 == Grease Pencil - Conversions + Bugfixes ==
* New stuff: Grease Pencil strokes on the active layer can now be converted to 3d curves (geometry). More work is still needed to make the result look be more optimal (i.e. extruded curve)

* Bugfix: Spacing between collapsed layers is more compact now
2008-08-27 13:02:44 +00:00
6cccdf0cb2 BGE bugfix, ipo actuator's foce option didnt check that the object was dynamic. 2008-08-27 06:02:10 +00:00
d566765635 get/set Angular velocity for KX_GameObjects python api and for the AddObject actuator.
Needed so objects created in an explosion could start spinning without having motion actuators and collision sensors on each item.
2008-08-27 03:34:53 +00:00
6778c8dc29 BGE: allow sound actuators to be converted even when they have invalid samples
without this, an incorrect sound path could cause scripts to to fail, making some functionality not work at all.

This also fixes a problem where samples would be loaded multiple times.
2008-08-27 01:03:55 +00:00
0257f500e7 Fix for text plug-in scripts on 64-bit platforms. 2008-08-26 17:09:17 +00:00
0b523ac3e6 Particle System: a) Fixing visibility bug when a duplipart-system was deleted it didn't show up in during render any more, b) fixing possible crash during render 2008-08-26 01:07:18 +00:00
b81bdfdc7c TLC needed for Makefiles to get gameengine compiling again.
Sorry it took me so long to do this :)

Kent
2008-08-25 19:50:17 +00:00
Chris Want
e3961717be Patch #17517 from Enrico Fracasso (thanks!)
Explicitly setting CMake policy CMP003 to obey the CMake 2.6
way of dealing with how to find libraries when the full path
isn't known. See:

http://www.cmake.org/HTML/cmake-2.6.html#policy:CMP0003
2008-08-25 15:33:18 +00:00
10bcba77b1 Crash fix for having wind noise + particles (reported by Wahooney) 2008-08-25 13:49:55 +00:00
683aabae93 Fixing compiler warning due to unsed code 2008-08-25 11:49:58 +00:00
d37f0325ca Effector fall-off power was off by one for spherical, magnet, harmonic and charge fields. For example a square fall-off was reduced to linear etc. 2008-08-25 11:46:55 +00:00
afa8a76f46 Grease Pencil Eraser - Bugfix:
* 3d strokes could only be erased from start of stroke 
NB: 3d-strokes could be erased starting from previous commit
2008-08-25 11:09:19 +00:00
b5d254445c getting the last created object would return an object that had no SG_Node which would crash whenever python tried to get its location.
since the object was removed from the scene anyway, there is no reason to return it.
2008-08-25 09:52:38 +00:00
1ed408e8c6 == Grease Pencil - Drawing + Eraser Improvements ==
Drawing Improvements:
* Single 'dots' now draw rounded
* Strokes being drawn are drawn 'solid' instead of as dotted lines

Eraser:
* Now operates interactively, so no more wait to see if stuff was erased
* An influence circle is now drawn - the radius of this is defined as the thickness^2
2008-08-25 06:22:21 +00:00
5e13055849 Little feature request
Adding numerical input support to edge slide (and at the same time, loop cut).

Also clean up NumInput functions for external use. I might have a second pass at this to make it even easier.
2008-08-24 20:57:56 +00:00
bdcf3783d7 [#17433] Cannot break node links with LMB drag under linux.
Grease pencil commit added some panel draw code or whatnot which seems to change the matrix stack in unwanted (in this case) ways. Reset to identity fixes it.

* I don't think it was limited to Linux though
2008-08-24 15:22:44 +00:00
bf0803c0c2 Added better grouping for text markers with a separate group field (instead of using flags). The lower two bytes of the group are used for python scripts while the upper two (or more) are reserved for internal grouping. Plenty either way. 2008-08-24 13:30:35 +00:00
Hans Lambermont
b33e57952c fix settings for freebsd7 2008-08-23 13:12:17 +00:00
bc8f002a4c BGE state system improvement: the sensor with Level option enabled will trigger the controller of a newly activated state, even if the sensor is already connected to an active state; new isTriggered() python function to determine which sensor triggered the current controller.
Previously, this behaviour was available only for sensors
that were not connected to any active state, which was
forcing the game designer to duplicate sensors in some 
cases.
For example the Always sensors used to initialize the 
states needed to be duplicated for each state. With this
patch, a single Always sensor with Level option enabled
will suffice to initialize all the states. 
A Python controller can determine which sensor did trigger
with the new SCA_ISensor::isTriggered() function.

Notes:
- When a sensor with level option enabled is connected
  to multiple controllers, only those of newly activated
  states will be triggered. The controllers of already
  activated states will receive no trigger, unless the 
  sensor internal state toggled, in which case all the
  controllers are triggered as always.
- The old isPositive() function returns the internal
  state of the sensor, positive or negative; the new 
  isTriggered() function returns 1 only for sensors
  that generated an event in the current frame.
2008-08-23 11:54:27 +00:00
2076703a28 Removed cast warnings from shrinkwrap.c and BLI_kdopbvh.c
Only unused functions and openmp warnings left on those.
2008-08-22 18:28:34 +00:00
7630539fe8 Fix Windows compilation problem and update MSVC project files 2008-08-22 15:00:30 +00:00
39a8125e4c Typo in copyright notice (VF -> BF) 2008-08-22 12:48:12 +00:00
88b30a740a A bit of cleanup of warnings (gcc).
Warnings still exist in the following places:
* places (exotic.c, etc.) where format strings still use 'longs' but datatype is uintptr_t (i.e. resulting from the win64 changes)
* shrinkwrap.c - a few "incompatable type" warnings
2008-08-22 12:10:02 +00:00
c230bc4a82 Grease Pencil - Drawing Improvements:
This commit finishes the work started in the previous commit. 
1) Reduced the effects of 'shrinking' lines with acute angles (*)
2) Ends of strokes now get crude end-caps which look ok for most purposes (they are really just simple trapeziums not fancy semicircles)

* Note: some shrinking does still occur if the stroke was drawn quickly enough for few points to be recorded. Also, although there are still zones of overlapping when there are acute angles, this is reduced to steeper angles (and is not too bad considering real-life materials)
2008-08-22 11:46:59 +00:00
f88dabae8a BGE data conversion was making sound paths absolute, modify a copy rather then the original. 2008-08-22 10:27:16 +00:00
5dafc1a553 svn merge -r 16060:16222 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-08-22 09:31:32 +00:00
eab746fc5f Grease Pencil: WIP commit (nothing new)
Just a little commit so that I can transfer some changes back over to laptop. 
* Line drawing should now be improved for most cases, but acute angles still need more work to reduce 'shrinking' artifacts. As such, this is still hidden behind 'rt' setting
* Preparation work for Grease-Pencil in Image Editor, and also 'Stick to View' for Image/Sequence editors.
2008-08-22 08:36:29 +00:00
9b29810912 BGE Python API - GameLogic.getBlendFileList(path='//') to return a list of blend's in the current directory. Needed for creating a level selector that lists all files in the level directory.
CMakeFile include path to compile with recent changes.
2008-08-22 06:02:01 +00:00
4655426ec7 Merged shrinkwrap modifier from soc-2008-jaguarandi 2008-08-22 00:35:14 +00:00
f4ae23f379 svn merge -r 16174:16215 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-08-21 22:57:25 +00:00
f0d58a8b99 Update scons files in source/gameengine/Physics/Bullet.
Please Nathan double check this, but all compile fine here :)
2008-08-21 21:14:08 +00:00
57d1a1eac2 New things for particle effectors:
- For newtonian particles a "self effect" button in particle extras makes the particles be effected by themselves if a particle effector is defined for this system, currently this is a brute force method so things start getting slow with more than ~100 particles, but this will hopefully change in the future.
- Two new effector types: charge and a Lennard-Jones potential based force (inter-molecular forces for example).
   -Charge is similar to spherical field except it changes behavior (attract/repulse) based on the effected particles charge field (negative/positive) like real particles with a charge.
   -The Lennard-Jones field is a very short range force with a behavior determined by the sizes of the effector and effected particle. At a distance smaller than the combined sizes the field is very repulsive and after that distance it's attractive. It tries to keep the particles at an equilibrium distance from each other. Particles need to be at a close proximity to each other to be effected by this field at all.
- Particle systems can now have two effector fields (two slots in the fields panel). This allows to create particles which for example have both a charge and a Lennard-Jones potential.
2008-08-21 21:12:27 +00:00
3d3527eb6d BGE bug #17411 fixed: the always sensor is called before the the scale of the object is applied. The scale is now applied to the shape before the creation of the rigid body. 2008-08-21 21:04:42 +00:00
Ken Hughes
8551ac5e08 Missing newline at EOF. 2008-08-21 20:28:33 +00:00
ca1182ff56 fix warning in previous revision, update MSVC project files, scons files in source/gameengine/Physics/Bullet must be updated by adding these directories in the include list: intern/string/include, source/gameengine/Rasterizer, source/kernel/gen_system. I leave it up to more expert than me. 2008-08-21 19:00:24 +00:00
Ken Hughes
0a87d821a9 Python API
----------
Fix typo in Mesh module exception messages (submitted by Teppo Kansala ).
2008-08-21 16:13:26 +00:00
Ken Hughes
7e0c880c2e Python API
----------
Access to empty shapes by object.emptyShape attribute, contributed by Domino
Marama (thanks!)
2008-08-21 16:10:30 +00:00
e912ca9331 BGE bug #17491 fixed: BGE, Dupli instance with different scale, massive slowdown.
The root cause of this bug is the fact that Bullet shapes 
are shared between duplicated game objects. As the physics
object scale is stored in the shape, all duplicas must 
have the same scale otherwise the physics representation
is incorrect.
This fix introduces a mechanism to duplicate shapes at
runtime so that Bullet shapes are not shared anymore.
The drawback is an increased memory consuption. 
A reference count mechanism will be introduced in a 
later revision to keep Bullet shape shared between
duplicas that have the same scale.
2008-08-21 15:19:54 +00:00
4b9f5b2710 BGE Bullet fix: physics debug representation of cone shape does not take Up axis into account. Use Bullet 2.69 code to fix that bug. 2008-08-21 14:07:24 +00:00
09c4e88336 -> more FLT tweaks
LOD editor input ranges were too low.
Also fixed the interface drawing so it
always started at bottom of screen area.
2008-08-20 20:10:33 +00:00
e7cf01d083 -> Fix for last commit
The range of allowed values for the LOD editor
 inputs was too low.
2008-08-20 19:18:52 +00:00
6d7fa6020e -> LOD and DOF editor scripts
Two new scripts for the 'Misc' Menu. LOD and DOF
 Editors for creating/editing DOF and LOD FLT nodes
 inside of blender.
2008-08-20 19:10:33 +00:00
7608dcfc51 GameLogic.globalDict blenderplayer now keeps settings when loading new blend files.
workaround for python stopping and starting by storing the dictionary as marshal'd data. this means only python types are supported.
This feature is needed so when switching from a menu to a level blendfile, the configuration isnt lost.
2008-08-20 06:11:11 +00:00
b23f3f62c2 Ipo Handle vertex have own color and size (Venom request).
Now the vertex of the ipo handle have own color and
size, can be change from Theme -> Ipo Curve Editor:
	Handle Vertex		-	(Default Color)
	Handle Vertex Select	-	(Selected Color)
	Handle Size		-	(Point size, for vertex)

Add subverion so by default the handler have the same
settings that the ipo vertex options.
2008-08-19 14:39:11 +00:00
812583f1fa Added GameLogic.globalDict, this is a place where data can be stored even when new blend files are loaded. Using for apricot so frankie can go into levels in new blendfiles keeping his inventory, currently it dosnt work for the blenderplayer which stops python before loading new blend files. 2008-08-19 11:53:24 +00:00
7f49f67352 Particles now got that force-hiding feature, too --> jahka: please take a look :) 2008-08-19 11:26:18 +00:00
a7f5109f23 BGE Blend file loading was using BLO_read_from_memory which meant relative linked libraries could not be found.
This is odd because BLO_read_from_file was commented out with """//this doesn't work anymore for relative paths, so use BLO_read_from_memory instead"""
Undoing Erwins changes from r7497, just use normal file loading. From the commit log its not clear if he means relative filenames or relative linked libs but from testing both work now.
2008-08-18 23:48:59 +00:00
Ken Hughes
deadd5ee01 Python API
----------
Add Material.enabledTextures attribute; this allows users to enable and
disable textures assigned to a material.
2008-08-18 22:39:55 +00:00
17e4222230 Little tweaks so 0 wind results in 0 noise, also removed double-mass dependancy in cloth 2008-08-18 19:32:21 +00:00
a06321d55c Implemented a find_nearest with heaps. This reachs a minimal number of distance queries.
But the cost of maintaining the heap seems to be very high.

For now DFS with local heuristics gets better times.. so BVHTree still uses that.
2008-08-18 19:31:40 +00:00
d6a9f7f485 Made modification alert slightly less intrusive and added Ignore option. 2008-08-18 17:08:25 +00:00
8562efe8a3 a) Forces can be hidden by deflector object now (need to talk with jahka about particle integration - should be copy-paste) see http://dldw.de/tmp/index.php?file=w2.blend (press play button in timeline and change the absorption value ob the cube) b) fixed deflector/collision bug with continues physics c) cloth wind/forces uses masses now d) even faster collision object gathering e) have fun ;) 2008-08-18 14:41:24 +00:00
2ce338f7e8 svn merge -r 16077:16174 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-08-18 14:33:26 +00:00
e1ceab6ed6 Missed parentheses from except clause, has a whole different meaning. 2008-08-18 14:16:34 +00:00
410dbe9037 python get/set material function for 3d text 2008-08-18 12:40:31 +00:00
5aecd230cb Fix for bug #17485: inter object sensor/controller/actuator links could
get lost in reading libraries. The pointers were being remapped in the
expand stage, but not all objects were guaranteed to be linked in at that
point, so they got lost. Now it always does this in the lib linking stage
for both regular and library objects.
2008-08-18 11:55:40 +00:00
d5a890c078 a) New unified effector system by Janne (jahka) + Me (genscher): particle and cloth/sb don't use different systems anymore. b) cloth wind corrected for new system c) Wind has noise option now d) @ Bjornmose: since the old factors are gone SB doesn't need to divide by 1000 etc. anymore. I didn't want to touch your code - you might like to take a look at it :) 2008-08-18 11:09:27 +00:00
a84d346939 #2: Fixing compile errors on mingw/cygwin (reported by aligorith) 2008-08-18 10:48:37 +00:00
f876fd66b4 Fixing compile errors on mingw/cygwin (reported by aligorith) 2008-08-18 10:37:15 +00:00
d39cdd7aad Moving the find panel caused some funky projection effect, introduced when I fixed the scrollbar. The scrollbar and panel now play nice. 2008-08-18 10:24:56 +00:00
7f30e5fdd2 Better class support with inheritance for text parsing. 2008-08-18 10:01:49 +00:00
ff45582551 Added vec.reflect(mirror) method to Python Mathutils Vector type
also made sensor and actuator text areas a bit bigger so full names can be read.
2008-08-18 02:29:25 +00:00
89a735e4f8 BVHTree fix (non 2.47)
It was building incorrect trees when there was only 1 leaf.
Code fixed to always generate a tree with at least 1 branch.. since most of bvh code relies on this.
2008-08-17 23:48:16 +00:00
0c79804dbe another compile fix reported by ccherrett 2008-08-17 23:03:45 +00:00
0db489b119 another compile fix reported by ccherrett 2008-08-17 22:58:00 +00:00
ed9a0fe7e9 Update MSVC project files after Win64 patch 2008-08-17 22:32:40 +00:00
9f6109002b Fix compile problem in MSVC after Win64 patch 2008-08-17 22:28:30 +00:00
904b97eee9 Win64: Another missing include only appearing with powerpc-apple-gcc-4.x (reported by daredemo/#blendercoders) 2008-08-17 19:58:13 +00:00
0c5adb7504 Win64: compiles fine with scons with gcc now 2008-08-17 17:22:10 +00:00
62845c3d52 Win64: forget include => this compile errors never showed up on msvc (if anyone wonders) 2008-08-17 17:16:49 +00:00
1f46aaa547 Win64: forget include 2008-08-17 17:12:10 +00:00
7fd701ab58 == BPython API ==
Bug: Draw.Number wasn't properly checking that the initial, min and max values passed to it were numbers. On errors Python would set an error flag that would only be caught later on, masking where the real problem was. Pesky bug...

Reported by André (jaguarandi) on irc, thanks!

PS for bpy devs: PyInt_AsLong returns -1 on error and sets the error flag. With functions like that we need to take special care or not that obvious bugs appear.
2008-08-17 17:11:51 +00:00
f4d682dd2c Win64: forrget include 2008-08-17 17:11:00 +00:00
fd0072e77c Win64: please check my changes if you ran across them ;) But should be fine since no additional crashes were reported! 2008-08-17 17:08:00 +00:00
68765dc94b Win64 commit: first little commit to test how it compiles on other plattforms - I'll then commit the other changes if all is fine :) 2008-08-17 16:36:37 +00:00
e93151dc39 Fix for text area scrollbar drawing incorrectly 2008-08-17 10:10:25 +00:00
3a62928777 Fix for numeric var types creating an error. 2008-08-17 10:08:38 +00:00
5c2015fa89 Fix for fix. Forgot to check if markers exist before trying to clear. Oops 2008-08-17 09:46:47 +00:00
fda00bc034 BGE patch: New Delay sensor (derived from patch #17472)
Introduction of a new Delay sensor that can be used to 
generate positive and negative triggers at precise time,
expressed in number of frames. 
The delay parameter defines the length of the initial 
OFF period. A positive trigger is generated at the end
of this period. The duration parameter defines the 
length of the ON period following the OFF period.
A negative trigger is generated at the end of the ON period. 
If duration is 0, the sensor stays ON and there is no 
negative trigger. 
The sensor runs the OFF-ON cycle once unless the repeat 
option is set: the OFF-ON cycle repeats indefinately 
(or the OFF cycle if duration is 0).

The new generic SCA_ISensor::reset() Python function
can be used at any time to restart the sensor: the
current cycle is interrupted and no trigger is generated.
2008-08-16 20:45:37 +00:00
9b6dffad2d Fixed problems with markers where Edit All did not behave the same for every marker and deleting selections that intersect markers did not remove the marker in all cases. 2008-08-16 20:31:38 +00:00
ae42934c93 Boids didn't get correct fall-off from wind effector.
Boids now react to vortex field also.
2008-08-16 16:29:12 +00:00
a6514f0c39 Animateable (ipos) power and fall-off for particle effectors. 2008-08-16 16:21:01 +00:00
310a6e2179 Esc removes markers in stages. Temporary markers are removed first (if any) then other markers follow. 2008-08-16 14:38:08 +00:00
a5d414c298 warning message for when sensors loose their controllers, has been a problem recently with linking in groups that contain game logic.
- also useful for testing bug [#17485] Sensors lost when loading objects from a group (apricot showstopper)
2008-08-16 12:42:34 +00:00
1ffede8872 SCA_PythonController.cpp - Made errors in python print the controller name, useful when blender crashes on printing the python error which happens frequently.
buttons_logic.c - NULL checks for game logic buttons, linking in groups with some logic links to objects outsude the group could crash blender. There are NULL checks for this case elsewhere so I assume it should be supported.
CMakeLists.txt - remove YESIAMSTUPID option, is not used anymore.
2008-08-16 00:06:51 +00:00
d1d1d2b870 Improvements to the base BPyTextPlugin module:
- Added a centralized function for resolving targets (aaa.bbb.ccc)
 - Added documentation support for locally defined classes and methods
 - The time taken to parse now dictates how long to use the cache before parsing again
 - Other tweaks and comments and support for numeric var types

The text plugin scripts have been updated to make use of these features.
2008-08-15 23:14:22 +00:00
528722f472 BGE bug fix: the fix in revision 16022 for bug #17450 was wrong: the formula used to extract scaling and rotation was giving incorrect results for some type of rotation, leading to wrong position and orientation for parented objects with no scale applied. The new formula follows Blender's internal math. 2008-08-15 22:17:50 +00:00
a88eb64f70 Simpledeform origin is no longer attache to parent by default
That was due to a current limitation on dag system.. that leads to cyclic dependencies.

So now you can attach the origin of a simpledeform  to an empty and mark whether its
affected by the relative position of empty or the global one.

brecht found a workarround to solve the cyclic dependency by
using a parent of both the mesh and the control empty:

empty_parent
 |
 |-> empty controlling simpledeform
 |-> mesh with simpledeform modifier
2008-08-15 00:51:44 +00:00
bda3e4f8e2 Merge from trunk 16031:16122 2008-08-15 00:00:27 +00:00
feb5e3a688 Add a function to join thread by index in the thread list.
This can be safely merged in trunk, in case anyone needs something like that.
2008-08-14 23:48:52 +00:00
db42038bcf merging trunk 15964 -> 16116 2008-08-14 21:16:48 +00:00
c965ef7824 Fixing button placement typo reported by Carsten on mailing list 2008-08-14 19:16:55 +00:00
4cec480338 Used the Python icon for the text plugin button and created an ON version. 2008-08-14 17:09:39 +00:00
7b1a2d5f3a Got rid of the horrible blocking UI problems with Find and Replace by using a blockhandler panel. The panel is shown when find is invoked with Alt F (or from the menu). Successive presses of Alt F search again, while the panel is visible. Alt H does the same for replace. (Ctrl F and Ctrl H also work - more like other editors) 2008-08-14 16:22:25 +00:00
c37923c7a3 Fixed bug related to some missed rays-hits.. just a lack of a FLT_EPSILON 2008-08-14 15:37:47 +00:00
c5d902133f Bugfix for a) Fluid ipos gone after save-load b) changing viscosity causes fluidsim to be reversed [both reported by broken] (at least 3 known bugs left) 2008-08-14 09:19:41 +00:00
47c2271d67 Python API get/setObject update for Actuators. (SetParent, AddObject, Camera and TrackTo)
* bugfix for BGE python api - SetParent actuator getObject would segfault if the object was not set.
* Added utility function ConvertPythonToGameObject() that can take a GameObject, string or None and set the game object from this since it was being done in a number of places.
* allow setObject(None), since no object is valid for actuators, Python should be able to set this.
* added optional argument for getObject() so it returns the KX_GameObject rather then its name, would prefer this be default but it could break existing games.
2008-08-14 08:58:25 +00:00
639f3e12a9 Last part of the svn release commit.
No need freeze, in a sec I merge both revision into
the 2.47 branch and tag it.
2008-08-14 06:42:52 +00:00
ae3a875ad2 Part one of the 2.47 release commit 2008-08-14 06:33:19 +00:00
29668ba2d0 bugfix (good for 2.47) - 2 cases of returning Py_None without increfing it. this can crash blender. 2008-08-14 05:06:59 +00:00
3f2cb6e878 game engine python api
* removed macros that were not used much, some misleading.
* removed error string setting calls that overwrote the error set by PyArg_ParseTuple with a less useful one.
* use python macros Py_RETURN_NONE, Py_RETURN_TRUE, Py_RETURN_FALSE
2008-08-14 03:23:36 +00:00
8da4ad74e9 Added subsurface levels option to normal projection.
Now when doing normal projeciton is possible to ask it to project along the normals
that the vertex would have if it was subsurfaced... this gives "better" projections on
low polys.

Point of this commit is to add the feature request from Eclectiel
http://blenderartists.org/forum/showpost.php?p=1181531&postcount=9

workflow as Eclectiel wanted is now possible:

to archieve a nice low-res retopology that aproximates a high-res mesh when subsurfaced:
1 - make base low-poly retopo
2 - apply a shrinkwrap with projection along normal.. and with SS level = N (where N>0)
3 - add a Subsurface with level N
4 - run bretch's script (ss_fit)
2008-08-14 03:05:13 +00:00
6a5976a0f5 Added a Marker sub-menu to the Edit menu in the text space header. 2008-08-13 21:13:56 +00:00
715ca7cbf6 starting threading code for retarget
nothing working yet, will finish tomorrow at home
2008-08-13 20:33:57 +00:00
89be876f96 Fixed problem of "lack of normal information" 2008-08-13 20:18:56 +00:00
43bf03580f svn merge -r 15988:16077 https://svn.blender.org/svnroot/bf-blender/trunk/blender
To have the 50% faster nearest_surface point.
Changed mesh_faces_nearest_point to return the face normal instead of collision normal
2008-08-13 19:22:35 +00:00
d2750f7bda Snap menu header rewording, to make documentation clearer (there was "mode" and "snap mode").
This can and should be merged for 2.47, as the docs will use those wordings.
2008-08-13 17:38:38 +00:00
6a8236a8da Fixed a typo
I was using the word "kept" (past tense) instead of "keep" (basic form).
I hope my english teachter dont sees this commit xD
2008-08-13 17:34:09 +00:00
55438d9fe0 Small bug fix: Scripts were not being recompiled after an error, if the (auto-selected) erroneous text was simply deleted and the script re-run. 2008-08-13 17:29:51 +00:00
3713470204 Fixed compile for windows 2008-08-13 13:36:09 +00:00
e2c42be829 PageUp/Down now moves the mouse cursor instead of just the view. Also added some other pops for when the cursor went off screen (click after horizontal scroll, undo, redo, etc.) 2008-08-13 12:20:49 +00:00
d60025e95f Bugfix: in the game engine, errors in a particular python script caused
somewhat random crashes, which I think was caused by the error print
using python objects that were freed too soon. Now it frees the dictionary
after the print.
2008-08-13 10:19:47 +00:00
1e7e8ceaac fixed a bug related with "cullfaces" option on shrinkwrap
enabled openmp during the tree queries (before it was only enabled during tree building)
2008-08-13 01:38:13 +00:00
5ade004592 Added a button to allow plug-ins to be enabled/disabled for each text space. It was confusing using the syntax button for both. 2008-08-12 22:12:24 +00:00
c6de35e558 *Added documentation mainly at shrinkwrap.c
*removed commented code about the dropped shrinkwrap options
*Removed references to "cut plane", "limitMesh".. its now called "auxiliar target"

*Added option to shrinkwrap over an selected axis
*"Normal projection" mode is now called "projection" since it can now project over "normal, and any combination X, Y, Z"
2008-08-12 20:43:10 +00:00
b30a925447 Add missing stuff in new scene code to properly init skeletor params properly.
Add sanity check on file load to fix old files (won't be merged in trunk).
2008-08-12 19:56:03 +00:00
65d0ef3e74 Speed improvements for reading text lines and the option to specify a range for Text.asLines([start[, end]]) Also some tweaks for the plug-in scripts and updates to pydocs. 2008-08-12 15:17:08 +00:00
7af0643df7 New nearest_point_in_tri_surface function.. 50% faster
Results were verified against the old function

Non 2.47 fix
2008-08-12 13:30:17 +00:00
2345757746 raise an error when assigning properties to a game object that cant be converted. also use python apis functions for converting floats and int types (faster then PyArg_Parse) 2008-08-12 12:32:54 +00:00
0410775e2e Rolled back on rev. 16039. Had problems with display, messages being blank and scripts not being recompiled in some cases. Needs more thought before committing. 2008-08-12 10:08:46 +00:00
bd34ecafef svn merge -r 15973:16060 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-08-12 09:49:46 +00:00
5a310fe8e1 Bugfix for non-compiling on msvc and mingw (reported by Matt) 2008-08-12 09:36:51 +00:00
ea134f8411 bdiego no 2.47 option for now
make soft bodies spawn threads on a mid level 
use G.rt == 16 to switch to 'old style'
i am going to remove that G.rt switch if everyone is fine /* i do not intend to keep 2 versions of code up because of "BAD STYLE" */
so .. give feed back ..
2008-08-11 20:40:29 +00:00
d4f1a98219 Fix flipped arc caused by harmonic interpolation 2008-08-11 20:01:15 +00:00
Ken Hughes
7f3a2a4abe Python API
----------
Added texture.offset and textute.gain attributes, to access parameters for Musgrove textures.
2008-08-11 19:06:30 +00:00
7e7d416f4d svn merge -r 15988:16055 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-08-11 13:29:38 +00:00
991539d1c8 preparing to merge trunk (those files were sent to trunk) 2008-08-11 13:16:06 +00:00
d90d413421 Suggestion list scrolling and selection made independent for easier use. Selections no longer move away from the cursor. 2008-08-11 11:10:16 +00:00
04b90467c3 * Fix for a bug zanqdo reported in IRC - transparent shadows were not
getting correct alpha when cast through node materials - in fact the 
node tree wasn't being shaded at all.
2008-08-11 05:23:36 +00:00
f876930904 fix for [#17365] PLY export script writes comment in invalid way
this is good for 2.47
2008-08-11 03:52:21 +00:00
a5d955632f Added sys.path module search to BPyTextPlugin module and fixed IndentationError when parsing. 2008-08-10 17:00:25 +00:00
5dad154414 Fixed inconsistencies between the text plugins and them not suggesting when called from the menu. 2008-08-10 16:07:14 +00:00
fb3a42d0f9 Shift keys cancelled the suggestions list (missed from earlier event refactor) 2008-08-10 14:24:14 +00:00
6ba72d4550 Fixed saving to relative paths and made external modification messages more user friendly. 2008-08-10 12:02:33 +00:00
f3c138e131 Changed a few places where visibility for EditMode bones is tested, so that they now use a macro I introduced in the previous commit. 2008-08-10 03:39:09 +00:00
2fe31596e3 == Armature Editing Tweaks ==
* New Tool: Switch Direction
This tool switches the direction of selected bones in EditMode, and can be found under the Specials Menu (WKey). It also adjusts the parenting, so that continuous chains can still be linked. 

* Bone Locking:
Removed Lock/Unlock functions from Specials menu, and moved this functionality under the Toggle/Set/Clear Bone Settings tools (Shift/Ctrl-Shift/Alt W respectively)
2008-08-10 03:10:07 +00:00
00c308391a * Script to convert BDF pixel fonts into C++ files blender can read. - Amiga bitmap font example http://download.blender.org/ftp/incoming/bitmap.png
* BF_CONFIG was missing from SCons help menu.
2008-08-10 01:38:02 +00:00
Ken Hughes
295155b448 Python API
----------
Remove documentation for Render.EnableEdgeShift and Render.EnableEdgeAll methods, which are no longer in the API.
2008-08-09 22:24:12 +00:00
c1e9d25364 Fix bug caused by extranuous return in distance weight calculations (ignored the weighting parameter)
Extract constant for shape level matching
Go to lowest node with matching shape, instead of just lowest node (created bugs)
2008-08-09 19:39:31 +00:00
83bcb9deff Python errors originating in the active text are now displayed at the top of the text area. Errors in other files/scripts still pop up a message as before and all errors are still printed to the console. This removes the need to switch to the console for local errors. 2008-08-09 18:11:40 +00:00
4c89ee7838 Line highlighting did not work for syntax errors. 2008-08-09 14:47:51 +00:00
7cbfe78044 Bugfix #17465: "Pose Edit Not Possible" message activated on 3D navigation
When navigating the 3d-view with a bone (or bones) selected, 'Rest Pose' enabled for the armature, and 'Orbit Around Selection' turned on, a "Pose Edit Not Possible" warning would pop up every time the view was manipulated. 

Was caused by a missing check for the 'TFM_DUMMY' transform mode used when calculating center to use (based on active item)
2008-08-09 10:50:59 +00:00
ed972db1a3 Merge from trunk: 15912:16031 2008-08-09 10:12:59 +00:00
d7f64d43dd Whole word ops. now treat symbols differently to whitespace allowing better control over cursor movements (solves mindrones' request). 2008-08-08 23:14:32 +00:00
4d83ce920a Improvements to the suggestion and doc listing events (when to update and when to remove). 2008-08-08 20:30:55 +00:00
e9c92144d1 Clipboard operations added to text editor RMB menu. 2008-08-08 16:49:14 +00:00
adcd339198 Fix for [#13697] Reactor particles with children doesn't render
-Particles were being recalculated a bit too aggressively. Normal particles didn't care, but since reactor particles have dynamic birth times they lost crucial information in the recalculation.
2008-08-08 16:40:41 +00:00
d42891975b Typing 'from a import b' threw an error if b was not found. Accidentally moved this out of the try block in an earlier tidy-up. 2008-08-08 15:54:04 +00:00
3832af90d7 Fix for [#16671] Moving a metaball that a particle system uses as a object (for visualization) also moves the particles
-The particle dupliobjects were using the objects trackflag in combination with it's rotation causing strange behavior. Now the trackflag is ignored and only the rotation of the object being duplicated is taken into account.
2008-08-08 15:38:14 +00:00
6501ff6bdd Fixing point-face distance to support degenerated tris/quads with area<FLT_EPSILON 2008-08-08 14:24:47 +00:00
98302f6c7c forgot update ver.number in last commit 2008-08-08 11:40:51 +00:00
277a420a90 == PoseLib: Add New (on Current Frame) ==
When adding poses to a PoseLib, it is now possible to make them be added on the current frame. It is still recommended to use the default method (plain Add New), as it is prevents poses stored in the PoseLib from being overwritten accidentally.
2008-08-08 10:15:08 +00:00
62f9ba67c0 BGE bug #17450 fixed: When we have parented objects with no scale-applyed objects the ray hit system doesn't work properly. Fix by separating rotation and scaling in the parent inverse node to keep scaling correct down to the leaf objects. Only isotropric scaling should be used, as always with the BGE. 2008-08-08 09:57:17 +00:00
fa98def953 Update MSVC project to include bvhutils.c 2008-08-08 09:52:32 +00:00
1d425f8da2 -> Fix for warnings in FLT exporter and Palette Manager
Removed buffer overflow masking warnings from the
FLT exporter and Palette Manager.
2008-08-07 22:31:35 +00:00
a821c8af1e Typing digits over the line numbers jumps to that line (from mindrones' wishlist) 2008-08-07 22:15:54 +00:00
c58e27d070 Fixing compile error with msvc (introducing max tree to 32) 2008-08-07 22:05:45 +00:00
2edb87d90e Fixed compiling warnings of bvhutils.c
Commited the right version of BLI_kdopbvh.c
2008-08-07 20:12:56 +00:00
Ken Hughes
10dc8169cc Disable redcode (the file format of RED one, R3D) by default. 2008-08-07 18:01:39 +00:00
36ef95eff5 BGE bug #17408 fixed: Radar sensor is oriented the wrong way when the set along negative axis. Improve reliability of Radar detection by clearing the manifold cache instead of updating it. 2008-08-07 17:29:06 +00:00
c25bb4685a BVH-KDOP update (merge from shrinkwrap branch): supports raytracing, nearest neighbour, non-recursive now, faster than kdtree.c implementation normaly, divided into 2 sources: generla structure in blenlib, mesh/derivedmesh depending interface stuff in blenkernel 2008-08-07 17:27:29 +00:00
29a44ca927 Moved bvhtree_from_mesh api to its own files
BKE_bvhutils.h and intern/bvhutils.c
2008-08-07 15:18:47 +00:00
0b533d022d Added several comments to BLI_kdopbvh
Changed BENCH to print both wall-clock/real time and cpu time
2008-08-07 14:26:27 +00:00
a37938ea3c Word-wrap support for up and down arrows between lines, and home/end keys for a wrapped line segment. 2008-08-07 14:21:43 +00:00
15952fb26c BGE bug #17409 fixed: BGE Near Sensor Incorrect once inside the radius. The bug is located in Bullet: the manifold contact points for non-response objects (sensor, ghost) are not refreshed and stay in the cash as long as the objects overlap in the broad phase. Instead of fixing Bullet, I put a work around in the BGE. This may need review when a new Bullet library is integrated 2008-08-07 11:31:24 +00:00
3adf5dda97 BGE fix: alignToVect() fac parameter clamping should obviously be done the other way round 2008-08-07 11:25:45 +00:00
a1f46e1e32 fix for [#17448] Duplicating textures with IPOs doesn't increment IPO user count 2008-08-07 09:56:31 +00:00
66d6221899 -> Slight tweak to FLT exporter
FLT files written by the FLT exporter would
reference external files (other FLT files,
texture maps, ect) with standard backslash
seperators on win32. However, many tools
that deal with FLT files expect directory
seperators to always be forward slashes
regardless of platform.
2008-08-07 04:38:35 +00:00
5d62ad194d added back copy buttons to "Texture Face" panel. 2008-08-07 01:02:06 +00:00
Chris Want
ba12aa0962 Getting the blenderplayer to compile/link with CMake.
Note: yuck, this is a horrible way to do it -- python devs should
think about splitting the python stuff into separate libs if they
only want to partially include it in the game engine.
2008-08-06 20:37:15 +00:00
Ken Hughes
6688ab7ae4 Python API
----------
Fix typo in documentation for render.startFrame() and render.endFrame().  Arguments are valid in the range 1 to MAXFRAME.
2008-08-06 20:05:08 +00:00
Chris Want
5539d57b1a Fixed a warning due to a change in policy between cmake 2.4 and
cmake 2.6. (Other warnings still exist, but are harder to fix.)
2008-08-06 19:47:52 +00:00
523634ca17 svn merge -r 15908:15988 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-08-06 16:50:07 +00:00
e57c5ef56c Fixed non_recursive BVHbuild with openmp
CHanged the BENCH functions to use: gettimeofday (wall time) instead of clock (cpu time)
This was to test if the openmp was working right.
2008-08-06 15:46:38 +00:00
6c0f4660ed Various UI drawing and event tweaks to make markers feel more natural and avoid getting in the way. If there is a marker under the cursor, ESC will remove it and others in its group. Otherwise all temporary markers are removed. Tab finds/cycles/removes temp. markers, cycles non-temp. markers (under cursor) and behaves normally in all other cases. 2008-08-06 13:46:44 +00:00
8102217b9c BGE fix: confirm fix for segmentation fault by Diego and remove warning in calling ConvertMaterial Ipos. 2008-08-06 10:23:47 +00:00
553e35e36f * blenderplayer wasnt useing the scenes frame rate.
* GBE Python API's alignToVect wasnt clamping the align ammount from 0.0-1.0
* Generated images arnt animated - use for a test to see if the textures animated.
2008-08-06 04:09:10 +00:00
799ba2c351 Added a Python interface to the marker system with a few additional functions for modifying text selections in general. Tweaked some of the events and drawing code and added a template completion script along the lines of gedit's snippets. 2008-08-05 23:23:31 +00:00
028d44c075 Made Mathutils its own module rather then GanmeLogic.Mathutils 2008-08-05 22:26:00 +00:00
553da831e6 Update MSVC project files for Mathutils support in the blenderplayer 2008-08-05 22:23:38 +00:00
Ken Hughes
ab5f21e24c Fix compiler warnings from earlier commit. 2008-08-05 22:13:13 +00:00
a86609af8e Fix segmentation faul in GE.
We assign the material name before check the pointer.

Please Benoit check this and also I have a compiler warning
about the second argument in the previous call of
ConvertMaterialIpos, the argument is NULL but the function
need a dword.
2008-08-05 21:20:14 +00:00
2d04b641d4 Just a tmp commit about bvhtree build
Theres something broken with BVHtree queries.. updates are not advised at all
2008-08-05 18:49:51 +00:00
06c3dee92b Find and Replace now support "Mark All" which marks all occurrences of a string and allows them to be edited from one instance. Improvements have also been made to the UI allowing better control over which occurrences to replace. 2008-08-05 17:43:03 +00:00
553694b614 BGE fix bug #17430: BGE Collide/Touch Sensor interfearing with other unrelated sensor states. The bug was introduced in the recent logic optimization patch. It only affects collision and touch sensors. The bug is fixed by keeping track of registration count. 2008-08-05 16:23:33 +00:00
1d87a596e4 svn merge -r 15800:15973 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-08-05 16:12:40 +00:00
b277de2895 Fix for [#17421] Issue with Displace modifier not updating with
animated textures

I have added a dependsOnTime function for the Displace modifier which checks
if the displacement texture has IPOs, is a plugin, or uses an animated image.
2008-08-05 14:42:04 +00:00
cd1d46c61d Added GameLogic.Mathutils so Mathutils and its types can be accessed from blenderplayer.
also changed importText so it dosnt do a malloc
2008-08-05 09:35:46 +00:00
9e968cea47 Bugfix #16673: Segfault when using Bake Constraints Script
There were several buggy things here (in order of significance):
1) PyAPI method didn't check to make sure that there was an active posechannel when deleting posechannel constraints. This was required by constraint_active_func() to be able to update the 'active' flags for the constraints in that stack
2) PyAPI method removed the links to the constraint data from the constraints list, even though that wasn't necessary, and may have caused memory leaks. 
3) constraint_active_func() had no error checking for no constraints-stack being found
2008-08-05 03:29:46 +00:00
e238066525 Merging with trunk
15568 - 15963
2008-08-05 02:27:09 +00:00
07bc1e56fe own bug in weightpaint cleaning, wasnt removing as many groups from verts as it should be. 2008-08-04 23:20:12 +00:00
53e535dfcf Text Markers: multiple, coloured selections within a Text object with group relationships. They allow portions of text to be edited as one and enable quick jumping between and editing of different areas.
Flags control the behaviour and grouping of markers. At present, Ctrl+M places a marker with TMARK_EDITALL set for testing purposes.

I have also split the text area event handler into separate methods for marker handling and the existing text tools. This makes the events system much easier to follow as it was getting a little hairy.
2008-08-04 23:01:47 +00:00
0008b1d424 Shrink BVHNode by 16bits 2008-08-04 20:30:57 +00:00
d4b646103a Option to hide embedding dots on display
Merge internal and external filtering in a single loop (solve problems caused by order of filtering)
Made graph length calculations work on cyclic graphs (it unrolls them)
2008-08-04 19:12:42 +00:00
8d285fc10a Fix for better icc + openmp support using scons 2008-08-04 17:24:11 +00:00
51d90eeb49 Fix for [#17291] Array modifier merge caps leaves a whole
This code was missing a test_index_face call after merging, so it was making
quads with v4 == 0.
2008-08-04 16:44:13 +00:00
cbec9883f9 Fix for [#17376] Applying mirror modifier does not respect UV pinning.
The custom data system wasn't swapping pinning or selection flags for MTFace
data when face vertices were reordered.
2008-08-04 14:49:55 +00:00
a0f39107fd Made shrinkwrap variables be initialized when declared 2008-08-04 14:27:25 +00:00
9ec6083cfe Fix for [#17414] Particles doesn't obey to lattice once children are added
-Lattice calculations were left out for children by accident
2008-08-04 14:17:11 +00:00
0c9508d248 Fix for [#17366] Particle children from particles only take colour from UV-Maps
-Some old code in particle rendering hadn't been updated properly.
2008-08-04 13:57:04 +00:00
919eba04de SimpleDeform modifications:
* Added "Lock axis" options on taper and strech/squash (suggested by ZanQdo)
  * Better control of deform factor (suggested by ZanQdo)
  * Added eModifierTypeFlag_AcceptsCVs (so it now accepts both curves and meshes)
2008-08-04 13:12:35 +00:00
d786fead10 Fixed double inflation in case of co_moving points 2008-08-04 11:50:36 +00:00
2e6a3710bb * Armature hierarchy selection tools
These are for use in pose mode or armature edit mode, to let you quickly traverse up and down a chain of bones. 
It's quite useful for bones that are in hard-to-click places.

The tools are:
*Select parent/child ( [ and ] )
selects the parent or child of the active bone, deselecting the original active bone

* Extend select parent/child (shift [ and shift ] )
selects the parent or child of the active bone, adding to the selection

Thanks to Joshua for reviewing this so promptly!

PS. I'd like to use these [ and ] keys more widely in blender as consistent 'select next / previous' tools. I can imagine it being very useful for a lot of things like keyframes, nodes, mesh edges, etc.
2008-08-04 11:47:17 +00:00
3598dcd279 * KX_GameObject.cpp - error with getMesh(), was returning None rather then an error with invalid args. also memory leak with getVectTo() if invalid args were given.
* Material.c - functions for get/setRayTransGlossSamples were not being used.
* BPY_interface.c - removed function GetName(), since everything else just uses id->name+2.
* header_info.c - added ifdef win32 around copy_game_dll since its not needed for other os's yet
2008-08-04 01:57:22 +00:00
ae762bec91 BGE patch #17398 approved: implementation of BGE method getVectTo(). 2008-08-03 21:59:36 +00:00
df2364ab1a Update MSVC project files for new Boolean Operation file (BOP_Merge2.cpp) 2008-08-03 21:57:52 +00:00
b647c5bba5 == FFMPEG ==
This fixes:
[#16655] Blender crashes when Fraps videos are added to the sequencer

(sorry, color conversion is not supported by swscaler for some reason,
so currently, only the crash is fixed)
2008-08-03 16:11:57 +00:00
ac7aef6b3d DXF-importer script. Works well with 2.46winXP
Please commit to 2.47 branch
patch history:
 v1.12 - 2008.08.03
 c2 warningfix: relocating of globals: layersmap, oblist 
 c2 modif UI: buttons newScene+targetLayer moved to start panel
 v1.12 - 2008.07.04
 c1 added control Curve's OrderU parameter
 c1 modif UI: preset buttons X-2D-3D moved to start panel
 b6 added handling exception of not registered LAYERs (Hammer-HL-editor DXF output)
 b5 rebuild UI: global preset 2D for Curve-Import
 b5 added UI-options: PL-MESH N+N plmesh_flip and normals_out 
 b5 added support for SPLINEs, added control OrderU parameter
 b5 rewrote draw module for NURBS_curve and Bezier_curve
 v1.12 - 2008.06.22
 b4 change versioning system 1.0.12 -> 1.12
 b4 print at start version-info to console
 b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name)
2008-08-03 15:57:09 +00:00
855fa737d7 == Sequencer ==
Fixes:
[#15082] Sequencer: for image strips, the Input file field disappears if the cursor is out of the selected strip

also it wasn't really a bug, since the file name of image input strips
_has_ to depend on CFRA.

Well, we choose the next possible image strip, which is most likely the thing,
most people expected...
2008-08-03 15:56:35 +00:00
7fc6741bcf == Sequencer ==
This fixes:
[#17405] Sequencer: unselected black strips are unreadable
using
[#17418] Fix for bug #17405: unselected black seq strips text unreadable

Thanks to Roelf De Kock for providing the patch and 
mindrones for the bug report :)
2008-08-03 15:45:53 +00:00
c2cd6bebe6 added openmp support for bvhtree build (max processes = tree_type) 2008-08-03 15:37:24 +00:00
cad3b73144 == Sequencer ==
This fixes:
[#17413] Sequencer: Blender crashes pressing R on a color strip
2008-08-03 15:35:56 +00:00
27b259345e Grease Pencil Drawing:
Some WIP code for 'nicer' drawing of thick 2d-strokes that will hopefully result in smoother lines, particularly with abrupt direction changes. Currently the code is hidden behind the rt button (for rt != 0), as in some cases, it still looks rather bad.
2008-08-03 11:55:45 +00:00
7a14a3580b Little speedup for kdop-bvh 2008-08-03 11:40:09 +00:00
ae5217733d Added shrinkwrap as a constraint.
All modes are available:
nearest surface
nearest vertex
normal projection (along X,Y or Z axis)
2008-08-03 02:02:15 +00:00
1d49ed89cb Bugfix for non working selfcollisions [no 2.47 bugfix] 2008-08-03 01:41:57 +00:00
ad2be5f64f Bugfix for weird + in the code, no idea why it compiled (yet some selfcollision bug to fix) [no 2.47 fix] 2008-08-03 01:00:51 +00:00
bf168dc3c5 Small update to get the BlenderPlayer compiling (also needed for 2.47) 2008-08-02 22:11:22 +00:00
e632b966ec BKE_global.h include path wasnt correct. made boxpack2d.c a bit more
readable. no functionality changes.
2008-08-02 21:39:01 +00:00
03f9c6a3fc Copies all required DLLS for Save Game as Runtime.
Under Windows, all DLLs are copied to the same folder as the runtime .EXE, so that the process becomes a single click and deploy solution.

Linux doesn't require this ( thx for info centralnoise ) and will update to work on OS/X after I do a bit of research on .a and .so files ( thx for info kaito ).
2008-08-02 17:08:16 +00:00
341655eab7 == imagebrowser ==
- HKEY now toggles hide/show dotfiles
2008-08-02 09:44:01 +00:00
82d87b2ab9 * patch #17394 by Vilem Novak - add menu item for 'Make Proxy Object'. Thanks! 2008-08-02 06:31:56 +00:00
38aa350173 * (slightly modified) old patch #7471 from Davide Vercelli - menu items for Show All Layers/Show Previous layers in the 3D View. Sorry this took so long! 2008-08-02 06:29:15 +00:00
b11790e08f * Minor tweaks to file menu item naming 2008-08-02 06:11:35 +00:00
451c00697f Scons - Mingw Compiling Fix:
When using BF_SPLIT_SRCS as a hack to get some of the larger libs compiled, there were some problems linking Blender related to some boolean calls. This commit tweaks the priorities for the boolean libs for the 'intern' group so that they get linked before the src libs are.
2008-08-02 00:25:50 +00:00
ed5002458b Merged 15771:15912 from trunk 2008-08-01 23:39:52 +00:00
Maxime Curioni
7565990db2 soc-2008-mxcurioni: made considerable changes to support cross-language polymorphism for UnaryFunction0D, Interface0D, Interface1D. Add to change UnaryFunction1D<void> to static UnaryFunction1D_void. Resolved namespace collision on the Image class (changed to FrsImage). There is greater support for style modules but somehow, some do not show anything yet (japanese_bigbrush being an example). 2008-08-01 21:55:58 +00:00
289d875dfd svn merge -r 15688:15908 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-08-01 21:37:36 +00:00
aa02e605f1 Fix for GE Make Runtime menu option
Doh - I forgot to add a comment to the previous commit.

This adds a file exists check for Make Dynamic Runtime for the GE.  It also removes this menu option for now, as the required file ( blenderdynplayer.exe ) hasn't been included with the Blender app for quite a few releases ( therefore the feature has been broken ).

I also renamed the option, to make it a bit more understandable.  This might even be better moved to the Game menu, but I didn't want to do that ( yet :) )
2008-08-01 21:17:54 +00:00
fc52146342 2008-08-01 21:12:47 +00:00
ede6c42dc2 Fix problem with long stretches without embedding between head/tail nodes and the actual start and end of embedding bucket.
Instead of having to muck around in the generating and retargetting code to deal with those cases, just fill dummy buckets with interpolations.
2008-08-01 20:29:42 +00:00
2568b3d486 Draw embeding points in blue, easy to visualize long stretches without embedings. 2008-08-01 20:01:01 +00:00
b767d406ad Mouse cursor positioning and selections now work with word-wrapped text. It's not the best solution but it does the job for now. I wanted to get a working version committed before I improve/break it. 2008-08-01 13:00:53 +00:00
115dfb22cc Ipo Editor would not allow access to either World or Lamp texture Ipos. Now it does. Fixes bug #17379. 2008-08-01 12:56:29 +00:00
Maxime Curioni
c324f0cbc7 soc-2008-mxcurioni: clean-up #2 2008-08-01 02:25:21 +00:00
Maxime Curioni
4580fd1415 soc-2008-mxcurioni: clean-up #1 2008-08-01 02:16:36 +00:00
Maxime Curioni
149f3688a4 soc-2008-mxcurioni: moved Curve to FrsCurve, fixed bugs with some style modules having with strokes without a representation and iterators not being correctly routed. For example, the cartoon style module should work now. 2008-08-01 02:15:25 +00:00
Ken Hughes
cb0aa467cd Tools
-----
New boolean merge algorithm.  The current code often does a poor job of merging tris and quads after the operation, resulting in many unnecessary faces.  This commit add a new algorithm which takes advantage of topology information saved in the interal BOP structures.

The file intern/boolop/intern/BOP_Misc.h has two #defines which control which algorithm(s) are compiled.  They are set now to compile both, with the new algorithm as the default.  The original algorithm can be enabled by setting the "rt" debugging button on the Scene panel (F10) to 100.

One note: the current boolean code still occasionally creates a non-manifold mesh from an operation on two manifold meshes.  The original merge algorithm would sometimes "close" these meshes and sometimes not.  The new algorithms behaves the same way, but sometimes closes a mesh the original would not and sometimes leaves open a mesh the original would close.  My fairly extensive tests did not indicate any significant difference in the percentage of final non-manifold meshes.
2008-07-31 18:37:03 +00:00
2c4a1bf381 Accidentally removed too many BIF_ThemeColors resulting in funny colours for non-syntax-highlighted text. 2008-07-31 18:16:01 +00:00
baf20b803f Selected two closest nodes when joining subgraphs, not just closest on one side with first on other side. (helps get good result out of high joining threshold) 2008-07-31 17:54:21 +00:00
d66449996c == Grease Pencil Eraser - Tweaks ==
Improved accuracy of the eraser a bit. Now it does a boundbox test first before trying to erase strokes, which means that other (rather unrelated) strokes are less likely to be affected as well.
2008-07-31 12:23:29 +00:00
db82e15e6f Korean translation, provided by J.H. Jeong (yongdori)
(Bugreport 17415)
2008-07-31 12:23:09 +00:00
Maxime Curioni
6a6c23ecd8 soc-2008-mxcurioni: moved namespace collision resolution to the freestyle_init.py (for Curve, Material and Noise) 2008-07-31 11:59:06 +00:00
726982be29 Word wrap fix: There were cases where the brackets, cursor and selections (which all use the same function) weren't lining up with the drawn text (which uses its own function). This fix simplifies the algorithm and hopefully now makes it work for all cases. 2008-07-31 11:54:17 +00:00
Maxime Curioni
f09f89d5dc soc-2008-mxcurioni: added a Freestyle panel to select a style at run-time, by specifying its pathname. By default, it is loaded with the contour.py path. 2008-07-31 11:20:30 +00:00
Maxime Curioni
3010f2b753 soc-2008-mxcurioni: the native Python system now supports cross-language polymorphism for the following classes: BinaryPredicate0D (__call__), BinaryPredicate1D (__call__), UnaryPredicate0D (__call__), UnaryPredicate1D (__call__), StrokeShader (shade), ChainingIterator (init, traverse).
Other methods could easily be supported in the future. The method now works as planned for the contour style. For style modules with Python shaders, there still is a problem that I will fix right away.
2008-07-31 08:50:12 +00:00
Ken Hughes
1b78333087 Tools
-----
Minor changes to boolean code; add an new include file to gather various
#defines global to the boolean system.  Currently, this just allows control
of whether some debugging code is compiled or not.

This is a precursor commit for some other boolean optimizations/cleanups.
But in case that commit is later reverted, this code should still remain.
2008-07-30 21:52:02 +00:00
Nathan Letwory
01b1bd4901 * another commit adding std:: to the sort call (older msvc [<9] choked?) 2008-07-30 20:45:04 +00:00
409d0eac7c Merge subgraph with closest node, not just first node under threshold. 2008-07-30 18:10:21 +00:00
8a8a12ed84 BGE patch: logic optimization part 2: remove inactive sensors from logic manager.
With this patch, only sensors that are connected to 
active states are actually registered in the logic
manager. Inactive sensors won't take any CPU,
especially the Radar and Near sensors that use a
physical object for the detection: these objects
are removed from the physics engine.

To take advantage of this optimization patch, you
need to define very light idle state when the 
objects are inactive: make them transparent, suspend
the physics, keep few sensors active (e,g a message
sensor to wake up), etc.
2008-07-30 17:41:47 +00:00
d05363627b Update MSVC project since recent commit 2008-07-30 17:22:57 +00:00
7f170c18bb Bugfixes: fix for two memory leaks related to dupligroups,
and a missing reference count in the trackto actuator. This
showed up as leaked pose data, but actually the whole object
was not being freed.
2008-07-30 16:15:15 +00:00
9667af9cfd Oops, forgot about horizontal/vertical scrolling. Cursor, selections and brackets should now draw correctly when scrolled. 2008-07-30 11:27:04 +00:00
2d3a57eaa3 Bugfix for mesh deformer under windows --> uninitialized variable was used in meshdeform_inside_cage() 2008-07-30 11:21:10 +00:00
f3a4f3adaf Grease Pencil Bugfixes:
* Segfaults with eraser should now be fixed 
* Attempted fixed for sequencer redraw problems with buttons
2008-07-30 09:20:05 +00:00
7b819bc631 == Grease Pencil - Eraser (First Draft) ==
This commit introduces the ability to erase strokes. Admittedly, the code for this is not totally stable yet, and doesn't always produce optimum results. I'm committing now for backup purposes.

It currently uses the lasso code to check whether segments of the strokes (a segment occurs between two recorded points) occur inside a region defined by the 'eraser' stroke, or any intersections it makes with the 'eraser' stroke.

There are multiple ways to erase strokes:
* With 'Draw Mode' on, use RMB-drag to erase
* With a tablet, use the 'eraser' end of the stylus
* Hold the Alt Key, and use the 'selection' mouse-button (i.e. LMB if mouse-button swapping is on, RMB otherwise) to erase. For this one, this is necessary to avoid overriding the view-rotation hotkey combo for 2-button mice!

Todo:
* 3d-strokes are not correctly mapped back to screen-space for sampling yet
* Drawing of eraser strokes is still not distinctive enough
* After running a few times, may cause stack corruption/segfaults, so be careful!


== Bugfixes ==
* Grease-Pencil Onion-Skinning works again. Onionskining was being supplied the wrong frames, and the alpha factor was still the old one used for 0-255 ranged colour values
2008-07-30 09:07:56 +00:00
Maxime Curioni
a482f64424 soc-2008-mxcurioni: Tested SWIG-less environment more and understood why the former predicate methods were not working. As Stéphane had mentioned a few months ago, Freestyle uses SWIG directors to provide cross-language polymorphism. The API and the system I had provided did not support that feature and only implementations in C++ were supported. To correct the problem, after researching how directors are implemented in SWIG, I provided the same functionality. So far, I only provided the code for the UnaryPredicate1D class and it works. The implementation is in intern/python/Director.cpp and Operators.cpp. I will port the remaining directors tonight and continue to test it.
To prevent strokes from piling up after each render,  I clear the canvas at each render now (as it should have been all along)
2008-07-30 01:51:40 +00:00
140a8b740d Bracket matching now works with word-wrap. Mouse selection and scrolling to do. 2008-07-30 00:05:19 +00:00
34bb446734 Simple changes to Motion Actuator UI.
This includes...

- Renaming dLoc and dRot as Loc and Rot ( as well as changing the tooltip to location and rotation ).  dLoc and dRot are programming terms, not user terms.

- Placing Loc and Rot as the two initial shown values, so that the physical ones are all shown together.

I also changed it so that only Loc and Rot are shown in the UI, unless the object is Dynamic ( as the other values only make sense if it is dynamic ).

These are just a few simple changes, that should make a lot of difference to users when learning how to use the GE.


--------------------------------------

Things I'd *really* like to do to this, when I get a chance to code Blender again ( hopefully in a few days time, after I have finished teaching on the GE course )...

Color / Colour tint the X,Y and Z entry boxes as slightly red, green and blue, to reflect the colour of the axis / transform gizmo
...or...
Just show X,Y and Z labels above all of the values.

Getting to grips with the whole XYZ thing is very confusing for users, esp when they are presented with 6 x 3 entry boxes.
2008-07-29 22:44:43 +00:00
Nathan Letwory
e04c48df86 * making sure BGE compiles after brecht's big commit (r15867). Needed <algorithm> to compile with msvc. 2008-07-29 21:56:50 +00:00
7f3c27995e Copy Attributes now has option to copy all physical attributes.
There existed two options to copy only the mass, and only the damping, but no option to copy all of the physical attributes.

This patch adds in this option, right under the Mass and Damping listings.
2008-07-29 21:49:59 +00:00
ca951b3627 Am teaching a GE course this week, and am finding some small issues that I'm hoping to patch.
This one deals with the very small default clipend value ( 100.0 ) when pressing P to run the GE from a non-camera view.  ( ie if the user zooms out a bit from the default box area, the box will get clipped out of view, so it's a WFT from the user )

To see what this fixes, load up Blender default scene, go into perspective, and press P. Everything looks grand.  Now, zoom out until the box is about 10 pixels high, and press P again.  The box will disappear / be clipped out.

I've set the clip end to the maximum ( 5000 ) as defined in Camera.h.

This should be suitable for inclusion in 2.47 branch also.
2008-07-29 20:28:11 +00:00
2efd74138c Bug fixes:
Retag subgraphs when merging, to prevent loops
Mark missing up link in multi resolution as NULL
Ignore hidden vertices when propagating weight between islands
2008-07-29 20:20:24 +00:00
039814f7d2 No long needed here (win64 cleanup) 2008-07-29 18:07:06 +00:00
908337bee1 Game Engine: alpha blending and sorting
=======================================

Alpha blending + sorting was revised, to fix bugs and get it
to work more predictable.

* A new per texture face "Sort" setting defines if the face
  is alpha sorted or not, instead of abusing the "ZTransp"
  setting as it did before.
* Existing files are converted to hopefully match the old
  behavior as much as possible with a version patch.
* On new meshes the Sort flag is disabled by the default, to
  avoid unexpected and hard to find slowdowns.
* Alpha sorting for faces was incredibly slow. Sorting faces
  in a mesh with 600 faces lowered the framerate from 200 to
  70 fps in my test.. the sorting there case goes about 15x
  faster now, but it is still advised to use Clip Alpha if
  possible instead of regular Alpha.
* There still various limitations in the alpha sorting code,
  I've added some comments to the code about this.

Some docs at the bottom of the page:
http://www.blender.org/development/current-projects/changes-since-246/realtime-glsl-materials/

Merged some fixes from the apricot branch, most important
change is that  tangents are now exactly the same as the rest
of Blender, instead of being computed in the game engine with a
different algorithm.

Also, the subversion was bumped to 1.
2008-07-29 15:48:31 +00:00
b204eeca7d Selections now draw correctly when word-wrapped. 2008-07-29 11:37:11 +00:00
Maxime Curioni
7d5eaa674b soc-2008-mxcurioni: corrected problems in API with UnaryFunction1DVoid subclasses and Curvature2DAngleF1D. Understood that Curve and Noise classes cannot be defined in Freestyle's API because they are already given by Blender's API. Will rename to FrsCurve and FrsNoise and change the corresponding style modules. 2008-07-29 11:19:30 +00:00
Maxime Curioni
4fa17fc69c soc-2008-mxcurioni: SWIG replacement is effective and the native Freestyle API renders a correct result for the test style module 'contour.py'. More testing needs to be done to make sure my work was correct.
To make it work, I had to:
- update Operators to include all of its methods in the Python API
- redefine the Freestyle modules as local classes, allowing predicates to support the __call__ method (I found out that Python does not allow modules to be callable). The API is defined in the new freestyle_init.py  file.
- remove all references to former Python Freestyle API (located in source/blender/freestyle/python/, under the Freestyle.py file) and replace it with the new API file.
- normalize all constants related to the Nature class
- redefine the logical_operators.py file so that AndUP1D, OrUP1D and NotUP1D would be subclasses of a UnaryPredicate1D subclass having a operator() implementation. Using UnaryPredicate1D as a superclass would somehow prevent calls to the operator(). For the time being, I chose ContourUP1D (even though it does not really matter which subclass it is, since the __call__ method is redefined in all of these classes). I will implement this classes in C++ to get rid of the problem altogether.
- turn off a few classes that somehow are not well recognized (Noise, Curve...). I will reenable them later once I understand what's going on.
2008-07-29 10:45:06 +00:00
Maxime Curioni
725915615a soc-2008-mxcurioni: SWIG replacement is effective and the native Freestyle API renders a correct result for the test style module 'contour.py'. More testing needs to be done to make sure my work was correct.
To make it work, I had to:
- update Operators to include all of its methods in the Python API
- redefine the Freestyle modules as local classes, allowing predicates to support the __call__ method (I found out that Python does not allow modules to be callable). The API is defined in the new freestyle_init.py  file.
- remove all references to former Python Freestyle API (located in source/blender/freestyle/python/, under the Freestyle.py file) and replace it with the new API file.
- normalize all constants related to the Nature class
- redefine the logical_operators.py file so that AndUP1D, OrUP1D and NotUP1D would be subclasses of a UnaryPredicate1D subclass having a operator() implementation. Using UnaryPredicate1D as a superclass would somehow prevent calls to the operator(). For the time being, I chose ContourUP1D (even though it does not really matter which subclass it is, since the __call__ method is redefined in all of these classes). I will implement this classes in C++ to get rid of the problem altogether.
- turn off a few classes that somehow are not well recognized (Noise, Curve...). I will reenable them later once I understand what's going on.
2008-07-29 10:42:10 +00:00
Maxime Curioni
db6388e0f2 soc-2008-mxcurioni: finished porting the Freestyle API. All of the original classes, except EdgeModifier and TimestampModifier (which aren't even ported via SWIG), are available under the Blender.Freestyle module. Testing of the porting will now begin to make sure the SWIG-less system works as the original.
Quite a few modifications were made to finish the API:
- Freestyle's SConscript was modified to catch all files within the intern/python directory, allowing integration of future shaders implemented in C++.
- the Operators class was ported, with a special care of making its methods static (using the METH_STATIC flag in the tp_methods method definitions)
- all of the type-checking functions [ BPy_[class name]_Check(obj) ] were changed to allow subclasses to be seen as that type too: instead on looking at the ob_type value, the PyObject_IsInstance function is used.
- all of the iterators can now retrieve the object pointed to by the operator, using the getObject() method. A directedViewEdge pair is returned as a list of the two elements in the pair.
- all of the style modules were copied to a style_modules_blender/ folder and were modified to use Freestyle as a Blender's submodule. IntegrationType and MediumType was also integrated (for example, changing MEAN to IntegrationType.MEAN).

Testing now begins. If everything works correctly, I'll move on to lib3ds removal right away.
2008-07-29 05:45:16 +00:00
5ba56ffe47 Bugfix to get deform modifiers after subsurf work again (reported by nudel) 2008-07-28 22:56:30 +00:00
Maxime Curioni
e4677c409d soc-2008-mxcurioni: add all predicate subclasses( BinaryPredicate1D, UnaryPredicate{0D,1D} ).
There is just one more class remaining to port (and probably the most important): Operators. After that, I'll be able to test whether Freestyle functions well without SWIG.
2008-07-28 22:53:42 +00:00
b0c513e83a BGE patch: fix support of group hidden layer in dupli group instantiation: only the objects in layers matching the group layer mask will be instantiated. This is equivalent to the 3D view 2008-07-28 22:36:27 +00:00
Ken Hughes
3120af6f34 Bugfix for #17396. Adding a text object would segfault when using freetype
2.3.6 or later.  Thanks to Cyril Brulebois for a one-line patch, which was
sent to the ML a while back.
2008-07-28 22:10:32 +00:00
dfc93da127 UI fixes are the hardest ones.. (2nd try) 2008-07-28 21:52:37 +00:00
dd1634b07d Bugfix for messed up UI (reported by nudel) 2008-07-28 20:24:05 +00:00
8b77b54469 WIP commit, completely untested (should introduce: 1. copy of modifier settings work, 2. reverse domain, 3. reverse control) 2008-07-28 16:55:48 +00:00
fd327cb393 Word wrap fix: formatting and cursor positioning was not working correctly for wrapped lines containing tabs, or lines with no breaks. 2008-07-28 15:47:46 +00:00
d63a3f7a7c Bugfix for not-working-deformers (reported by nudel) 2008-07-28 15:21:18 +00:00
c566867de9 Add automatic weight probagation between islands without any selected vertex. Makes it easier to do multi part meshes. 2008-07-28 15:03:58 +00:00
bc85f11e68 Bugfix: game engine does not support non-camera type objects as a
camera, would crash, so disabled using the object as a camera then.
2008-07-28 14:28:19 +00:00
12f0fb1a42 Draw cursor at the leading edge of selection (as in other apps.) and hide cursor swapping from the user. 2008-07-28 11:54:13 +00:00
f45aca0447 Complete rewrite of syntax highlighting and formatting. Some improvements:
- Takes less than half the time to format a full document
 - Where possible only the required lines are re-parsed when text is changed (was the whole file, for every key press!)
 - Memory is allocated in one place only (there were all sorts of problems here)
 - Should be easily extensible for other scripting languages
 - Lots of comments to make it very easy to follow / change
 - def and class are now properly coloured. They had a theme colour but the checks didn't work.
2008-07-28 11:05:35 +00:00
48b7f16d76 Phase1: fluidsim obstacles/control objects are grabbed from the specific position in modifier stack now (introducing new funciton in DerivedMesh.c), fixed some UI glitches. 2008-07-28 11:01:34 +00:00
91ece746b8 commit by jms:
Rvk1 to rvk2 script python did not work anymore with the softbodie in blender 2.46.  Only one line needs to be removed.
2008-07-28 10:13:56 +00:00
8162215f2a Bugfix:
Bone-locking should only be set if the bone (and not its parent/children) are selected. Transposition error from the patch (I had to manually apply as there were some oddities about the patch file).
2008-07-28 04:08:46 +00:00
edf557cb1c * Fix for Aligorith's fix for my mistaken uninitialised variable in outliner.c - it was never needed in the first place. 2008-07-28 00:21:34 +00:00
1a370eaafc Fix crash on baking pointcache reported by nudel 2008-07-27 16:27:59 +00:00
Maxime Curioni
362e4f763f soc-2008-mxcurioni: implemented and integrated all 21 original stroke shaders. 2008-07-27 13:40:33 +00:00
f4def51cd3 #17309: Copy/pasting bone names (without editing text) doesn't update bone/pose names
The pasting code for text-buttons (when hovering over the button), was incorrectly using the drawstr (i.e. the string that is displayed in the text-button, and includes the 'name' of the button) as the old value. This meant that the renaming code could not correctly detect matches to rename.
2008-07-27 12:48:46 +00:00
7762ef9574 Almost done with 'Phase 1': Fixed depsgraph update of modifier, fixed material index deletion, fixed face flag deletion (using face0 now as old fluid code) 2008-07-27 12:28:34 +00:00
b2be0a181f Bugfix #17334:
This bug-report revealed a critical error made in the menus for Constraints Owner/Target spaces. It seems that the wrong values have been used for 'pose space' and 'local with parent' space. This has now been rectified, so that old rigs won't break (just that the labels will be a bit different).
2008-07-27 11:41:39 +00:00
Maxime Curioni
2b2df54aef soc-2008-mxcurioni: ported ALL 1D unary functions, representing 32 new classes. 2008-07-27 11:27:59 +00:00
5ae7824a47 svn merge -r 15649:15800 https://svn.blender.org/svnroot/bf-blender/trunk/blender + forgot something in last commit --> e) Last simulated Frame will stay and not turn into cube/domain after last valid simulated frame. f) Fixed loading of old fluidsims (1 parameter was wrong) 2008-07-27 10:46:46 +00:00
d4656ae5a1 Phase 1: a) Fluidsim is a modifier now which allows apply'ing now. b) Fluid control start time/end time works now. c) Negative attraction forces are available now. d) Fluidsim IPOs are now hidden if they don't apply to the selected fluid-type (less confusion for the user). 2008-07-27 10:38:30 +00:00
Maxime Curioni
0cc6f9db3d soc-2008-mxcurioni: ported ALL 0D unary functions, representing 34 new classes. I will do the same for the 1D unary functions. 2008-07-27 06:57:46 +00:00
05ec9021e4 Outliner.c:
Fixed some warnings about 'ob' being used uninitialsed. In some places that was definitely the case!
2008-07-27 05:20:35 +00:00
6035b3e0c7 Grease-Pencil:
* UI - added delete button for hidden layers
* Renamed the two hardcoded defines added for testing distances to their more formal nomenclature.
2008-07-27 04:39:55 +00:00
b24485ab92 Patch #17336: Lock bones in edit mode
Submitted by: Lorenzo Pierfederici (lento) 

This patch adds the ability to lock transformation on bones in edit mode, to protect them from accidental editing.

Bones can be locked from the editing buttons, the transform property panel, the specials popup menu or the python api.
2008-07-27 04:19:56 +00:00
Maxime Curioni
995fdd9fcd soc-2008-mxcurioni: implemented and tested unary predicates. The good news is that My approach seems to works (even though it is not fully testable as it needs Freestyle to be running). I will now port the 80 predicate subclasses left.
In this commit, UnaryPredicate0DDouble and its subclasses DensityF0D and LocalAverageDepthF0D are implemented and integrated in the API.
2008-07-27 03:40:37 +00:00
b4fc80eb3d == Pose Mode - Copy Menu (Ctrl C) ==
This now works even when there is a proxy-protected bone selected with a few differences.
* The Transform Locks, IK-Flags, and Custom Bone Shape settings are unavailable, as they would be reset by the proxy protection anyway

Also, the Copy Constraints options have been altered so that they do NOT free all existing constraints on the target bones before copying.
* Constraints are now appended to the end of the constraint stacks, with those added to bones belonging on proxy protected layers getting tagged as 'local' constraints.
* This is more useful for riggers than the previous behaviour (which was quite nasty too).
2008-07-27 03:15:17 +00:00
01a6d44b07 Undo Fix: Down arrow on last line sent cursor to end (right) but undo sent it up. Similar for up arrow on first line. Undo was then off by a line. 2008-07-26 22:37:05 +00:00
6872ff71d5 Oops, forgot to reset counters for each line when calculating wrap. 2008-07-26 22:25:26 +00:00
8a295553f7 == Python scriptlinks ==
Render/postrender events were missing from bg rendering (and also from rendering called inside scripts). Found this because of bug #17389, the code to prevent race conditions with pynodes is currently inside BPY_do_all_scripts (that runs scriptlinks) and so was not being called in bg mode or rendering via scripts.

http://projects.blender.org/tracker/?func=detail&atid=125&aid=17389&group_id=9
2008-07-26 22:00:26 +00:00
Maxime Curioni
0c64c49d2f soc-2008-mxcurioni: added (but did not test) ViewMap and Noise classes. Updated ViewShape class accordingly 2008-07-26 21:47:39 +00:00
Maxime Curioni
5718639a79 soc-2008-mxcurioni: implemented (but did not test) ChainPredicateIterator and ChainSilhouetteIterator 2008-07-26 20:05:55 +00:00
6531d859ba TextPlugin update: Converted try-except blocks to use try-catch-else to allow better error tracking. Commented the descriptor classes and improved variable support for basic types (string, list, etc.) 2008-07-26 20:02:10 +00:00
Maxime Curioni
13364bf208 soc-2008-mxcurioni: completed implementing ViewEdgeIterator and ChainingIterator. Updated UnaryPredicate{0D,1D} 2008-07-26 19:32:47 +00:00
9f19d88a5d Word-wrap initial commit. Added button to header and updated draw code for text and cursor. Simple typing/deleting works fine. Other events (selections, clicking) behave as if text has not been wrapped and need work. 2008-07-26 18:38:59 +00:00
70ce017777 == Grease Pencil - Drawing (User Action not Display) Accuracy ==
This commit attempts to fix some of the problems with the accuracy of strokes recorded.

I've disabled the post-draw smoothing of strokes as it deviated from the source stroke too much. This was introduced to try to eliminate the effects of fine 'jitter' (which is especially noticable when using optical mice + fast computer). 

Now, I've introduced two thresholds which determine the 'minimum' distances that the mouse needs to have moved from the previous mouse-coordinates recorded, to be recorded. These are currently hardcoded, but may be exposed in the UI if there is significant need to do so.
- The first is for the distance that the mouse must have moved on both axes to be considered.
- The second is for the 'pythagorean' distance that needs to have been travelled by the mouse.
2008-07-26 12:54:03 +00:00
c4116a7f8d BGE patch: support runtime duplication of groups. Adding an object with Dupligroup option set will cause the group to be instantiated. No special actuator is needed for this feature, just put dupligroup objects in inactive layers and add them dynamically 2008-07-26 11:00:21 +00:00
4a8aa06a14 Merge from trunk
revs. 15635:15771
2008-07-26 10:45:11 +00:00
9f803439c7 == Sequencer ==
Fixes: [#17347] Scaling problems when "Use Translate" is enabled for image strip
2008-07-26 06:43:36 +00:00
8234abe2b5 == Sequencer ==
since clear_last_seq replaces set_last_seq in kernel,
removed unneeded bad_level_call.
2008-07-26 06:19:50 +00:00
Maxime Curioni
b216e4d12d soc-2008-mxcurioni: implemented (but did not test) the following classes: Material, Chain, FEdgeSharp, FEdgeSmooth. All Interface1D classes have now been fully implemented. 2008-07-26 02:33:21 +00:00
d979ebe11f Two fixes:
* For constraint mesh-targets, the check for whether the target mesh was in EditMode didn't check to see if the target mesh was the mesh in EditMode. 
Thanks jaguarandi for catching that!

* Bumped up size of buffer for grease-pencil drawing after seeing a program written in 1989 that had a 100 times larger buffer
2008-07-26 00:43:29 +00:00
4c6e0d49c8 Text plug-ins should only be invoked when syntax highlight is enabled (since they only update when it is set). We don't want things popping up when we're just writing text. 2008-07-26 00:25:03 +00:00
9e1ca2c1be Fixed simple deform strech/squash function 2008-07-25 23:52:16 +00:00
1b3cf253ed rolling back 'bad' wind and force scaling compared to particles ..
because i have no solution on backward compatibility  
keeping bug fix
-wind and force did not work if aero or edge collision was activated.
2008-07-25 22:58:22 +00:00
f6b85a55fa == PyNodes ==
Early Ehlinger reported a deadlock when a script tells Blender to render an animation and there are pynodes. While investigating I saw related crashes in bg (blender -b) mode, still not fixed. This commit tries to fix the problem for interactive mode, then. What it does is releasing the lock before rendering and relocking after that, like theeth suggests in the bug report:

http://projects.blender.org/tracker/?func=detail&atid=125&aid=17389&group_id=9
2008-07-25 22:30:03 +00:00
Maxime Curioni
51f9082c96 soc-2008-mxcurioni: added (but did not test) NonTVertex and TVertex classes. All Interface0D structures have been implemented 2008-07-25 21:56:06 +00:00
229a5809bb added exception messages to game engine matrix and vector conversions. also removed own unneeded defines in arithb.c 2008-07-25 21:14:23 +00:00
d7fecc9e96 Fluid control: WIP commit before weekend, not working is crashing on the first 3 frames 2008-07-25 18:57:16 +00:00
1537e75cba Converted shrinkwrap to a DeformOnly modifier
*the options "remove faces", "merge" points were removed
*made shrinkwrap work with CVs (curves and nurbs surfaces)
*cleanup shrinkwrap code.. (removed bruteforces and raytree methods)
2008-07-25 18:48:24 +00:00
a7f951f25e BGE patch: approve patch #17312: Multiple material IPOs per mesh in BGE. 2008-07-25 13:45:57 +00:00
ab44742cf3 BGE bug fix: approve patch #17297: Track To Actuator bug fix 2008-07-25 10:52:10 +00:00
1634b7c460 Documentation panel improved to scroll and have better word-wrapping. 2008-07-25 08:06:30 +00:00
Nathan Letwory
8df67dae36 * make sure blenderplayer links again 2008-07-25 07:56:07 +00:00
325b1666d4 Grease Pencil - Backend work:
Just preparation work for an eraser tool (as well as the code of a failed attempt at an implementation).
2008-07-25 07:11:08 +00:00
Maxime Curioni
dc385c59ea soc-2008-mxcurioni: fully implemented (but did not test) Curve class. 2008-07-25 02:18:02 +00:00
Maxime Curioni
c0f567e757 soc-2008-mxcurioni: fully implemented (but did not test) ViewEdge class. Modified functions accross API taking input boolean values. 2008-07-25 01:38:19 +00:00
846ae7a187 * Fix for bug #9450 'Problems with Extended Material node with AmbCol socket'
It turns out the material AmbCol property was never working properly, or even supported in the renderer, so I've removed it. Also included is a fix to make the 'Amb' input work properly too.
2008-07-25 01:17:37 +00:00
Maxime Curioni
d8d9839ab3 soc-2008-mxcurioni: Added iterator capability to FEdge and Stroke. Recoded parts of ViewVertex, SVertex and Convert to support these changes. 2008-07-25 00:18:10 +00:00
Maxime Curioni
fc97e91a3e soc-2008-mxcurioni: found and fixed all potential issues iterating over internal view-map data. The internal namespaces (ViewEdgeInternal, ViewVertexInternal, CurveInternal, StrokeInternal...) should NOT be included to prevent redefintion errors. 2008-07-24 21:32:50 +00:00
Maxime Curioni
2860bc5d5b soc-2008-mxcurioni: cleaned up the Convert header file to prevent cyclic or header positioning problems and adapted classes accordingly 2008-07-24 20:39:13 +00:00
71b2bf23e0 Slight code changes to select different limits for simulated annealing (commit now to test on another machine later) 2008-07-24 20:03:25 +00:00
bbd636df13 added note to epydocs explaining the nature of floats in id properties from the python point of view 2008-07-24 19:34:49 +00:00
0118a82379 added support for doubles to the id property code, and made the python code use them by default 2008-07-24 19:22:17 +00:00
d1bdd58797 Axial symmetry stability bug fix.
Axial symmetry tagging was depending on the order of the nodes, so it might tag left side as right and vice versa depending on the order. Stability test ensures the tagging is order independant (what it tags as right and left might not be the real right and left, but at least they are consistant between mesh graph and armature graph, so it doesn't flip limbs)
2008-07-24 19:12:30 +00:00
059b0651de Propagate control bones repositioning (can deal with chains of control bones)
Retargetting IK/FK switcher setups should work ok now (worked on a setup I did, need to test with more)
2008-07-24 14:11:36 +00:00
b93156a686 soft body bug fix own finding
left overs from new particles
-wind and force did not work if aero or edge collision was activated.
-force field had flipped sign compared to particles
tsk who thinks a attractive force should negative sign? well... i am passionless with that.
-adapted effect of wind and fields on softbodies such that softbody "particles" and particle "particles" behave consistently
note! 
effect of wind is 1/25 compared to before   
other forces 1/10
2008-07-24 12:27:31 +00:00
f9dc77c1c8 == Grease Pencil - More Tweaks (I) ==
New Stuff:
* Alt-XKEY / Alt-DelKey will now activate the Grease Pencil "Erase" menu. This will only show up when it's relevant (i.e. when there exists Grease Pencil data). It should make it faster to quickly delete the last stroke made. This hotkey has been added to the tooltips of the relevant buttons.
* Finished off colouring of 'active' layers panel so that they are now easily identify-able. This could also be done for Constraints, but the 'active' one isn't that important there.

Bugfixes:
* Fixed bug with drawing gp-data sources in the Action Editor, which resulted in missing icons.
* Fixed buttons in Grease Pencil panel. My hasty attempt last night at making the Action Editor to refresh was causing problems.
* Added a (hopefully temporary) button that will be used to prevent drawing from occurring with Shift-LMB. This is useful when trying to select stuff sometimes, with LMB as select-button, especially when selecting a bunch of closely spaced bones might be interpreted as a new stroke.
2008-07-24 09:23:13 +00:00
Maxime Curioni
a0359c3750 soc-2008-mxcurioni: added (without testing) the following classes: BBox, SShape, ViewShape. Also corrected a few typos (Get#->get#). 2008-07-24 08:29:48 +00:00
955ffb4abf * Added the ability to toggle visibility/renderability for bones in edit mode or pose mode, in the outliner 2008-07-24 06:21:33 +00:00
c1e85535cc * Added the ability to toggle visibility/renderability for modifiers, from the outliner 2008-07-24 06:04:03 +00:00
Maxime Curioni
dd899939da soc-2008-mxcurioni: Added first batch of Iterators: AdjacencyIterator, Interface0DIterator, CurvePointIterator, StrokeVertexIterator, SVertexIterator, orientedViewEdgeIterator. 2008-07-24 04:48:34 +00:00
004197f720 * A bit more precision in the bevel mod 'width' field 2008-07-24 02:09:44 +00:00
5eb14d70b9 BGE patch: Add PyDoc for new logic bricks, set exception message on Py error, remove args on Py functions that don't take any to save CPU time 2008-07-23 21:37:37 +00:00
d2013570a0 Refactor: Renamed text tool methods (suggestions and docs) for clarity and consistency. 2008-07-23 21:28:48 +00:00
3b70337f7f Improvements to text find (and replace):
- Added GUI panel
 - Selected text is copied to "find" field
 - Option to search "all texts"
 - Option to replace text
 - Alt+F finds, Ctrl+Alt+F finds again (without UI)
 - Alt+H replaces (UI), Ctrl+Alt+H replaces again (and undo works)
 - Fixed: Find didn't push undos so cursor position was wrong
2008-07-23 19:35:13 +00:00
16ebff308e time_t isn't supported in SDNA so we'll use double instead. 56bit precision is plenty for storing seconds (for a billion years at least) 2008-07-23 18:19:56 +00:00
dcbe9ade7a Added NodeUpdateGS so GameObject Python api alignAxisToVect function,
Otherwise the rotation isn't applied.
2008-07-23 15:45:23 +00:00
6b4b03317d Bugfix: Deleting backward selected text was getting stuck on redo.
Selections were not correctly preserved through undo/redo operations causing unexpected behaviour.
2008-07-23 12:59:05 +00:00
8a1dbea363 == Grease Pencil - UI Improvements ==
Based on user feedback, I've made some changes to the Grease Pencil UI (most notably in 'Time Editing' facilities). 
* 'Edit Timing' button gone
* Pin button and '<Grease Pencil Data' string gone from Action Editor
* Action Editor in 'Grease Pencil' mode now displays all grease-pencil datablocks for current screen. 
* AE: GP-Datablocks are drawn like 'groups', with an expand/collapse button to show/hide layers. Its name shows the type of space it comes from, and shows indicative status info (i.e. for 3d-view, it shows view-angle)
* Added refresh calls for action editor after editing relevant data.

I haven't tested all tools yet, but most should be stable. 

Also, I've removed some unnecessary buttons, and added a few tooltips. There's also some experimental code to try to get clearer indication of 'active' layer.
2008-07-23 12:27:08 +00:00
Maxime Curioni
d1b82d1f15 soc-2008-mxcurioni: added Iterator class, base class for all iterators in Freestyle (on the C++ side). Created the equivalent in Python BPy_Iterator with the simple interface:
- getExactTypeName()
- increment()
- decrement()
- isBegin()
- isEnd()

Contrary to previously stated, I am reverting back to implementing iterators in the (Python) API, for different reasons:
- it will make testing quicker to achieve, as I won't have to recode a big chunk of the original Python files
- it will be a base for API refactoring
- it won't prevent the use a list-based approach later (it is simple to get it from the Iterator)
2008-07-23 10:19:08 +00:00
Maxime Curioni
a9789d90ae soc-2008-mxcurioni: renamed all Freestyle API related files with 'BPy_' prefix to avoid library name collision.
Included MediumType's initialization at proper time to avoid Blender's crash.
2008-07-23 07:56:08 +00:00
ab722cf7b1 == Sequencer ==
Fixes: [#17315] Sequencer: after undo there's no active object
closes: [#17357] fix for bug #17315 - Sequencer: after undo there's no active object
(kiemdoder: thanks for the patch, had to do it in a little bit different way,
since sort_seq will kill your sort order idea...)
2008-07-23 07:11:23 +00:00
Maxime Curioni
0c494442d3 soc-2008-mxcurioni: merged changes to revision 15705 2008-07-23 06:02:18 +00:00
Maxime Curioni
0c3f7c2b7e soc-2008-mxcurioni: implemented (without testing) StrokeShader, Stroke and MediumType (used by Stroke to define medium types) classes. The Stroke class is missing the InsertVertex method.
Before porting other classes, I'll resolve the List (Python) <=> Iterator (C++) correspondence problem by implementing a general class appropriately suited for the task.
2008-07-23 05:54:34 +00:00
1e7523ea44 Updated some out of date documentation of Object Ipo curve names 2008-07-23 02:31:56 +00:00
a18c723d55 BGE patch: Add min/max parameters to orientation constraint actuator
The min/max parameters define a minimum/maximum angle
that the object axis can have with the reference 
direction without being constrainted. The angle is 
expressed in degree and is limited to 0-180 range. 
The min/max parameters define a conical free zone
around the reference direction.

If the object axis is outside that free zone, the
actuator will tend to put it back using as a temporary
reference direction the vector that is exactly at
min or max degree of the reference direction 
(depending if the axis angle is below the minimum 
or above the maximum) and is located in the plane 
formed by the axis and the reference direction.

With a low damping value, this is equivalent to 
clamping the axis orientation within min/max degree
of the reference direction.

Backward compatibility corresponds to the absence
of free zone: min = max = 0.
2008-07-22 23:05:06 +00:00
21bf5167ed Update MSVC project files 2008-07-22 18:11:32 +00:00
deccefc029 First draft for control bones repositioning.
All bones marked as no deform are repositioned after the retarget based on their "linked" bone (linked bone is constraint owner if control bone is a target, parent bone if not).

Arithb:
 Function to make a quat between two normalized vectors
2008-07-22 17:44:06 +00:00
1abe753bf0 BGE patch: update KX_GameObject::getChildren() to use CListValue instead of python list (allows name search keep refcount consistent) 2008-07-22 16:44:35 +00:00
6d0e840648 Bug fix for the bug fix. Wasn't closing the clipboard before returning. Thanks b333rt for catching this. 2008-07-22 15:31:22 +00:00
20af6c61e8 Bugfix: Pasting non-text data (or trying to retrieve non-text data from the clipboard) crashed blender on Windows. 2008-07-22 14:56:02 +00:00
aec6b78ded svn merge -r 15590:15688 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-07-22 12:02:57 +00:00
06f67dd531 *BVHTreeFromMesh api changed.. it now stores all information like defaults callbacks to raycast and nearest surface (just to make it easier to use)
*Fixed button size of "Above surface"
2008-07-22 11:50:50 +00:00
32d10bca2b == Grease Pencil ==
Grease Pencil is a tool which allows you to draw freehand in some views, allowing you to annotate/scribble over the contents of that view in either 2d or 3d. This facilitates many easier communication and planning abilities.

To use, simply enable it from the View menu (choose 'Grease Pencil...' and click 'Use Grease Pencil'). Then, click+drag using the left-mouse button and the shift-key held to draw a stroke.

For more information, check the following page on the wiki:
http://wiki.blender.org/index.php/User:Aligorith/247_Grease_Pencil
2008-07-22 09:53:25 +00:00
Maxime Curioni
48732bf2ab soc-2008-mxcurioni: filled and tested StrokeVertex class 2008-07-22 08:15:21 +00:00
Maxime Curioni
2c29af6a29 soc-2008-mxcurioni: corrected StrokeAttribute, verified with test case.
I realized today that it will not be possible to implement getter/setter functionality easily for our Freestyle API. The reason is that Python does not support function overloading as-is. It is possible to 'fake' overloading by taking a general argument object and count the number of arguments in the object (rgbTuple_setCol in Blender's API is a good example of how to go about it). 

For the time being, we'll get around that problem. The tangible effect of that constraint is that all API setter functions return a 'None' PyObject, instead of returning an integer status code. It is important to note that this problem is due to Freestyle's API being C++ in nature. Fortunately, this shouldn't really impact the usage of the API.

If the Blender Python group wants me to correct that, I'll be able to do it. It is just going to take me quite some time correcting it, writing support functions for methods having different types of arguments.
2008-07-22 00:27:40 +00:00
3c8b695f72 Fixed a bug relative to editmode..
now its calling CDDM_calc_normals when receiving a mesh to deform,
since in edit mode the mesh doenst has normals calculated
2008-07-21 22:36:05 +00:00
Maxime Curioni
7426a3e35b Added StrokeAttribute class. Beginning of StrokeVertex.
IMPORTANT: The setters functions' names were normalized due to constant confusion regarding capitalization. All the function names start with set... instead of Set.... This convention was changed all throughout Freestyle. To use Freestyle as an external renderer, the SWIG library MUST be regenerated.
2008-07-21 21:24:37 +00:00
Ken Hughes
4c086bf4ae Python API
----------

Particle patch from Cédric Paille: bugfixes and child-particles export improvements for .getLoc(), part.getRot() part.getSize(), part.getAge() methods.

Also fix a bug with part.randemission getter (was using PART_BOIDS_2D instead of PART_TRAND), plus typos and duplications in API documentation.
2008-07-21 20:42:11 +00:00
07b8c7e887 Updated the textplugin_outliner.py plug-in to use the new Draw.PupTreeMenu and updated this menu to support titles. 2008-07-21 19:11:38 +00:00
4c76c57a77 Made shrinkwrap modifier work when target or cutPlane are in editmode. 2008-07-21 18:12:02 +00:00
78ce90b752 allow to write to libraries that are indirectly linked 2008-07-21 17:05:59 +00:00
434f2172f6 Removed requirement for suggestions to be pre-sorted. Allowed lists of strings to be suggested without having to specify their type. Specifying a prefix when suggesting is now also optional. 2008-07-21 16:40:32 +00:00
9bf0bfcae7 Fix for crash with fc and quality < 5 (reported by Nudel) 2008-07-21 13:47:42 +00:00
4ae4ecd3ce BGE patch: Optimization of bullet adaptation layer - part 1.
First batch of optimizaton of the bullet adaptation layer in the BGE.
- remove circular motion state update.
- optimization of physic adaptation layer for bullet: bypass
  unecessary conversion of rotation matrix to quaternion and back.
- remove double updates during object replication.
2008-07-21 12:37:27 +00:00
5435d7c3ea Oops, typo in rev. 15664 caused error 2008-07-21 11:21:49 +00:00
fab7270e40 Script template added for text plug-ins 2008-07-21 10:07:03 +00:00
2647bed77d Enabled fc for testing 2008-07-21 07:10:10 +00:00
6352cd509e BPyTextPlugin now has descriptors for variables, functions and classes (and their variables/functions). Each descriptor also holds the line number of the definition allowing a simple outliner to be written.
Text.setCursorPos(row, col) now pops the text into view if it is in the active window space. The outliner uses this to jump to any definition in a script; it is invoked with Ctrl+T.
2008-07-21 00:38:42 +00:00
8f17a66036 BGE 2dFilters some extra fixes 2008-07-20 23:34:17 +00:00
5350d5eb2c BGE Bug Fix:#17349, fixes some problems about 2d-filters 2008-07-20 23:03:01 +00:00
9f53999181 BGE patch: constraint orientation actuator did not work when damping=0. 2008-07-20 21:09:56 +00:00
e0fc591697 Fix for crash in collisions (introduced *after* 2.46 with my collision recode) 2008-07-20 21:05:48 +00:00
def3150098 [#17356]: Reactor particles makes blender crash 2008-07-20 18:07:02 +00:00
e95e2fb43e GameObject functions getChildren() and getChildrenRecursive() 2008-07-20 17:18:46 +00:00
433c43932b Bugfix #16662
Curve modifier on lattice suffered drawing updates, only when the system
was not animated though, missed depsgraph calls then.

Solved it by forcing lattice to always return displist for its vertices,
that's same as for how mesh/curve works now.
2008-07-20 16:06:40 +00:00
d725e5f78e BGE bug fix (for 2.47): setParent() fix, third part: set mass to 0 when parenting. Allow loc/scale/orientation change on child object with physic controller. 2008-07-20 15:40:03 +00:00
89f2a63ecd Bugfix #8182
Specular render in Blender still had terminator problems... only the diffuse
part got "phong correction" applied. I didn't fix this before to not change
rendering results just before the release. Now there's time I hope?

Render results should only differ minimal, and only visible for low spec
hardness values (like 1 or 2)
2008-07-20 10:09:19 +00:00
037f1188e6 svn merge -r 15529:15649 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-07-20 08:52:48 +00:00
Maxime Curioni
ab722884d3 soc-2008-mxcurioni: updated support for Nature class. 2008-07-20 05:01:29 +00:00
a8785893c5 Added functions so python can change library paths.
* bpy.libraries.paths() -> list of library paths.
* bpy.libraries.replace(fromPath, toPath)
2008-07-19 15:44:00 +00:00
0703d9aad1 Following the same optimization as bvh raycast:
*Made nearest surface also use "quad" bvh tree (instead of splitting quads in 2 bvh nodes).
 Again that leaded to improvements in build and query time.

*BLI_bvhtree_find_nearest api is now following the same concept as BLI_bvhtree_ray_cast

removed code relative to bvhtree_from_mesh_tris.
2008-07-19 15:22:38 +00:00
37c8f08f28 syntax change so GCC 4.3 will build 2008-07-19 13:04:55 +00:00
7e990de294 BGE bug fix (good for 2.47): remove static-static collision messages on the console since previous SetParent fix. The physical object is set to static+ghost while the object is parented. This behavior will be made optional in a future release. The DisableDynamics actuator will also make the object static except that the ghost/non-ghost flag is preserved. 2008-07-19 10:27:52 +00:00
9ed079bf5c BGE patch: Relink actuators with target within group when duplicating group; generalize protection against object deletion for all actuators that point to objects.
Certain actuators hold a pointer to an objects: Property,
SceneCamera, AddObject, Camera, Parent, TractTo. When a
group is duplicated, the actuators that point to objects
within the group will be relinked to point to the
replicated objects and not to the original objects.
This helps to setup self-contained group with a camera
following a character for example.
This feature also works when adding a single object
(and all its children) with the AddObject actuator.

The second part of the patch extends the protection
against object deletion to all the actuators of the above
list (previously, only the TrackTo, AddObject and
Property actuators were protected). In case the target
object of these actuators is deleted, the BGE won't
crash.
2008-07-19 07:45:19 +00:00
f042a468fd Merged 15170:15635 from trunk (no conflicts or even merges) 2008-07-18 23:35:34 +00:00
123407e0b4 Added a documentation panel with primitive word-wrap functionality. It can be displayed by Text.showDoc(string) in python and has a text-plugin script for function docs which may be invoked with Ctrl+I inside its params list. Eg. type "dir(" <Ctrl+I> 2008-07-18 23:12:19 +00:00
59a2b50171 *Added "kept" mesh above surface option on shrinkwrap to nearest surface
changed a few code relative to project over normal mode (to try to kept code generic and more independent of modifier itself)
2008-07-18 22:24:20 +00:00
Maxime Curioni
16d7d12123 soc-2008-mxcurioni: Added IntegrationType and Nature classes, used to store constants used throughout Freestyle 2008-07-18 20:31:40 +00:00
5e2ee19187 BGE patch: support for partial hierarchy in dupligroup instantiation; removal of links that point to inactive objects during group instantiation.
This situation corresponds to a group containing only a portion
of a parent hierarchy (the Apricot team needed that to avoid
logic duplication). The BGE will instantiate only the
children that are in the group so that it follows the 3D view
more closely.
As a result, the logic links to the objects in the portion of the
hierarchy that was not replicated will point to inactive objects
(if the groups are stored in inactive layers as they should be). 
To keep the logic system consistent, these links are automatically
removed.
This last part of the patch is a general fix that could go in
2.47 but as this situation does not normally occurs in pre-2.47
games, it is not needed.
2008-07-18 19:56:56 +00:00
25de501805 Exponential cooling off and progressive minimization for simulated annealing 2008-07-18 19:09:41 +00:00
c0dfe80e0d Fix misceleanous errors/tweaks in cost calculations
- Angle cost could easily balloon up, don't use relative difference
- fix error with ends (wrong indexes)
- add missing out of bound preventions
2008-07-18 17:57:34 +00:00
a397b4b82f BGE bug fix (good for 2.47): SetParent actuator did not work on dynamic objects. Dynamics will now be disabled automatically and the object will be set ghost for the duration of the parenting; this is to avoid static interaction with the parent object. The dynamic state is restored when the parenting is removed with RemoveParent actuator. This fix also applies to setParent() and removeParent() python functions. 2008-07-18 14:40:24 +00:00
6786c517af own error, recent commit that tried to keep an active face could crash when deleting faces. 2008-07-18 13:05:15 +00:00
c216c980d3 bugfix
the aspect of a block could become negative and default when scaling icons.
this is caused by the using viewRedrawForce (transforming a mesh) and drawing icons in the image panel.
must look into why bwin_getsinglematrix can give a negative value, probably because the opengl state is set incorrect.

This is still not correct because the aspect will be wrong. but at least it wont crash.
2008-07-18 13:04:15 +00:00
b205cf34b4 All parsing is now done in one sweep and cached to allow details to be obtained without re-parsing. A text can be manually parsed with parse_text(text) which also updates the cache. 2008-07-18 11:00:34 +00:00
Maxime Curioni
21674d2db2 soc-2008-mxcurioni: canvas for UnaryFunction0D, UnaryFunction1D, UnaryPredicate0D, UnaryPredicate1D.
UnaryFunction0D and UnaryFunction1D implementations are going to be really challenging due to the changes in the infrastructure: UnaryFunction0D<T> and UnaryFunction0D<T> are templates and must be determined for compile-time. The easiest solution is to support each type individually; unfortunately, it removes the benefit of using an interface. To find a middle ground, a general unary function Python object type was created for 0D and 1D. In both cases, the types have a void* pointer keeping the address of the current unary function type. I am not sure yet if it will work.

Interface0DIterator being removed by a list type, the t() and u() coordinate functions will to be transferred somehow, probably directly at the Interface0D level.
2008-07-18 04:59:07 +00:00
Maxime Curioni
d3973dac71 soc-2008-mxcurioni: FEdge class added. Modifed converting functions to passing-by-reference format. Improved the type checking for FEdge and CurvePoint. Modified FEdge C++ class to test for null vertices. Updated previous classes to support FEdge.
So far, whenever a Python object is created from its corresponding C++ object, the input object reference is copied into a new object. Due to Freestyle's functions (especially regarding the way it is iterated), it is currently impossible to deal with a pointer-based Python object. It is not a real drawback, just an aspect to keep in mind.
2008-07-18 02:55:23 +00:00
1b46522ec4 Max cost for collapsed bones 2008-07-17 20:46:12 +00:00
98d85c3047 Solve a crasher bug in the brute force solver 2008-07-17 19:19:43 +00:00
426451a44d More levels for multi resolution (smoother progression between filtering values). Also different progression for internal edges filtering than external edges (small internal and less important than small external). 2008-07-17 17:33:45 +00:00
Ken Hughes
dcfcc41901 Change message printed by sceneRender.enableCropping() to be more descriptive, and note the method as deprecated in the python docs. 2008-07-17 17:30:32 +00:00
439e474e4e BGE patch: use the Blender convention to duplicate groups in the BGE so that the objects will be created with the location and orientation as in Blender. Note that the BGE handles scaling in a parent tree differently than Blender. To avoid discrepencies between the 3D view and the BGE, use only isotropic scaling on all your objects except the leaf objects (i.e. without children) that can have anisotropic scaling 2008-07-17 15:33:27 +00:00
5848fee125 BGE bug fix (good for 2.47): fix logic reconnection after replication. The old method was matching the bricks by name assuming they are unique but it is not always the case, especially with the new dupligroup feature. The new method matches the bricks by objects and position. 2008-07-17 12:29:42 +00:00
Maxime Curioni
e4748940c0 soc-2008-mxcurioni: SWIG removal - completed SVertex and CurvePoint classes migration. Stabilized a lot of the code for C++ -> Python conversion. Added the correct rich comparison operator and tested it. Corrected 'dupplicate' typo and changde to __copy__ for Python API.
From now on, when a set should be output (PySet_Type), it is given as a list (PyList_Type). The reason is that it doesn't really matter what we bring back to the Python interpreter. The set is guaranteed in memory on the C++ side.

For the CurvePoint class, the userdata variable is not yet ported (and will probably available as a list or a dictionary). The CurvePoint implementation works except for the initialization from other CurvePoints: somehow, the inner variables don't seem to be correctly handled. I do not know if it is a bug in Freestyle or if the CurvePoint object's state is correct for my test case. CurvePoint needs more testing.
2008-07-17 06:35:30 +00:00
dbfc5f6b71 BGE patch: fix mesh deformation errors with duplicated objects sharing the same mesh in case of 1) armature+multiple material 2) shape drivers 2008-07-16 21:24:54 +00:00
7ef48296fc Bugfix: particles with deflection based on size could pass through
objects due to a broken SweepingSphereIntersectsTriangleUV. This
merges the code from the shrinkwrap branch by André Pinto, thanks!
2008-07-16 13:47:03 +00:00
062643eefd Fixed error when scripts were run without a visible Text to work on. 2008-07-16 12:56:23 +00:00
3ae64f67e1 * change active face behavior so that entering editmode will assign the first face as active when none is set. UnSetting the active face will also use the first face as active.
* missing countall when selecting linked
2008-07-16 11:48:55 +00:00
cc89221a24 Previously relying on import to run scripts didn't work every time and was not the right way to do it. Also fixed a problem with 'import *' not working and added the sys.modules list to the import suggestion list with a timed update. 2008-07-16 10:33:48 +00:00
3b8ed8910a Bug Fix #17337, now atmosphere works correctly with FSA enabled 2008-07-16 08:10:23 +00:00
8d94bfec1b Last commit fixed the file contents.. but some svn props were missing.
So I fixed the problem with merges instead of copying files over.
Also trunk/blender/release/scripts/scripttemplate_ipo_gen.py from revision 14530 was missing. (that was fixed)

svn merge -r 15590:15551 https://svn.blender.org/svnroot/bf-blender/branches/soc-2008-jaguarandi (revert changes to the point where the merge was incorrect)
svn merge -r 15552:15572 https://svn.blender.org/svnroot/bf-blender/branches/soc-2008-jaguarandi (apply branch modifications)
svn merge -r 15392:15590 https://svn.blender.org/svnroot/bf-blender/trunk/blender (merge from trunk)
2008-07-15 21:08:39 +00:00
db5a83d083 More merging goodness
fix adjacency list inline instead of having to rebuild fully
	reweight joined graphs properly
2008-07-15 21:07:13 +00:00
7afacb6ea8 BGE patch: DUPLIGROUP option supported in BGE.
Blender duplicates groups in the 3D view at the location of objects having the DUPLIGROUP option set. This feature is now supported in the BGE: the groups will be instantiated as in the 3D view when the scene is converted. This is useful to populate a scene with multiple enemies without having to actually duplicate the objects in the blend file.

Notes: * The BGE applies the same criteria to instantiate the group as Blender to display them: if you see the group in the 3D view, it will be instantiated in the BGE.
       * Groups are instantiated as if the object having the DUPLIGROUP option (usually an empty) executed an AddObject actuator on the top objects of the group (objects without parent).
       * As a result, only intra-group parent relationship is supported: the BGE will not instantiate objects that have parents outside the group.
       * Intra-group logic bricks connections are preserved between the duplicated objects, even between the top objects of the group.
       * For best result, the state engine of the objects in the group should be self-contained: logic bricks should only have intra-group connections. Use messages to communicate with state engines outside the group.
       * Nested groups are supported: if one or more objects in the group have the DUPLIGROUP option set, the corresponding groups will be instantiated at the corresponding position and orientation. 
       * Nested groups are instantiated as separate groups, not as one big group.
       * Linked groups are supported as well as groups containing objects from the active layers.
       * There is a difference in the way Blender displays the groups in the 3D view and how BGE instantiates them: Blender does not take into account the parent relationship in the group and displays the objects as if they were all children of the object having the DUPLIGROUP option. That's correct for the top objects of the group but not for the children. Hence the orientation of the children objects may be different in the BGE.
       * An AddGroup actuator will be added in a future release.
2008-07-15 20:05:23 +00:00
08039ef38f Optimization method selectable at runtime
Start multi resolution match from node, not arc (solve problem with Rinky)
various uglyness being cleaned up or factored out
2008-07-15 19:38:48 +00:00
e433719f51 BGE bug fix (good for 2.47): radar and near sensor did not filter correctly the collisioning objects based on ACTOR flag when the parent object was added dynamically. This could result in a very big performance decrease. 2008-07-15 18:57:10 +00:00
4c48b4846e Updated so things compile. (Missing includes needed)
Kent
2008-07-15 18:12:08 +00:00
512eec04aa Made suggestions case-insensitive which also puts _ prefixed items at the bottom. Improvements have also been made to the way the list works, when it should disappear/update/confirm, etc. 2008-07-15 17:03:59 +00:00
9037159d7a Text plugin script updates: Better error handling, variable parsing, token caching for repeat parsing of the same document. Fixed joining of multiline statements and context detection. 2008-07-15 12:55:20 +00:00
afc30d1a33 There was a problem with the last merge :S
Somehow it didnt finished and didnt added some files under the svn control
(found thanks to lguillaume that reported some files were missing)

Last merge fixed and also merged modifications up to revision 15584.

I checked the diff
svn diff --new . --old https://svn.blender.org/svnroot/bf-blender/trunk/blender
And everything seems to be right now
2008-07-15 12:54:57 +00:00
aeb4d0c631 Created a BPy module BPyTextPlugin to centralize functions used across the text plugin scripts. Also created two more scripts to handle imports and member suggestions. 2008-07-15 07:34:46 +00:00
dbb61988fd Any script can now register a unique key combination as part of its bpy header. For a supported space type, the user may press this shortcut to invoke the script.
Space types that are to support shortcuts like this should call BPY_menu_do_shortcut(...) from the event queue read method (See winqreadtextspace in drawtext.c for example)
2008-07-15 07:04:31 +00:00
Maxime Curioni
cc1a6b398d soc-2008-mxcurioni: reimplemented the initialization/allocation for base classes. The Python object type tp_new slot is now set to PyType_GenericNew, instead of the former custom functions. As a note, by default, Python does not set this slot: it is therefore mandatory for the base classes. For children classes, only __init__ is needed.
To make our base classes subclasses, the Py_TPFLAGS_BASETYPE flag was added to the object type tp_flags slot.

Finally, I began to implement CurvePoint, descendant of Interface0D. This commit allowed me to verify that my SWIG replacement method works: interfaces are well taken into account by children. For a test, use the following code:

================================

import Blender
from Blender import Freestyle
from Blender.Freestyle import *

print Interface0D()
print CurvePoint()

================================

The __repr__ method is only implemented in Interface0D:

PyObject * Interface0D___repr__(BPy_Interface0D* self)
{
   return PyString_FromFormat("type: %s - address: %p", self->if0D->getExactTypeName().c_str(), self->if0D );}

and the result is of the form:

type: Interface0D - address: 0x18e5ccc0
type: CurvePoint - address: 0x18e473f0

As you can see, the correct getExactTypeName of the class is called.
2008-07-15 05:33:12 +00:00
22fc20fe62 Fix segfault in the Sequence.
If you enable the Proxy and Custom Dir options and later disable
the Proxy (but not the Custom Dir options), Blender crash every
time that you try select the strip, because the proxy don't exist
anymore.

The solution: only draw the Custom Dir button if the Proxy
option is enable.
2008-07-15 01:23:56 +00:00
Maxime Curioni
96e52b09da soc-2008-mxcurioni: Reimplemented the Freestyle Python API's files to be correctly used as classes and not submodules. Added and integrated object lifecycle functions (__new__, __alloc__, __repr__) for the previous classes: BinaryPredicate0D, BinaryPredicate1D, Id, Interface0D, Interface1D. All of these classes were tested within Blender's Python interpreter with simple test cases and their getter/setters were corrected.
Interface0DIterator was modified to allow BPy_Interface1D to be instantiated: verticesBegin(), verticesEnd(), pointsBegin(float) and pointsEnd(float) are not pure virtual functions anymore. If they are called directly from  BPy_Interface1D (instead of its subclasses), an error message is displayed.
2008-07-15 01:07:19 +00:00
6583edf07d Bugfix:
My recent commit in transform code messed up Auto-IK.
2008-07-14 23:49:17 +00:00
ac6641664e Subgraph joins to non-terminal nodes 2008-07-14 20:30:23 +00:00
657a3676bd First draft of subgraph joining 2008-07-14 19:05:25 +00:00
785123cc5a Improved build time on BLI_kdopbvh
Its now faster than raytree (both on build and query)

Things tryed:
 X=>Y=>Z=>X split (reduces build time.. but increases query time)
 bucket sorts
	(initial sorts for fast usage of bucket take a long time)
	(nth is linear.. so its quite fast already)

Best times archieve with:
 *usage of 4-ary trees.. reduces build time and tree size but didnt decreased query time
 *quads are on the same node instead of splitting in 2 tris..
	(this actually turned on speedup on query time.. since tree size is reduced by a factor of 2)
 *test ray-bb before ray-primitive gives better times on both tris and quads

Notes:
 measures where made projecting a sphere from inside the head of suzanne.
2008-07-14 18:42:53 +00:00
e8e1f27ac1 bugfix
* samples that wernt loaded could crash blender - divide by zero errors from having 0 channels or bits.
* could also corrupt memory when selecting samples with long names. from the sample selector menu.
2008-07-14 17:19:24 +00:00
84ae0fc000 merge with trunk (15330 -> 15566) 2008-07-14 14:09:36 +00:00
d50d175ba1 Win64 fix: disable 1GB restriction for 64bit windows systems, baking fluid with >4GB is verified to work on Vista64. 2008-07-14 12:24:49 +00:00
0c23d0c2ad Bugfix #17327
Small one: changed the string attribute in multilayer exr files to be:

"2.43 and newer"

To indicate that it's about compatibility of the exr file, not the version
Blender saved it in.
2008-07-14 10:26:11 +00:00
0022222b05 Bugfix #17323
Ztransp OSA render did not include z values anymore in pass... this is
not good Z anyway (aliased), but at least it's back now.

Note: for composites using Z values: use FSA for superior results.
2008-07-14 09:37:06 +00:00
38cfe9c1a2 importing the GameLogic module was being done by adding the text "import GameLogic" to the start of all scripts used in the game engine, this meant every error line number was off by 1 (quite annoying). better to do this to the dictionary that the scripts run with. 2008-07-14 00:47:07 +00:00
8a19adeb58 Win64 fix: if you disable enough things in CMakeList.txt blender compiles on win64 now using cmake --> *BUT* it doesn't say anything about if it works with MEM>4GB (that's next thing to explore!) 2008-07-13 18:29:07 +00:00
915baebda6 Get simulated annealing working correctly. Meaning bone arc retargeting is much faster than before.
Still need to do stability tests and analysis (brute force is probably better in some situations).
2008-07-13 18:24:27 +00:00
37ca3d7a39 Fix to let Ghost compile with win64 msvc compiler. 2008-07-13 17:49:12 +00:00
59df4a4b3a Bugfix #14435
"(De)Select faces with material" (edit buttons) should also draw image window
2008-07-13 14:49:07 +00:00
70730c7226 svn merge -r 15392:15551 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-07-13 13:21:01 +00:00
7d6e004153 Adding the Cullface option on normal projection of shrinkwrap when using bvhtrees 2008-07-13 01:49:53 +00:00
751aa3e121 Fixing the fix: Sometimes, Valgrind sees memory leaks where noone is - especially with external used memory managers like in this case (and Python case) 2008-07-12 22:11:26 +00:00
572f1d88d2 BGE bug fix (good for 2.47): automatic detection that target object of AddObject actuator is being deleted to avoid crash (bad game design anyway) 2008-07-12 12:10:27 +00:00
6c444c205a Update MSVC project files 2008-07-12 11:57:21 +00:00
a49c9c458a improvement of 2d-filter custom shader,
some bugfixes,
now you can use depth buffer and luminance buffer without any settings,
also you can use object's properties in a shader
2008-07-12 10:21:37 +00:00
5f15b164c5 Patch #17285: fix for bug #14685: frame counter not always updating while scrubbing
Patch submitted by Roelf De Kock (kiemdoder) 

The parts of the patch affecting the timeline were have not been committed, as there was a better solution.
2008-07-12 06:49:33 +00:00
a4eb0d6c2f Bugfix #17318: PoseLib: Crash while searching for pose typing in letter i then backspace
When searching failed to find any matches, the pointer to a matching pose was cleared. However, it wasn't reset upon clearing the invalid search-string, so a crash occurred.
2008-07-12 06:44:57 +00:00
279c5b65e2 Patch #17310: Fixing urls in main README
Thanks to Dietrich Bollmann (diresu) for the patch
2008-07-12 06:18:06 +00:00
Maxime Curioni
8398730043 soc-2008-mxcurioni: merge with trunk - rev 15540 2008-07-12 05:02:47 +00:00
42d43de25d == Action Editor - NKEY Properties Panel ==
When the NKEY is pressed in the Action Editor while hovering over the keyframes area, a floating properties panel can now be accessed. It shows relevant properties for the active channel, however this is currently only for Action Groups. Action Channel support will come later.

The key benefit of this panel is that it is now possible to edit the colour set used by a group. Also, there is a button for selecting all the channels in that group (which can also be done by simply Ctrl-Shift clicking on any group).
2008-07-12 05:00:37 +00:00
Maxime Curioni
d124d3c5cd soc-2008-mxcurioni: first part of the Freestyle Python implementation. A new Freestyle module is added. The following modules are implemented: BinaryPredicate0D, BinaryPredicate1D, Id, Interface0D, Interface1D. I added a Convert module to help in the creation of Python objects for Freestyle's data structures. I also added a missing file for guarded_alloc needed for compilation on Windows. 2008-07-12 04:02:08 +00:00
1ffdc66791 Fix for bug [#13479] Particle system "corrupts" when changing material colour and used in conjunction with softbodies
- changing particlesystem settings for hair particles cleared & recalculated everything even when hair softbody was baked
2008-07-11 23:47:44 +00:00
21d032e919 Added sphere cast (tought it doenst seems to solve the intersection problem)
Fixed SweepingSphereIntersectsTriangleUV
2008-07-11 19:46:35 +00:00
b369936b11 Fix for several memory leaks in fluidsim (found with Valgrind). 2008-07-11 18:08:25 +00:00
efb2639a26 Memory leak fix (found with Valgrind) 2008-07-11 17:08:45 +00:00
c83e32fc33 svn merge -r 15409:15529 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-07-11 14:44:20 +00:00
3fce5ba59a Memory leak fix: br_find_exe() uses strdup() which uses malloc and therefore the returned string needs free'ing (Found with valgrind). 2008-07-11 14:11:55 +00:00
2e144abfbd Bugfix #17306: Missing refresh call for button in UserPrefs
Autokey settings were missing redraw for Info-window
2008-07-11 00:36:38 +00:00
de1987eba8 First draft for simulated annealing optimization method (disabled because not ok yet) 2008-07-10 21:04:29 +00:00
ccc62d3385 Use tree length as parameter for multi resolution filtering.
This is the begining of the simplification phase (meaning less parameters to mess up users)
2008-07-10 18:48:27 +00:00
8eab9e15d5 Fix for bug #14411: missing preview render redraw for a few lamp buttons. 2008-07-10 18:11:36 +00:00
7971d7c9f3 Fix for bug #14665: stars not working in 3D view. 2008-07-10 16:29:42 +00:00
46493c0af5 Fix for bug #17292: vertex paint blur darkens the colors as you
paint, due to old optimization to use >>8, but this is equivalent
to /256, and it should be /255.
2008-07-10 15:30:35 +00:00
fbc105335f Special multi resolution lookup on first arc, because the lowest node can get filtered out too. 2008-07-10 15:15:47 +00:00
310a37c29c Adding an option for action actuator - "Continue" this means animations always play from where they left off. Continue was the 2.46 operation too, so new functionality is the option to disable.
When using states, an action like kick or throw can often switch out before finishing playing the action, and there was no way to play from the start frame the second time round. (even setting the actions current frame through python doesn't work work)
2008-07-10 14:23:19 +00:00
99fdf27af9 Sync with Apricot Game Engine
=============================

* Clean up and optimizations in skinned/deformed mesh code.
* Compatibility fixes and clean up in the rasterizer.
* Changes related to GLSL shadow buffers which should have no
  effect, to keep the code in sync with apricot.
2008-07-10 12:47:20 +00:00
3d7358539d AutoMerge Keyframes option for Action/NLA editors will now also delete duplicate keyframes if a Duplicate (SHIFT-DKEY) operation is cancelled. 2008-07-10 01:47:51 +00:00
5c82516261 -> Support for Custom Data in bevel modifier
Added Customdata to Bmesh <-> derivedmesh functions
2008-07-10 00:46:19 +00:00
496a9c1a95 Apricot Request:
When changing the active action in the NLA editor with NLA-override off, armatures now have their restpose applied before the new action is evaluated. 

I've commented the code here to make it clearer what is going on.
2008-07-10 00:15:57 +00:00
45ab006e7c Draw node index
Retargetting, go to higher levels no nodes when no match is found
Fix bug in exterme threshold external filtering
2008-07-09 21:07:02 +00:00
686027a75a Multi resolution retargetting. Go back to lowest level on shared nodes. 2008-07-09 19:44:40 +00:00
d674041f2b Add raycast ability for BLI_kdopbvh
small bvh fixes:
*allow to create any tree type >= 2
*save split axis

changed shrinkwrap to perform normal cast with raytree and bvh tree and print both times:

Shrinkwrap (OBCube)24578 over (OBSuzanne)504482
target = raytree_create_from_mesh(calc->target): 1260.000000ms
shrinkwrap_calc_normal_projection_raytree(&calc): 1850.000000ms
tree = bvhtree_from_mesh_tri(calc->target): 3330.000000ms
shrinkwrap_calc_normal_projection(&calc): 3780.000000ms

On general query time is bit smaller on bvh tree..
but the build time of bvh is pretty big.
(build time can be removed from both if a cache system is added)
But I am still trying to see how fast I can make the bvh build
2008-07-09 19:43:09 +00:00
b915ba5e97 [#17298] surface normal direction compensation for objects with negative scale in rendering with radiosity
from Roelf De Kock (kiemdoder) 

Fixes bug [#7969] Mirroring Object Breaks Radiosity Calculations

- copied from the tracker.
The code in this patch detects whether an object has negative scale (test the OB_NEG_SCALE bit in Object.transflag)
and then compensate for the negative scale when the surface normals are calculated for a radiosity render.
2008-07-09 19:15:26 +00:00
4019cae181 Fix external arc merging bug (could mess up node degrees) 2008-07-09 18:36:35 +00:00
12c128ac04 Fixed bug #14510 - wave modifier crash
CDDM_apply_vert_coords needs a CDDerivedMesh, but it was getting a
CCGDerivedMesh from the preceding Subsurf modifier. This fix just makes
a CDDerivedMesh copy of the supplied DerivedMesh rather than using it directly.
2008-07-09 15:54:53 +00:00
732d886e0a bugfix, vector was not checked for zero length before normalizing, closing blender instantly with an assert. 2008-07-09 15:30:15 +00:00
d0d179dce6 Buhh... and now I left in testing print in exr code. 2008-07-09 15:25:34 +00:00
180a7d1f62 Replaced strcasecmp with BLI_strcasecmp, to make msvc happy! 2008-07-09 13:12:58 +00:00
Maxime Curioni
d760119f45 soc-mx-2008: SWIG dependency - wrapper functions extracted from ModuleWrapper.cpp 2008-07-09 08:24:13 +00:00
Maxime Curioni
f7f0077294 soc-2008-mxcurioni: first (blank) file upload for SWIG removal, in source/blender/freestyle/intern/python. The migration will be based on source/blender/freestyle/intern/swig/ModuleWrapper.{cpp,h} 2008-07-08 22:55:00 +00:00
daa853a31f Rename some struct members to reduce confusion
Proper flag clearing for retarget on multi resolution
2008-07-08 19:34:20 +00:00
3bab1eba3a Introduced quality to GUI, not yet tested (WIP commit) 2008-07-08 17:38:33 +00:00
f8afbb4054 Start multi resolution search on first arc and smarter search (match first two levels only).
Now need a way to go back to lower levels at shared nodes.
2008-07-08 16:22:18 +00:00
01e9635ef1 Correct IPOs again, have yet to find a resolution how to hide some unsused IPOs 2008-07-07 21:04:20 +00:00
52219d52dd First draft: Use multiresolution graph for retargetting (enables bypassing small appendages that don't correspond to anything on the armature). 2008-07-07 20:31:53 +00:00
2ad696111e Some channel fixes for fc 2008-07-07 20:28:56 +00:00
f139e1f1b4 Reeb multiresolution filtering, now with more than one level 2008-07-07 17:27:22 +00:00
e409c2463d WIP commit to introduce channels 2008-07-07 14:36:33 +00:00
d3745d70a5 Another addition of time values, yet some things to follow 2008-07-07 09:23:12 +00:00
7bbf88d602 Added 4 gui elements to structs, another 2-3 will follow; Unsolved problems: simulation and control time desync 2008-07-06 21:55:03 +00:00
Maxime Curioni
270184e1b2 soc-2008-mxcurioni: merge-repair with trunk rev 15456 2008-07-06 19:53:32 +00:00
b3303c98b1 Another fluid type 'control' added and introduced to elbeem, still some issues to solve but with 1 change in fluidsim.c it kind of works already (hint for me - disabled for other people so they don't complain) 2008-07-06 18:19:42 +00:00
de286af3f1 Filter according to arc length, not weight different (more logic physical filtering) 2008-07-05 22:01:46 +00:00
Maxime Curioni
eda7cdc81d soc-2008-mxcurioni: merged changes to revision 15441 2008-07-05 13:30:48 +00:00
Maxime Curioni
85611d1045 soc-2008-mxcurioni: render buffer modification 2008-07-05 11:16:03 +00:00
Maxime Curioni
d50fbd6568 soc-2008-mxcurioni: render buffer format 2008-07-05 11:13:57 +00:00
Maxime Curioni
65c9dfe436 soc-2008-mxcurioni: render layer with FBOs -> render buffers, version 2. Still not working. 2008-07-05 08:50:41 +00:00
Maxime Curioni
5200f51a87 soc-2008-mxcurioni: first render layer implementation with frame buffer objects. It does not work yet: I cannot manage to read from the correct buffer yet. 2008-07-05 06:22:15 +00:00
37a017b18a *Added vertex groups on simple deform
*Fixed a few UI things

*Make SimpleDeform and Shrinkwrap to use vertexgroup_get_vertex_weight, a similar function
 "static float vert_weight(MDeformVert *dvert, int group)"  existed on modifier.c, changed
it a bit and moved into BKE_deform.h
2008-07-04 19:56:31 +00:00
44e13eb8d5 Generate and display multi resolution filtering graphs 2008-07-04 17:05:06 +00:00
baa1001b47 Initial GUI implementation, yet not functional 2008-07-04 15:23:21 +00:00
Maxime Curioni
5bee0c9a82 soc-2008-mxcurioni: foundations for Freestyle as a render layer - new UI buttons and mode flags, Freestyle API refactoring, modified pipeline to incorporate the new render layer. Compared to previously, the layer functionality is available when selecting 'Blender Internal' as the rendering engine. Freestyle's result is not available in the layer yet. I need to integrate OpenGL offscreen rendering properly (with framebuffer objects) to reach that goal. 2008-07-04 07:59:19 +00:00
ad310b5087 Added modes Squash and Strech to SimpleDeform (need testing)
CHanged the add modifier menu to show a submenu for selecting the type of simpledeform.
2008-07-04 01:03:50 +00:00
a4b6f74a48 Reeb Graph Copy procedures, for multi resolution filtering 2008-07-03 17:51:19 +00:00
a440769843 Fix arc flipping for null embedding filtering 2008-07-03 16:32:19 +00:00
2b3df6ea63 svn merge -r 14676:15409 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-07-02 21:55:25 +00:00
d350e272e7 Remove some debugging prints
Better symmetry detection using subtree shapes instead of depth
Fix the bug with flipping arcs caused by internal filtering
2008-07-02 21:36:45 +00:00
Maxime Curioni
ffb07fcfb3 soc-2008-mxcurioni: renamed libQGLWidget's Camera class to AppGLWidget_Camera to use Blender's Camera struct, integrated the camera parameters from Blender. Perspective projection (precisely field of view) is now correct. Orthographic projection still having issues. 2008-07-02 12:16:36 +00:00
eca709e481 Added lower and upper options on all modes of simple deform
Fixed existent offset after applying bend.
2008-07-02 00:17:08 +00:00
c7dbc65488 svn merge -r 15292:15392 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-06-30 22:57:52 +00:00
14c1ed0810 Fixed own platform bug with stat/fstat. 2008-06-28 00:07:22 +00:00
ab6e6b4c41 Mouse selection (LMB) and confirmation (MMB) added to suggestions UI. Also fixed the problem of offset text (horizontally scrolled). 2008-06-27 19:55:08 +00:00
09c898bd65 Modifications on simple modifier
+Added limits on bend
+button to create an empty and make child of object
+empty is now relative to object
2008-06-27 16:45:37 +00:00
aee5e95610 Modifying a file externally or deleting a file linked with a Blender Text object presents options for reloading, saving or separating the Text object from the external file (like the make local idea). 2008-06-26 18:28:33 +00:00
829b2668c5 Starting to debug the elusive graph spliting bug
Better check for RigGraph head
Fix harmonic weighting for quads
2008-06-26 18:15:45 +00:00
fc392040dd Added readline() and reset() for reading lines from a Blender Text Object and resetting the pointer to the beginning of the buffer. readline() will return the '\n' character and return '' when the end of the buffer is reached in accordance with other readline methods. 2008-06-25 21:00:39 +00:00
e68834c75b Added UI for suggestions list. Works with arrow-keys and mouse wheel, accept with Enter, reject with Esc or click elsewhere. Mouse selection not yet supported. The script is called from the File->Text Plugins menu.
Tidied python script, the C suggestions functions and fixed some bugs including suggestions not being freed properly.
2008-06-25 13:51:54 +00:00
bdc030c664 Text plugin basis with plugin for suggestions/completions. The suggest plugin works for imported global variables, methods, modules and module members. For example typing:
import Blender
from Blender import *
| <- cursor here suggests globals
Blender.Draw.gl| <- cursor here suggests all Draw members starting gl

Currently suggestions are listed in the console when the space is redrawn but will be presented as a menu-style list soon. Also to add are shortcut/activation keys to allow plugins to respond to certain key strokes.
2008-06-24 15:25:25 +00:00
9629f7ca11 Adding initial SimpleModifier (bend,taper,twist)
(I might only touch this code again late on the week :S, so here is a tmp commit)
2008-06-24 12:04:27 +00:00
c0daf62733 More robust primary symmetry axis algorithm (support branch in two)
Draw primary axis and weight delta
2008-06-23 21:47:31 +00:00
488fa13fc0 MERGING TRUNK 2008-06-23 16:37:51 +00:00
ac898d39ca Changed the style on shrinkwrapModifier_copyData.
Genscher made me do it the same way that the other 10 modifiers do.
The reason why I initially choosed memcpy was so that if anyone added
parameters on DNA there would be no need to update _copyData, unless
if it was a feature related to memory (eg.: point cache)
2008-06-23 16:23:26 +00:00
0f8697b9d2 Fixed bug.. on shrinkwrap_copyModifier 2008-06-23 15:48:03 +00:00
e426c7ce29 Added shrinkwrapModifier_isDisabled api function 2008-06-23 14:12:22 +00:00
39a7a24838 Display graph in 3d view 2008-06-22 17:06:50 +00:00
ffbe42129e svn merge -r 15202:15292 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-06-20 21:36:15 +00:00
824eac5095 Added cut-plane option.
Its now possible to project 2 planes over a model and get a cloth..
Tought it still has a few issues.. related with distance to kept from mesh.
2008-06-20 21:10:16 +00:00
b5bde6d4dc More params for reeb graph visualizer 2008-06-20 18:06:41 +00:00
42eed50935 Distance parameter for retargeting. Keeps bones close to the embedding (pretty much the same thing as the correlation/distance parameter when generating).
This is very slow though, the naive approach to optimising the solution is starting to take its toll.
2008-06-17 21:00:06 +00:00
05ce388f35 Added functions to the BPy Text object for positioning the cursor and inserting text. It seems Text.write() actually inserts *then* moves to the end of the buffer, so it doesn't really append as it says in the docs. However, with these new functions both appending and inserting can be achieved. 2008-06-17 19:26:26 +00:00
91f8ad8398 Added merge option to shrinkwrap when using projection mode (bruteforce for now)
Changed code to remove faces (now quad faces that got one vertice projected are turned on tri)

Merge option is still not very usefull since shrinkwrap does not yet moves unprojected vertices
2008-06-17 19:00:21 +00:00
Maxime Curioni
dfa10eba19 soc-2008-mxcurioni: Freestyle now supports camera information (the image is still a bit larger than Blender's internal renderer, probably a field of view problem). 3d scene is now no longer rendered, only 2d scene (strokes from view map information) is. Style module is still static (contour.py), will soon be handled via independent UI panel.
Phase 1 is considered finished. Phase 2 starts now: the objective is integrating Freestyle as an independent render layer.
2008-06-16 00:51:19 +00:00
Maxime Curioni
d8171e4bc6 soc-2008-mxcurioni: removed static dependencies (formerly fixed in app_blender/test_config.h). From now on, to use the branch, one needs to define a FREESTYLE_BLENDER_DIR environment variable to point to the Freestyle directory source/blender/freestyle 2008-06-13 22:23:24 +00:00
512019c6f2 First draft for gradient descent optimization for aggressive retargetting (results no go) 2008-06-13 21:07:46 +00:00
39d35edbe6 Merge from trunk
svn merge -r 15104:15202 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-06-11 22:53:52 +00:00
b5432c6780 Added sample "CreatePlane" .. it simple projects a grid over the selected image and determines which squares are to be used. 2008-06-11 22:35:27 +00:00
dce7e07001 Skeleton generation
Add option to select bone placement on embedding (following last commit).

Add option for distance to embedding adaptive subdivide (for comparison with correlation based method)
2008-06-10 21:15:48 +00:00
48bf0ef2ed Improvements to whole-word ops (thanks mindrones for suggestions). 2008-06-10 15:25:05 +00:00
10d59e7208 Merged from trunk
svn merge -r14988:15170 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-06-09 14:04:19 +00:00
7fd8c2424f Fix: Convert to spaces/tabs corrupted syntax 2008-06-09 12:45:49 +00:00
Maxime Curioni
07001e708e soc-2008-mxcurioni: merged changes to revision 15163 2008-06-08 20:12:29 +00:00
Maxime Curioni
062fb01614 soc-2008-mxcurioni: now supports current scene drawing (instead of fixed scene object), still with fixed style and fixed camera. Initialization is properly handled, which limits memory problems and speed-ups subsequent rendering. The viewing ratio should be correct now too. I also removed linking references to former lib3ds library path (caused some linking problems). 2008-06-08 19:35:20 +00:00
39a6807348 Prevent editing of linked library Texts 2008-06-08 19:29:19 +00:00
12f5a0a228 Added file info to header. Also reopen was marking text dirty (different from disk) which it isn't. 2008-06-06 11:32:45 +00:00
a68975f4e1 Whole word operations added:
* Alt-Left/Right: moves cursor/selection a word to the left/right
 * Alt-/Ctrl-Delete/Backspace deletes whole words at a time
2008-06-04 23:20:54 +00:00
ec4b6ba3f3 Fixed unreported bug: Backspace at top of text pushed newline onto undo stack 2008-06-04 16:03:19 +00:00
2dcab87383 Overwrite mode added, toggled with INSERTKEY 2008-06-04 12:32:06 +00:00
a39c8de24b Reason of last commits kdopbvh tree is now on trunk.
Added those files to the branch and added code for NearestNeighbour, needed for shrinkwrap
2008-06-03 19:56:19 +00:00
7265e9e855 Merge from trunk
svn merge -r 15064:15104 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-06-03 19:27:46 +00:00
db650f1be9 Removed BLI_kdopbvh 2008-06-03 19:20:57 +00:00
d6d4382396 Fix mem leak in graph rem doubles 2008-06-03 16:43:07 +00:00
6d0ac5095f Alternative method for correletation based skeleton subdivision (where bone end points can deviate from embedding).
Disabled because too unstable
2008-05-31 18:52:23 +00:00
7f3928652e Added culling on normal projection.
Now renderdemon is happy ;)
and now shrinkwrap can be used for bulging :)
2008-05-31 01:25:24 +00:00
318606addf Merge from trunk
svn merge  -r 14954:15064 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-05-30 20:33:33 +00:00
42740a1442 More and less debug prints
Also, setting the merge limit to be non-zero for armature graphs (since very small yet non-zero differences would prevent merges and correct graph creation)
2008-05-30 18:13:43 +00:00
08750f66a4 Retargetting
More refined symmetry grouping (can take care of tails properly) and better matching between symmetry groups (based on relative length of arcs)
2008-05-30 17:42:02 +00:00
Maxime Curioni
be2b832db7 soc-mx-curioni: resolved the rendering issue. In the previous steps, I was only rendering the strokes, not the toatl scene (explaining why the render color was being inverted). i added a call to the view's draw() method. Now, the rendering steps are complete and display both the object and the silhouette. 2008-05-29 11:41:06 +00:00
Maxime Curioni
f3966dda4e soc-2008-mxcurioni: made the image rendering faster by reading the frame buffer directly into the RenderResult's ImBuf structure, removing the need to copy it manually 2008-05-29 09:00:49 +00:00
Maxime Curioni
4b7174a6dd soc-2008-mxcurioni: updated SConscript file for SWIG module compilation and linking under Linux 2008-05-29 02:31:36 +00:00
Maxime Curioni
9a6302e109 soc-2008-mxcurioni: First render ! It should render the teapot upside down on a black background. The correction was made by following Yafray's rendering and display implementation, which is very clear. 2008-05-29 00:27:09 +00:00
Maxime Curioni
9986b5cd73 soc-2008-mxcurioni: corrected GLStrokeRender::preparePaper function for paper texture loading. The canvas view now has its frame properly initialized to fixed dimensions. When the Freestyle render is executed, the render is displayed for a fraction of a second and is then erased by a standard gray background. I have to analyze what command I need to call to keep the result on display. 2008-05-28 21:19:56 +00:00
ab787c9765 Generalizing the graph code used for Reeb graphs and Rig (Armature) graphs
Removing a lot of duplicated code
2008-05-28 16:39:05 +00:00
07e80dc265 Enabled EditMode on shrinkwrap modifier 2008-05-27 22:39:00 +00:00
40b0de4506 Fixed a compile error under msvc. 2008-05-27 18:40:33 +00:00
2a0a999a71 Added bvh nearest neighbour for nearest surface shrinkwrap 2008-05-27 18:32:23 +00:00
Maxime Curioni
58066fd0af soc-2008-mxcurioni: updated SWIG module linking instruction 2008-05-27 14:49:28 +00:00
Maxime Curioni
21c4797896 soc-2008-mxcurioni: Freestyle execution now works flawlessly (Python runtime loads appropriate modules, using SWIG wrapper), but does not render anything yet (render window OpenGL context not used yet). Currently, the SWIG wrapper library needs to be manually compiled (see SWIG section in source/blender/freestyle/SConscript for details). I am missing some knowledge on scons to create it automatically from the SConscript. Once I find that information, I'll make it automatic and for different platforms.
I also corrected a simple GLStrokeRenderer bug for texture loading (not in original Freestyle code). Apparently, IMB_loadiffname doesn't recognize the paper's texture depth so a work-around will have to be found.
2008-05-27 14:13:16 +00:00
db44a4a1a7 Skeleton retargetting - Preliminary commit. Results are encouraging but nothing *that* useful yet
Smarter heuristic noise arc filtering for Reeb graph
2008-05-27 13:33:24 +00:00
1345417f27 Reeb Graph importer (for debuging purpose only) 2008-05-27 13:24:38 +00:00
e70573badd gHash iterator initializer
To be able to have iterators on the stack/reuse iterators
2008-05-27 13:22:17 +00:00
8676e9f44e rebranching for skeleton generation phase 2 2008-05-27 12:38:07 +00:00
Maxime Curioni
4245f81605 soc-2008-mxcurioni: PythonInterpreter now properly handles its initialization (in accordance with original Freestyle code). This is achieved by creating a temporary Text structure, adding the required import and appending the necessary Python path. The text is executed using the BPY_txt_do_python_Text command.
When Freestyle is run within Blender, it should not crash; the Python interpreter should report an ImportError on _Freestyle (the SWIG wrapper).
2008-05-27 03:29:43 +00:00
04fb0c6f79 First commit and merge from trunk for testing.
Merge: 14970-14988
2008-05-26 23:04:37 +00:00
4383743ace Fixed some compile erros under msvc (thanks lguillaume)
Fixed object dependency (thanks ZanQdo for pointing it out)
Make some code cleaner
(preparing for adding bvh trees on nearest surface)
2008-05-26 21:57:53 +00:00
Maxime Curioni
373d42dbea soc-2008-mxcurioni: PythonInterpreter works, using Blender's Python functions. The drawing still does not produce anything because the SWIG module wrapper is missing 2008-05-26 19:52:55 +00:00
Maxime Curioni
fc8cd192a3 soc-2008-mxcurioni: Freestyle compiles but crashes at runtime because of the Python environment.
I analyzed the crash with gdb and PyImport_AddModule ("__main__") in Python/import.c:320 seems responsible for the crash: apparently, "__main__" is not found and causes the error "No such file or directory".

I have to figure out what's wrong with the current configuration, especially whether Freestyle's PythonInterpreter can be used as is. I am going to see whether it's just quicker to use Blender's functions.
2008-05-26 16:19:30 +00:00
ea760cade7 creating gsoc branch for Ian Thompson 2008-05-25 19:24:46 +00:00
Maxime Curioni
59df5a23b4 soc-2008-mxcurioni: merged changes to revision 14967 2008-05-25 18:28:52 +00:00
Maxime Curioni
8518e500d1 soc-2008-mxcurioni: Big update. Finally works (links and compiles). So far, the following steps work:
1. instantiates the config path, the controller and the view
2. sets the controller’s view
3. loads a 3ds file (right now a fixed file)
4. inserts a style module (right now, also fixed)
5. computes the view map

The next and final step is running the Python script. A lot of information are fixed and should be changed to test the following code: see source/blender/freestyle/app_blender/*.cpp and search for fixed paths (starting in /Users/).

I am currently evaluating whether it's worth making Python run on its own environment (right now, the program crashes because of PyImport_AddModule) or whether it should use Blender's Python capabilities. Also, I need to figure out how to integrate the SWIG wrapper dynamic library into the current scheme.
2008-05-25 17:34:21 +00:00
ad3f4c89aa Merge BVH tree fixes from cloth branch
svn merge -r 14954:14963 https://svn.blender.org/svnroot/bf-blender/branches/cloth/blender/source/blender/blenlib/BLI_kdopbvh.h
svn merge -r 14954:14963 https://svn.blender.org/svnroot/bf-blender/branches/cloth/blender/source/blender/blenlib/intern/BLI_kdopbvh.c
2008-05-25 15:47:54 +00:00
ad2fecf266 Added BVH nearest neighbour code, for now only works in 6-dop and finds the node with the nearest bounding volume.
I'll work on making it more generic.
So far it querys faster than kdtree, but building the tree is slower.
And bvhtree NN uses an heuristic based on the last match.

Shrinkwrap (OBCube)24578 over (OBSuzanne)31658
kdtree
build: 30.000000ms
query: 1360.000000ms

bvhtree
build: 140.000000ms
query: 490.000000ms

Shrinkwrap now uses bvhtree (binary tree, 6dop) for nearest vertex.
2008-05-25 15:43:18 +00:00
cc98ef4012 Merge from trunk
svn merge -r 14843:14954 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-05-25 13:53:58 +00:00
fd53876faf Merge bvh tree from cloth branch 2008-05-25 13:44:55 +00:00
Maxime Curioni
8ef2f1d524 soc-2008-mxcurioni: resolved uint issues (replaced with unsigned int). Still NOT linking 2008-05-19 13:15:07 +00:00
Maxime Curioni
09b36970bb soc-2008-mxcurioni: uploaded missing files. Still NOT linking so do not use this version yet :( 2008-05-19 05:34:31 +00:00
Maxime Curioni
32918e4523 corrected swig Sconscript to compile on unix-like machines 2008-05-18 14:10:44 +00:00
Maxime Curioni
55655a0659 soc-2008-mxcurioni: towards Freestyle's first render: controller, config, appglwidget corrected. Freestyle is called but cannot be linked (ImBuf issues). This is an unstable commit. 2008-05-18 13:01:52 +00:00
c4937891ea Merge from trunk
svn merge -r 14760:14843 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-05-14 20:01:22 +00:00
859a05864c I'm considering using bvhtree for shrinkwrap but the build was considerable slower than kdtree
as so i've made some improvements

So basicly theres no shrinkwrap improvements for now...
2008-05-14 18:25:23 +00:00
Maxime Curioni
29b2db8518 soc-2008-mxcurioni: swig SConscript updated to compile under all configs except Win32 (where binary is copied to build directory) 2008-05-11 21:49:04 +00:00
Maxime Curioni
6069124ac9 soc-2008-mxcurioni: lib3ds SConscript updated to compile under Win32 configs 2008-05-11 21:13:54 +00:00
Maxime Curioni
c785d7493e soc-2008-mxcurioni: merged changes to revision 14798, compilation works for rendering/ directry. Still needs to figure out how to compile on non-Unix machines. 2008-05-11 20:28:47 +00:00
Maxime Curioni
fd9ad58298 soc-2008-mxcurioni: towards Freestyle compilation, removing Qt's QString and QImage dependencies. Up to this commit, the following directories compile well (and without any warning): system, image, geometry, graph, winged_edge, view_map, stroke.
Modified code is commented by //soc and unused variables by //soc unused
2008-05-09 23:06:28 +00:00
53e08925b5 Merge from trunk
svn merge -r 14692:14760 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-05-09 11:57:52 +00:00
Maxime Curioni
64e4a3ec9a soc-2008-mxcurioni: merged changes to revision 14747, cosmetic changes for source/blender/freestyle 2008-05-08 19:16:40 +00:00
50acbe29d1 Normal projection:
+added option to remove faces where all vertices got unprojected

Nearest surface point
+15% faster closest point on point-tri function
(archived by projecting the point on tri-plane and solving the problem on 2D)
(its still using bruteforce on triangles.. I'll add the right data structure later)
2008-05-07 12:45:02 +00:00
Maxime Curioni
cf2e1e2857 soc=2008-mxcurioni: reverted back to compiling swig as a binary, instead of as a library 2008-05-07 03:37:16 +00:00
Maxime Curioni
959f1a0f92 soc-2008-mxcurioni: swig compiles as independent library 2008-05-06 17:23:27 +00:00
Maxime Curioni
914a4d1a6c soc-2008-mxcurioni: lib3ds compiles as an external library 2008-05-05 19:26:10 +00:00
0b7ab2f8ec Merge from trunk
svn merge -r 14626:14692 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-05-05 17:30:33 +00:00
Maxime Curioni
102868467b lib3ds, swig added to extern/freestyle 2008-05-05 17:28:14 +00:00
Maxime Curioni
ec90691384 merge to 14689, Freestyle library changes, SConscript start 2008-05-05 16:56:44 +00:00
4983308a38 svn merge -r 14649:14676 https://svn.blender.org/svnroot/bf-blender/trunk/blender (sorry - forgot half of the commits last time) 2008-05-04 14:14:54 +00:00
2b5432e6bb Added control over distance to kept form target mesh
Quad bug was fixed by splitting the quads that are feed to RayTree
2008-05-02 22:09:01 +00:00
9026559ded +normal projection optimized with RayTree (RE_raytrace.h)
+control for normal projection direction (default,inverted,both)

There are some bugs on projection over quads.. it seems to work 100% on fully triangulized meshs
2008-05-02 00:16:48 +00:00
64f5d1bdf3 Nearest-vertex mode optimized with kdtrees
currently uses the kdtree code avaible on blender
2008-05-01 01:00:01 +00:00
27afa69c9a svn merge -r 14561:14627 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-04-30 18:30:11 +00:00
10ce8e3281 Merge trunk with branch
svn merge -r 14551:14626 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-04-30 18:14:27 +00:00
29f0f74b05 Changed a bit of code structure to make method optimization easier 2008-04-30 17:55:26 +00:00
Maxime Curioni
1cf3378793 Added Freestyle to extern/ directory 2008-04-30 15:41:54 +00:00
Maxime Curioni
f12cf0e250 Merged changes from trunk to soc-2008-mxcurioni, to revision 14603 2008-04-28 19:21:51 +00:00
Maxime Curioni
812a0eb1fb Merged changes from trunk to soc-2008-mxcurioni: svn merge -r 14534:14595 https://svn.blender.org/svnroot/bf-blender/trunk/blender/ 2008-04-28 16:21:26 +00:00
928b676b99 Implemented shrink modes are now:
+ Nearest surface point
+ Normal projection
+ Nearest vertex (gives similar results to nearest surface if the target mesh has many vertexs and is a lot faster to calculate)
^^ all bruteforce calculation for now

+ fixed matrix order multiplication
+ request for CD_MDEDEFORMVERT
2008-04-27 19:29:40 +00:00
31fffd00d3 svn merge -r 14505:14561 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-04-27 17:22:57 +00:00
7374d23b61 Merge trunk with branch
svn merge -r 14529:14551 https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-04-25 18:28:59 +00:00
a0add959ff Shrinkwrap skeleton code
+vertex weights supported
+target object now saves to file: load/save works :)

for now simple moves objects vertexs to the nearest vertexs on target object
(so that I can test if its working correctly with the modifier API)
2008-04-25 18:22:20 +00:00
149f7f07d2 Merge trunk with branch
svn merge -r 14521:head https://svn.blender.org/svnroot/bf-blender/trunk/blender
2008-04-23 13:06:53 +00:00
087c66fd29 Added simple UI to configure some shrinkwrap modifier properties (simple commit to try svn) 2008-04-23 12:44:10 +00:00
2fb9b30485 Creating GSoC branch for mxcurioni 2008-04-23 02:20:01 +00:00
Chris Want
71a2bd140a Creating GSoC branch for jaguarandi 2008-04-22 22:13:06 +00:00
c9c3c41815 svn merge -r 14236:14505 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2008-04-21 21:30:50 +00:00
006d4d1176 This version now includes the fluid control sources, however the Blender
interface for it is still missing. Right now there is only a simple hard coded
example, that moves a single control particle with strong attraction
and velocity forces through the domain.

I added more detailed information about the control code to the wiki
http://wiki.blender.org/index.php/SoCFluidDevelDoc#The_Fluid-Control_Branch ,
together with some thoughts on how a Blender integration could be done.
2008-04-08 16:56:43 +00:00
5606cb156e creating branch for Nils 2008-03-25 13:18:13 +00:00
1095 changed files with 90820 additions and 30538 deletions

View File

@@ -38,6 +38,10 @@ MACRO(BLENDERLIB
ENDMACRO(BLENDERLIB)
MACRO(SETUP_LIBDIRS)
# see "cmake --help-policy CMP0003"
if(COMMAND cmake_policy)
CMAKE_POLICY(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
LINK_DIRECTORIES(${PYTHON_LIBPATH} ${SDL_LIBPATH} ${JPEG_LIBPATH} ${PNG_LIBPATH} ${ZLIB_LIBPATH} ${ICONV_LIBPATH} ${OPENEXR_LIBPATH} ${QUICKTIME_LIBPATH} ${FFMPEG_LIBPATH})
IF(WITH_INTERNATIONAL)
LINK_DIRECTORIES(${GETTEXT_LIBPATH})

View File

@@ -63,8 +63,8 @@ OPTION(WITH_QUICKTIME "Enable Quicktime Support" OFF)
OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF)
OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF)
OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" OFF)
OPTION(WITH_WEBPLUGIN "Enable Web Plugin (Mozilla-Unix only)" OFF)
IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
@@ -183,9 +183,9 @@ IF(UNIX)
SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++")
IF(WITH_OPENMP)
SET(LLIBS "${LLIBS} -lgomp ")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
SET(LLIBS "${LLIBS} -lgomp")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
ENDIF(WITH_OPENMP)
@@ -197,10 +197,17 @@ IF(UNIX)
ENDIF(UNIX)
IF(WIN32)
INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake)
INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake)
SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/windows)
# Setup 64bit and 64bit windows systems
IF(CMAKE_CL_64)
message("64 bit compiler detected.")
SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/win64)
ENDIF(CMAKE_CL_64)
SET(PYTHON ${LIBDIR}/python)
SET(PYTHON_VERSION 2.5)
SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}")
@@ -214,12 +221,20 @@ IF(WIN32)
SET(OPENAL_LIB openal_static)
SET(OPENAL_LIBPATH ${OPENAL}/lib)
SET(PNG_LIB libpng_st)
IF(CMAKE_CL_64)
SET(PNG_LIB libpng)
ELSE(CMAKE_CL_64)
SET(PNG_LIB libpng_st)
ENDIF(CMAKE_CL_64)
SET(JPEG_LIB libjpeg)
SET(ZLIB ${LIBDIR}/zlib)
SET(ZLIB_INC ${ZLIB}/include)
SET(ZLIB_LIB libz)
IF(CMAKE_CL_64)
SET(ZLIB_LIB zlib)
ELSE(CMAKE_CL_64)
SET(ZLIB_LIB libz)
ENDIF(CMAKE_CL_64)
SET(ZLIB_LIBPATH ${ZLIB}/lib)
SET(PTHREADS ${LIBDIR}/pthreads)
@@ -234,7 +249,11 @@ IF(WIN32)
SET(GETTEXT ${LIBDIR}/gettext)
SET(GETTEXT_INC ${GETTEXT}/include)
SET(GETTEXT_LIB gnu_gettext)
IF(CMAKE_CL_64)
SET(GETTEXT_LIB gettextlib)
ELSE(CMAKE_CL_64)
SET(GETTEXT_LIB gnu_gettext)
ENDIF(CMAKE_CL_64)
SET(GETTEXT_LIBPATH ${GETTEXT}/lib)
SET(FREETYPE ${LIBDIR}/freetype)
@@ -265,7 +284,12 @@ IF(WIN32)
SET(FFMPEG_LIB avcodec-51 avformat-52 avdevice-52 avutil-49 swscale-0)
SET(FFMPEG_LIBPATH ${FFMPEG}/lib)
IF(CMAKE_CL_64)
SET(LLIBS kernel32 user32 vfw32 winmm ws2_32 )
ELSE(CMAKE_CL_64)
SET(LLIBS kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid ws2_32 vfw32 winmm)
ENDIF(CMAKE_CL_64)
IF(WITH_OPENAL)
SET(LLIBS ${LLIBS} dxguid)
ENDIF(WITH_OPENAL)
@@ -302,7 +326,11 @@ IF(WIN32)
SET(WINTAB_INC ${LIBDIR}/wintab/include)
SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib")
IF(CMAKE_CL_64)
SET(PLATFORM_LINKFLAGS "/MACHINE:X64 /NODEFAULTLIB:libc.lib;MSVCRT.lib ")
ELSE(CMAKE_CL_64)
SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib ")
ENDIF(CMAKE_CL_64)
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib;libc.lib ")
ENDIF(WIN32)
@@ -429,6 +457,13 @@ SUBDIRS(
# Blender Application
SUBDIRS(source/creator)
#-----------------------------------------------------------------------------
# Blender WebPlugin
IF(WITH_WEBPLUGIN)
SET(MOZILLA_DIR "${CMAKE_SOURCE_DIR}/../gecko-sdk/" CACHE PATH "Gecko SDK path")
SET(WITH_PLAYER ON)
ENDIF(WITH_WEBPLUGIN)
#-----------------------------------------------------------------------------
# Blender Player
IF(WITH_PLAYER)

14
README
View File

@@ -24,22 +24,22 @@ dir to one of these locations (your home directory being recommended).
-------------------------------------Links--------------------------------------
Getting Involved:
http://www.blender.org/docs/get_involved.html
http://www.blender.org/community/get-involved
Community:
http://www.blender3d.org/Community/
http://www.blender.org/Community
Main blender development site:
http://www.blender.org/
http://www.blender.org
The Blender project homepage:
http://projects.blender.org/projects/bf-blender/
http://projects.blender.org/projects/bf-blender
Documentation:
http://www.blender.org/modules.php?op=modload&name=documentation&file=index
http://www.blender.org/education-help
Bug tracker:
http://projects.blender.org/tracker/?atid=125&group_id=9&func=browse
http://www.blender.org/development/report-a-bug
Feature request tracker:
http://projects.blender.org/tracker/?atid=128&group_id=9&func=browse
http://wiki.blender.org/index.php/Requests

View File

@@ -184,15 +184,16 @@ if env['WITH_BF_OPENMP'] == 1:
env['CPPFLAGS'].append('/openmp')
env['CXXFLAGS'].append('/openmp')
else:
if env['CC'] == 'icc':
if env['CC'][-3:] == 'icc': # to be able to handle CC=/opt/bla/icc case
env.Append(LINKFLAGS=['-openmp', '-static-intel'])
env['CCFLAGS'].append('-openmp')
env['CPPFLAGS'].append('-openmp')
env['CXXFLAGS'].append('-openmp')
else:
env['CCFLAGS'].append('-fopenmp')
env['CPPFLAGS'].append('-fopenmp')
env['CXXFLAGS'].append('-fopenmp')
env.Append(CCFLAGS=['-fopenmp'])
env.Append(CPPFLAGS=['-fopenmp'])
env.Append(CXXFLAGS=['-fopenmp'])
# env.Append(LINKFLAGS=['-fprofile-generate'])
#check for additional debug libnames
@@ -240,6 +241,13 @@ if len(B.quickdebug) > 0 and printdebug != 0:
for l in B.quickdebug:
print "\t" + l
# remove stdc++ from LLIBS if we are building a statc linked CXXFLAGS
if env['WITH_BF_STATICCXX']:
if 'stdc++' in env['LLIBS']:
env['LLIBS'] = env['LLIBS'].replace('stdc++', ' ')
else:
print '\tcould not remove stdc++ library from LLIBS, WITH_BF_STATICCXX may not work for your platform'
# check target for blenderplayer. Set WITH_BF_PLAYER if found on cmdline
if 'blenderplayer' in B.targets:
env['WITH_BF_PLAYER'] = True
@@ -247,6 +255,31 @@ if 'blenderplayer' in B.targets:
if 'blendernogame' in B.targets:
env['WITH_BF_GAMEENGINE'] = False
if 'blenderlite' in B.targets:
env['WITH_BF_GAMEENGINE'] = False
env['WITH_BF_OPENAL'] = False
env['WITH_BF_OPENEXR'] = False
env['WITH_BF_ICONV'] = False
env['WITH_BF_INTERNATIONAL'] = False
env['WITH_BF_OPENJPEG'] = False
env['WITH_BF_FFMPEG'] = False
env['WITH_BF_QUICKTIME'] = False
env['WITH_BF_YAFRAY'] = False
env['WITH_BF_REDCODE'] = False
env['WITH_BF_FTGL'] = False
env['WITH_BF_DDS'] = False
env['WITH_BF_ZLIB'] = False
env['WITH_BF_SDL'] = False
env['WITH_BF_JPEG'] = False
env['WITH_BF_PNG'] = False
env['WITH_BF_ODE'] = False
env['WITH_BF_BULLET'] = False
env['WITH_BF_BINRELOC'] = False
env['BF_BUILDINFO'] = False
env['BF_NO_ELBEEM'] = True
# lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir
#B.root_build_dir = B.arguments.get('BF_BUILDDIR', '..'+os.sep+'build'+os.sep+platform+os.sep)
B.root_build_dir = env['BF_BUILDDIR']
@@ -389,6 +422,26 @@ if env['OURPLATFORM']!='darwin':
source=[dp+os.sep+f for f in df]
scriptinstall.append(env.Install(dir=dir,source=source))
#-- icons
if env['OURPLATFORM']=='linux2':
iconlist = []
icontargetlist = []
for tp, tn, tf in os.walk('release/freedesktop/icons'):
if 'CVS' in tn:
tn.remove('CVS')
if '.svn' in tn:
tn.remove('.svn')
for f in tf:
print ">>>", env['BF_INSTALLDIR'], tp, f
iconlist.append(tp+os.sep+f)
icontargetlist.append(env['BF_INSTALLDIR']+tp[19:]+os.sep+f)
iconinstall = []
for targetdir,srcfile in zip(icontargetlist, iconlist):
td, tf = os.path.split(targetdir)
iconinstall.append(env.Install(dir=td, source=srcfile))
#-- plugins
pluglist = []
plugtargetlist = []
@@ -437,6 +490,8 @@ textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist)
if env['OURPLATFORM']=='darwin':
allinstall = [blenderinstall, plugininstall, textinstall]
elif env['OURPLATFORM']=='linux2':
allinstall = [blenderinstall, dotblenderinstall, scriptinstall, plugininstall, textinstall, iconinstall]
else:
allinstall = [blenderinstall, dotblenderinstall, scriptinstall, plugininstall, textinstall]
@@ -487,6 +542,10 @@ if not env['WITH_BF_GAMEENGINE']:
blendernogame = env.Alias('blendernogame', B.program_list)
Depends(blendernogame,installtarget)
if 'blenderlite' in B.targets:
blenderlite = env.Alias('blenderlite', B.program_list)
Depends(blenderlite,installtarget)
Depends(nsiscmd, allinstall)
Default(B.program_list)

View File

@@ -20,3 +20,4 @@ Romanian:ro
Arabic:ar
Bulgarian:bg
Greek:el
Korean:kr

View File

@@ -86,10 +86,12 @@ IF(UNIX)
bf_oglrasterizer
bf_expressions
bf_scenegraph
bf_IK
bf_moto
bf_soundsystem
bf_kernel
bf_nodes
bf_gpu
bf_imbuf
bf_avi
kx_network

View File

@@ -87,10 +87,18 @@ if MAC_PROC == 'powerpc':
BF_OPENAL = '#../lib/darwin-8.0.0-powerpc/openal'
else :
BF_OPENAL = LIBDIR + '/openal'
WITH_BF_STATICOPENAL = 'false'
BF_OPENAL_INC = '${BF_OPENAL}/include'
BF_OPENAL_LIB = 'openal'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_CXX = '/usr'
WITH_BF_STATICCXX = 'false'
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
WITH_BF_SDL = 'true'
BF_SDL = LIBDIR + '/sdl' #$(shell sdl-config --prefix)
@@ -102,10 +110,13 @@ WITH_BF_FMOD = 'false'
BF_FMOD = LIBDIR + '/fmod'
WITH_BF_OPENEXR = 'true'
WITH_BF_STATICOPENEXR = 'false'
BF_OPENEXR = '${LCGDIR}/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread'
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
WITH_BF_DDS = 'true'
@@ -143,7 +154,6 @@ BF_FTGL_LIB = 'extern_ftgl'
WITH_BF_GAMEENGINE='true'
WITH_BF_PLAYER='true'
WITH_BF_GLEXT= '1'
WITH_BF_ODE = 'false'
BF_ODE = LIBDIR + '/ode'

View File

@@ -6,18 +6,28 @@ BF_VERSE_INCLUDE = "#extern/verse/dist"
BF_PYTHON = '/usr'
BF_PYTHON_VERSION = '2.5'
WITH_BF_STATICPYTHON = 'false'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}' #BF_PYTHON+'/lib/python'+BF_PYTHON_VERSION+'/config/libpython'+BF_PYTHON_VERSION+'.a'
BF_PYTHON_LINKFLAGS = ['-Xlinker', '-export-dynamic']
BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION}.a'
WITH_BF_OPENAL = 'true'
WITH_BF_STATICOPENAL = 'false'
BF_OPENAL = '/usr'
BF_OPENAL_INC = '${BF_OPENAL}/include'
BF_OPENAL_LIB = 'openal'
BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
# some distros have a separate libalut
# if you get linker complaints, you need to uncomment the line below
# BF_OPENAL_LIB = 'openal alut'
# BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a ${BF_OPENAL}/lib/libalut.a'
BF_CXX = '/usr'
WITH_BF_STATICCXX = 'false'
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
WITH_BF_SDL = 'true'
BF_SDL = '/usr' #$(shell sdl-config --prefix)
@@ -28,14 +38,17 @@ WITH_BF_FMOD = 'false'
BF_FMOD = LIBDIR + '/fmod'
WITH_BF_OPENEXR = 'true'
WITH_BF_STATICOPENEXR = 'false'
BF_OPENEXR = '/usr'
# when compiling with your own openexr lib you might need to set...
# BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
WITH_BF_DDS = 'true'
WITH_BF_JPEG = 'true'
@@ -139,7 +152,7 @@ BF_OPENJPEG_LIB = ''
BF_OPENJPEG_INC = '${BF_OPENJPEG}/include'
BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib'
WITH_BF_REDCODE = 'true'
WITH_BF_REDCODE = 'false'
BF_REDCODE = '#extern/libredcode'
BF_REDCODE_LIB = ''
# Uncomment the following two lines to use system's ffmpeg
@@ -166,8 +179,8 @@ CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing']
CPPFLAGS = ['-DXP_UNIX']
CXXFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing']
REL_CFLAGS = ['-O2']
REL_CCFLAGS = ['-O2']
REL_CFLAGS = ['-O3']
REL_CCFLAGS = ['-O3']
##BF_DEPEND = 'true'
##
##AR = ar

View File

@@ -14,10 +14,18 @@ BF_PYTHON_LIB = 'python25'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = 'true'
WITH_BF_STATICOPENAL = 'false'
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include'
BF_OPENAL_LIB = 'openal_static'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_CXX = '/usr'
WITH_BF_STATICCXX = 'false'
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
WITH_BF_SDL = 'true'
BF_SDL = LIBDIR + '/sdl'
@@ -34,10 +42,13 @@ WITH_BF_FMOD = 'false'
BF_FMOD = LIBDIR + '/fmod'
WITH_BF_OPENEXR = 'true'
WITH_BF_STATICOPENEXR = 'false'
BF_OPENEXR = LIBDIR + '/gcc/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = ' Half IlmImf Iex '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
WITH_BF_DDS = 'true'

View File

@@ -9,10 +9,12 @@ BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}/config'
WITH_BF_OPENAL = 'false'
# WITH_BF_STATICOPENAL = 'false'
#BF_OPENAL = LIBDIR + '/openal'
#BF_OPENAL_INC = '${BF_OPENAL}/include'
#BF_OPENAL_LIB = 'openal'
#BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
#BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
WITH_BF_SDL = 'true'
BF_SDL = '/usr/local' #$(shell sdl-config --prefix)
@@ -24,9 +26,12 @@ WITH_BF_FMOD = 'false'
BF_FMOD = LIBDIR + '/fmod'
WITH_BF_OPENEXR = 'false'
WITH_BF_STATICOPENEXR = 'false'
BF_OPENEXR = '/usr/local'
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
WITH_BF_DDS = 'true'

View File

@@ -9,10 +9,18 @@ BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}' #BF_PYTHON+'/lib/python'+BF_PYTHON_
BF_PYTHON_LINKFLAGS = ['-Xlinker', '-export-dynamic']
WITH_BF_OPENAL = 'true'
WITH_BF_STATICOPENAL = 'false'
BF_OPENAL = '/usr/local'
BF_OPENAL_INC = '${BF_OPENAL}/include'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
BF_OPENAL_LIB = 'openal'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_CXX = '/usr'
WITH_BF_STATICCXX = 'false'
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
WITH_BF_SDL = 'true'
BF_SDL = '/usr/local' #$(shell sdl-config --prefix)
@@ -24,10 +32,13 @@ WITH_BF_FMOD = 'false'
BF_FMOD = LIBDIR + '/fmod'
WITH_BF_OPENEXR = 'true'
WITH_BF_STATICOPENEXR = 'false'
BF_OPENEXR = '/usr/local'
BF_OPENEXR_INC = ['${BF_OPENEXR}/include', '${BF_OPENEXR}/include/OpenEXR' ]
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
WITH_BF_DDS = 'true'

View File

@@ -12,10 +12,13 @@ BF_PYTHON_LIB = 'python25'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = 'true'
WITH_BF_STATICOPENAL = 'false'
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include'
BF_OPENAL_LIB = 'dxguid openal_static'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
WITH_BF_FFMPEG = 'false'
BF_FFMPEG_LIB = 'avformat swscale avcodec avutil xvidcore x264'
@@ -37,10 +40,13 @@ WITH_BF_FMOD = 'false'
BF_FMOD = LIBDIR + '/fmod'
WITH_BF_OPENEXR = 'true'
WITH_BF_STATICOPENEXR = 'false'
BF_OPENEXR = LIBDIR + '/gcc/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = ' Half IlmImf Iex '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
WITH_BF_DDS = 'true'

View File

@@ -19,10 +19,18 @@ BF_PYTHON_LIB = 'python25'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = 'true'
WITH_BF_STATICOPENAL = 'false'
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include ${BF_OPENAL}/include/AL '
BF_OPENAL_LIB = 'dxguid openal_static'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
# TODO - are these useful on win32?
# BF_CXX = '/usr'
# WITH_BF_STATICCXX = 'false'
# BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
WITH_BF_ICONV = 'true'
BF_ICONV = LIBDIR + '/iconv'
@@ -45,10 +53,13 @@ WITH_BF_FMOD = 'false'
BF_FMOD = LIBDIR + '/fmod'
WITH_BF_OPENEXR = 'true'
WITH_BF_STATICOPENEXR = 'false'
BF_OPENEXR = LIBDIR + '/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/IlmImf ${BF_OPENEXR}/include/Iex ${BF_OPENEXR}/include/Imath '
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib_msvc'
# Warning, this static lib configuration is untested! users of this OS please confirm.
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
WITH_BF_DDS = 'true'

View File

@@ -35,6 +35,7 @@ FILE(GLOB SRC
src/BulletDynamics/ConstraintSolver/*.cpp
src/BulletDynamics/Vehicle/*.cpp
src/BulletDynamics/Dynamics/*.cpp
src/BulletSoftBody/*.cpp
)
ADD_DEFINITIONS(-D_LIB)

View File

@@ -40,7 +40,8 @@ BulletCollision/NarrowPhaseCollision \
BulletCollision//CollisionDispatch \
BulletDynamics/ConstraintSolver \
BulletDynamics/Vehicle \
BulletDynamics/Dynamics
BulletDynamics/Dynamics \
BulletSoftBody
include nan_subdirs.mk

View File

@@ -58,9 +58,11 @@ IF NOT EXIST ..\..\..\..\..\build\msvc_7\extern\bullet2\include\BulletDynamics\C
IF NOT EXIST ..\..\..\..\..\build\msvc_7\extern\bullet2\include\BulletDynamics\Dynamics MKDIR ..\..\..\..\..\build\msvc_7\extern\bullet\include\BulletDynamics\Dynamics
IF NOT EXIST ..\..\..\..\..\build\msvc_7\extern\bullet2\include\BulletDynamics\Vehicle MKDIR ..\..\..\..\..\build\msvc_7\extern\bullet\include\BulletDynamics\Vehicle
IF NOT EXIST ..\..\..\..\..\build\msvc_7\extern\bullet2\include\LinearMath MKDIR ..\..\..\..\..\build\msvc_7\extern\bullet\include\LinearMath
IF NOT EXIST ..\..\..\..\..\build\msvc_7\extern\bullet2\include\BulletSoftBody MKDIR ..\..\..\..\..\build\msvc_7\extern\bullet\include\BulletSoftBody
XCOPY /Y ..\..\src\*.h ..\..\..\..\..\build\msvc_7\extern\bullet\include
XCOPY /Y ..\..\src\LinearMath\*.h ..\..\..\..\..\build\msvc_7\extern\bullet\include\LinearMath
XCOPY /Y ..\..\src\BulletSoftBody\*.h ..\..\..\..\..\build\msvc_7\extern\bullet\include\BulletSoftBody
XCOPY /Y ..\..\src\BulletCollision\BroadphaseCollision\*.h ..\..\..\..\..\build\msvc_7\extern\bullet\include\BulletCollision\BroadphaseCollision
XCOPY /Y ..\..\src\BulletCollision\NarrowPhaseCollision\*.h ..\..\..\..\..\build\msvc_7\extern\bullet\include\BulletCollision\NarrowPhaseCollision
XCOPY /Y ..\..\src\BulletCollision\NarrowPhaseCollision\*.h ..\..\..\..\..\build\msvc_7\extern\bullet\include\BulletCollision\NarrowPhaseCollision
@@ -394,12 +396,24 @@ ECHO Done
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btSequentialImpulseConstraintSolver.h">
</File>
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btSliderConstraint.cpp">
</File>
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btSliderConstraint.h">
</File>
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btSolve2LinearConstraint.cpp">
</File>
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btSolve2LinearConstraint.h">
</File>
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btSolverBody.h">
</File>
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btSolverConstraint.h">
</File>
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btTypedConstraint.cpp">
</File>
@@ -410,6 +424,12 @@ ECHO Done
<Filter
Name="Dynamics"
Filter="">
<File
RelativePath="..\..\src\BulletDynamics\Dynamics\btContinuousDynamicsWorld.cpp">
</File>
<File
RelativePath="..\..\src\BulletDynamics\Dynamics\btContinuousDynamicsWorld.h">
</File>
<File
RelativePath="..\..\src\BulletDynamics\Dynamics\btDiscreteDynamicsWorld.cpp">
</File>
@@ -482,18 +502,45 @@ ECHO Done
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btCollisionAlgorithm.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btDbvt.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btDbvt.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btDbvtBroadphase.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btDbvtBroadphase.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btDispatcher.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btDispatcher.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btMultiSapBroadphase.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btMultiSapBroadphase.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btOverlappingPairCache.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btOverlappingPairCache.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btOverlappingPairCallback.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btQuantizedBvh.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btQuantizedBvh.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\BroadphaseCollision\btSimpleBroadphase.cpp">
</File>
@@ -534,6 +581,12 @@ ECHO Done
<File
RelativePath="..\..\src\BulletCollision\NarrowPhaseCollision\btGjkEpa.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\NarrowPhaseCollision\btGjkEpa2.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\NarrowPhaseCollision\btGjkEpa2.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\NarrowPhaseCollision\btGjkEpaPenetrationDepthSolver.cpp">
</File>
@@ -589,6 +642,21 @@ ECHO Done
<Filter
Name="CollisionDispatch"
Filter="">
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btBoxBoxCollisionAlgorithm.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btBoxBoxCollisionAlgorithm.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btBoxBoxDetector.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btBoxBoxDetector.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btCollisionConfiguration.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btCollisionCreateFunc.h">
</File>
@@ -628,6 +696,18 @@ ECHO Done
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btConvexConvexAlgorithm.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btConvexPlaneCollisionAlgorithm.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btConvexPlaneCollisionAlgorithm.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btDefaultCollisionConfiguration.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btDefaultCollisionConfiguration.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btEmptyCollisionAlgorithm.cpp">
</File>
@@ -731,6 +811,12 @@ ECHO Done
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btConvexHullShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btConvexInternalShape.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btConvexInternalShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btConvexShape.cpp">
</File>
@@ -761,12 +847,21 @@ ECHO Done
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btHeightfieldTerrainShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btMaterial.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btMinkowskiSumShape.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btMinkowskiSumShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btMultimaterialTriangleMeshShape.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btMultimaterialTriangleMeshShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btMultiSphereShape.cpp">
</File>
@@ -785,6 +880,18 @@ ECHO Done
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btPolyhedralConvexShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btScaledBvhTriangleMeshShape.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btScaledBvhTriangleMeshShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btShapeHull.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btShapeHull.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btSphereShape.cpp">
</File>
@@ -827,6 +934,12 @@ ECHO Done
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btTriangleIndexVertexArray.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btTriangleIndexVertexMaterialArray.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btTriangleIndexVertexMaterialArray.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btTriangleMesh.cpp">
</File>
@@ -842,6 +955,12 @@ ECHO Done
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btTriangleShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btUniformScalingShape.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btUniformScalingShape.h">
</File>
</Filter>
</Filter>
<Filter
@@ -859,6 +978,12 @@ ECHO Done
<File
RelativePath="..\..\src\LinearMath\btAlignedObjectArray.h">
</File>
<File
RelativePath="..\..\src\LinearMath\btConvexHull.cpp">
</File>
<File
RelativePath="..\..\src\LinearMath\btConvexHull.h">
</File>
<File
RelativePath="..\..\src\LinearMath\btDefaultMotionState.h">
</File>
@@ -868,6 +993,9 @@ ECHO Done
<File
RelativePath="..\..\src\LinearMath\btGeometryUtil.h">
</File>
<File
RelativePath="..\..\src\LinearMath\btHashMap.h">
</File>
<File
RelativePath="..\..\src\LinearMath\btIDebugDraw.h">
</File>
@@ -886,6 +1014,9 @@ ECHO Done
<File
RelativePath="..\..\src\LinearMath\btPoint3.h">
</File>
<File
RelativePath="..\..\src\LinearMath\btPoolAllocator.h">
</File>
<File
RelativePath="..\..\src\LinearMath\btQuadWord.h">
</File>
@@ -904,9 +1035,6 @@ ECHO Done
<File
RelativePath="..\..\src\LinearMath\btScalar.h">
</File>
<File
RelativePath="..\..\src\LinearMath\btSimdMinMax.h">
</File>
<File
RelativePath="..\..\src\LinearMath\btStackAlloc.h">
</File>
@@ -920,6 +1048,58 @@ ECHO Done
RelativePath="..\..\src\LinearMath\btVector3.h">
</File>
</Filter>
<Filter
Name="BulletSoftBody"
Filter="">
<File
RelativePath="..\..\src\BulletSoftBody\btSoftBody.cpp">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftBody.h">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftBodyConcaveCollisionAlgorithm.cpp">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftBodyConcaveCollisionAlgorithm.h">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftBodyHelpers.cpp">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftBodyHelpers.h">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftBodyInternals.h">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftBodyRigidBodyCollisionConfiguration.cpp">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftBodyRigidBodyCollisionConfiguration.h">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftRigidCollisionAlgorithm.cpp">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftRigidCollisionAlgorithm.h">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftRigidDynamicsWorld.cpp">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftRigidDynamicsWorld.h">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftSoftCollisionAlgorithm.cpp">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSoftSoftCollisionAlgorithm.h">
</File>
<File
RelativePath="..\..\src\BulletSoftBody\btSparseSDF.h">
</File>
</Filter>
</Filter>
</Files>
<Globals>

View File

@@ -1,3 +1,8 @@
***
Apply bullet_compound_raycast.patch if not already applied in Bullet source
This patch is needed to return correct raycast results on compound shape.
/ben
*** These files in extern/bullet2 are NOT part of the Blender build yet ***

View File

@@ -23,15 +23,153 @@ subject to the following restrictions:
#ifndef BULLET_C_API_H
#define BULLET_C_API_H
#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
#ifdef BT_USE_DOUBLE_PRECISION
typedef double plReal;
#else
typedef float plReal;
#endif
typedef plReal plVector3[3];
typedef plReal plQuaternion[4];
#ifdef __cplusplus
extern "C" {
#endif
double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
/* Particular physics SDK */
PL_DECLARE_HANDLE(plPhysicsSdkHandle);
/* Dynamics world, belonging to some physics SDK */
PL_DECLARE_HANDLE(plDynamicsWorldHandle);
/* Rigid Body that can be part of a Dynamics World */
PL_DECLARE_HANDLE(plRigidBodyHandle);
/* Collision Shape/Geometry, property of a Rigid Body */
PL_DECLARE_HANDLE(plCollisionShapeHandle);
/* Constraint for Rigid Bodies */
PL_DECLARE_HANDLE(plConstraintHandle);
/* Triangle Mesh interface */
PL_DECLARE_HANDLE(plMeshInterfaceHandle);
/* Broadphase Scene/Proxy Handles */
PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);
PL_DECLARE_HANDLE(plBroadphaseProxyHandle);
PL_DECLARE_HANDLE(plCollisionWorldHandle);
/*
Create and Delete a Physics SDK
*/
extern plPhysicsSdkHandle plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc.
extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk);
/* Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);
extern plCollisionBroadphaseHandle plCreateSapBroadphase(btBroadphaseCallback beginCallback,btBroadphaseCallback endCallback);
extern void plDestroyBroadphase(plCollisionBroadphaseHandle bp);
extern plBroadphaseProxyHandle plCreateProxy(plCollisionBroadphaseHandle bp, void* clientData, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
extern void plDestroyProxy(plCollisionBroadphaseHandle bp, plBroadphaseProxyHandle proxyHandle);
extern void plSetBoundingBox(plBroadphaseProxyHandle proxyHandle, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
/* todo: add pair cache support with queries like add/remove/find pair */
extern plCollisionWorldHandle plCreateCollisionWorld(plPhysicsSdkHandle physicsSdk);
/* todo: add/remove objects */
/* Dynamics World */
extern plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk);
extern void plDeleteDynamicsWorld(plDynamicsWorldHandle world);
extern void plStepSimulation(plDynamicsWorldHandle, plReal timeStep);
extern void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
extern void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
/* Rigid Body */
extern plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape );
extern void plDeleteRigidBody(plRigidBodyHandle body);
/* Collision Shape definition */
extern plCollisionShapeHandle plNewSphereShape(plReal radius);
extern plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z);
extern plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewConeShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCompoundShape();
extern void plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
extern void plDeleteShape(plCollisionShapeHandle shape);
/* Convex Meshes */
extern plCollisionShapeHandle plNewConvexHullShape();
extern void plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);
/* Concave static triangle meshes */
extern plMeshInterfaceHandle plNewMeshInterface();
extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
extern void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling);
/* SOLID has Response Callback/Table/Management */
/* PhysX has Triggers, User Callbacks and filtering */
/* ODE has the typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); */
/* typedef void plUpdatedPositionCallback(void* userData, plRigidBodyHandle rbHandle, plVector3 pos); */
/* typedef void plUpdatedOrientationCallback(void* userData, plRigidBodyHandle rbHandle, plQuaternion orientation); */
/* get world transform */
extern void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
extern void plGetPosition(plRigidBodyHandle object,plVector3 position);
extern void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation);
/* set world transform (position/orientation) */
extern void plSetPosition(plRigidBodyHandle object, const plVector3 position);
extern void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation);
extern void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient);
typedef struct plRayCastResult {
plRigidBodyHandle m_body;
plCollisionShapeHandle m_shape;
plVector3 m_positionWorld;
plVector3 m_normalWorld;
} plRayCastResult;
extern int plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plRayCastResult res);
/* Sweep API */
/* extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); */
/* Continuous Collision Detection API */
// needed for source/blender/blenkernel/intern/collision.c
double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
#ifdef __cplusplus
}
#endif
#endif //BULLET_C_API_H

View File

@@ -21,640 +21,18 @@
#include <assert.h>
#ifdef DEBUG_BROADPHASE
#include <stdio.h>
void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality)
btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache)
:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache)
{
int numEdges = m_pHandles[0].m_maxEdges[axis];
printf("SAP Axis %d, numEdges=%d\n",axis,numEdges);
int i;
for (i=0;i<numEdges+1;i++)
{
Edge* pEdge = m_pEdges[axis] + i;
Handle* pHandlePrev = getHandle(pEdge->m_handle);
int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis];
char beginOrEnd;
beginOrEnd=pEdge->IsMax()?'E':'B';
printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex);
}
if (checkCardinality)
assert(numEdges == m_numHandles*2+1);
}
#endif //DEBUG_BROADPHASE
btBroadphaseProxy* btAxisSweep3::createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask)
{
(void)shapeType;
BP_FP_INT_TYPE handleId = addHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask);
Handle* handle = getHandle(handleId);
return handle;
}
void btAxisSweep3::destroyProxy(btBroadphaseProxy* proxy)
{
Handle* handle = static_cast<Handle*>(proxy);
removeHandle(handle->m_handleId);
}
void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax)
{
Handle* handle = static_cast<Handle*>(proxy);
updateHandle(handle->m_handleId,aabbMin,aabbMax);
}
btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles)
:btOverlappingPairCache()
{
m_invalidPair = 0;
//assert(bounds.HasVolume());
// 1 handle is reserved as sentinel
btAssert(maxHandles > 1 && maxHandles < BP_MAX_HANDLES);
// init bounds
m_worldAabbMin = worldAabbMin;
m_worldAabbMax = worldAabbMax;
btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin;
BP_FP_INT_TYPE maxInt = BP_HANDLE_SENTINEL;
m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize;
// allocate handles buffer and put all handles on free list
m_pHandles = new Handle[maxHandles];
m_maxHandles = maxHandles;
m_numHandles = 0;
// handle 0 is reserved as the null index, and is also used as the sentinel
m_firstFreeHandle = 1;
{
for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++)
m_pHandles[i].SetNextFree(i + 1);
m_pHandles[maxHandles - 1].SetNextFree(0);
}
{
// allocate edge buffers
for (int i = 0; i < 3; i++)
m_pEdges[i] = new Edge[maxHandles * 2];
}
//removed overlap management
// make boundary sentinels
m_pHandles[0].m_clientObject = 0;
for (int axis = 0; axis < 3; axis++)
{
m_pHandles[0].m_minEdges[axis] = 0;
m_pHandles[0].m_maxEdges[axis] = 1;
m_pEdges[axis][0].m_pos = 0;
m_pEdges[axis][0].m_handle = 0;
m_pEdges[axis][1].m_pos = BP_HANDLE_SENTINEL;
m_pEdges[axis][1].m_handle = 0;
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
btAssert(maxHandles > 1 && maxHandles < 32767);
}
btAxisSweep3::~btAxisSweep3()
bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache )
:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache)
{
for (int i = 2; i >= 0; i--)
delete[] m_pEdges[i];
delete[] m_pHandles;
}
void btAxisSweep3::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
{
btPoint3 clampedPoint(point);
clampedPoint.setMax(m_worldAabbMin);
clampedPoint.setMin(m_worldAabbMax);
btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & BP_HANDLE_MASK) | isMax);
out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & BP_HANDLE_MASK) | isMax);
out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & BP_HANDLE_MASK) | isMax);
}
BP_FP_INT_TYPE btAxisSweep3::allocHandle()
{
assert(m_firstFreeHandle);
BP_FP_INT_TYPE handle = m_firstFreeHandle;
m_firstFreeHandle = getHandle(handle)->GetNextFree();
m_numHandles++;
return handle;
}
void btAxisSweep3::freeHandle(BP_FP_INT_TYPE handle)
{
assert(handle > 0 && handle < m_maxHandles);
getHandle(handle)->SetNextFree(m_firstFreeHandle);
m_firstFreeHandle = handle;
m_numHandles--;
}
BP_FP_INT_TYPE btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask)
{
// quantize the bounds
BP_FP_INT_TYPE min[3], max[3];
quantize(min, aabbMin, 0);
quantize(max, aabbMax, 1);
// allocate a handle
BP_FP_INT_TYPE handle = allocHandle();
assert(handle!= 0xcdcd);
Handle* pHandle = getHandle(handle);
pHandle->m_handleId = handle;
//pHandle->m_pOverlaps = 0;
pHandle->m_clientObject = pOwner;
pHandle->m_collisionFilterGroup = collisionFilterGroup;
pHandle->m_collisionFilterMask = collisionFilterMask;
// compute current limit of edge arrays
BP_FP_INT_TYPE limit = m_numHandles * 2;
// insert new edges just inside the max boundary edge
for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++)
{
m_pHandles[0].m_maxEdges[axis] += 2;
m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
m_pEdges[axis][limit - 1].m_pos = min[axis];
m_pEdges[axis][limit - 1].m_handle = handle;
m_pEdges[axis][limit].m_pos = max[axis];
m_pEdges[axis][limit].m_handle = handle;
pHandle->m_minEdges[axis] = limit - 1;
pHandle->m_maxEdges[axis] = limit;
}
// now sort the new edges to their correct position
sortMinDown(0, pHandle->m_minEdges[0], false);
sortMaxDown(0, pHandle->m_maxEdges[0], false);
sortMinDown(1, pHandle->m_minEdges[1], false);
sortMaxDown(1, pHandle->m_maxEdges[1], false);
sortMinDown(2, pHandle->m_minEdges[2], true);
sortMaxDown(2, pHandle->m_maxEdges[2], true);
return handle;
}
void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle)
{
Handle* pHandle = getHandle(handle);
//explicitly remove the pairs containing the proxy
//we could do it also in the sortMinUp (passing true)
//todo: compare performance
removeOverlappingPairsContainingProxy(pHandle);
// compute current limit of edge arrays
int limit = m_numHandles * 2;
int axis;
for (axis = 0;axis<3;axis++)
{
m_pHandles[0].m_maxEdges[axis] -= 2;
}
// remove the edges by sorting them up to the end of the list
for ( axis = 0; axis < 3; axis++)
{
Edge* pEdges = m_pEdges[axis];
BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis];
pEdges[max].m_pos = BP_HANDLE_SENTINEL;
sortMaxUp(axis,max,false);
BP_FP_INT_TYPE i = pHandle->m_minEdges[axis];
pEdges[i].m_pos = BP_HANDLE_SENTINEL;
sortMinUp(axis,i,false);
pEdges[limit-1].m_handle = 0;
pEdges[limit-1].m_pos = BP_HANDLE_SENTINEL;
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis,false);
#endif //DEBUG_BROADPHASE
}
// free the handle
freeHandle(handle);
}
extern int gOverlappingPairs;
void btAxisSweep3::refreshOverlappingPairs()
{
}
void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback)
{
//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
m_overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
//remove the 'invalid' ones
#ifdef USE_POPBACK_REMOVAL
while (m_invalidPair>0)
{
m_invalidPair--;
m_overlappingPairArray.pop_back();
}
#else
m_overlappingPairArray.resize(m_overlappingPairArray.size() - m_invalidPair);
m_invalidPair = 0;
#endif
int i;
btBroadphasePair previousPair;
previousPair.m_pProxy0 = 0;
previousPair.m_pProxy1 = 0;
previousPair.m_algorithm = 0;
for (i=0;i<m_overlappingPairArray.size();i++)
{
btBroadphasePair& pair = m_overlappingPairArray[i];
bool isDuplicate = (pair == previousPair);
previousPair = pair;
bool needsRemoval = false;
if (!isDuplicate)
{
bool hasOverlap = testOverlap(pair.m_pProxy0,pair.m_pProxy1);
if (hasOverlap)
{
needsRemoval = callback->processOverlap(pair);
} else
{
needsRemoval = true;
}
} else
{
//remove duplicate
needsRemoval = true;
//should have no algorithm
btAssert(!pair.m_algorithm);
}
if (needsRemoval)
{
cleanOverlappingPair(pair);
// m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
// m_overlappingPairArray.pop_back();
pair.m_pProxy0 = 0;
pair.m_pProxy1 = 0;
m_invalidPair++;
gOverlappingPairs--;
}
}
}
bool btAxisSweep3::testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
const Handle* pHandleA = static_cast<Handle*>(proxy0);
const Handle* pHandleB = static_cast<Handle*>(proxy1);
//optimization 1: check the array index (memory address), instead of the m_pos
for (int axis = 0; axis < 3; axis++)
{
if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] ||
pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis])
{
return false;
}
}
return true;
}
bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB)
{
//optimization 1: check the array index (memory address), instead of the m_pos
for (int axis = 0; axis < 3; axis++)
{
if (axis != ignoreAxis)
{
if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] ||
pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis])
{
return false;
}
}
}
//optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization)
/*for (int axis = 0; axis < 3; axis++)
{
if (m_pEdges[axis][pHandleA->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleB->m_minEdges[axis]].m_pos ||
m_pEdges[axis][pHandleB->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleA->m_minEdges[axis]].m_pos)
{
return false;
}
}
*/
return true;
}
void btAxisSweep3::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax)
{
// assert(bounds.IsFinite());
//assert(bounds.HasVolume());
Handle* pHandle = getHandle(handle);
// quantize the new bounds
BP_FP_INT_TYPE min[3], max[3];
quantize(min, aabbMin, 0);
quantize(max, aabbMax, 1);
// update changed edges
for (int axis = 0; axis < 3; axis++)
{
BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis];
BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis];
int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
m_pEdges[axis][emin].m_pos = min[axis];
m_pEdges[axis][emax].m_pos = max[axis];
// expand (only adds overlaps)
if (dmin < 0)
sortMinDown(axis, emin);
if (dmax > 0)
sortMaxUp(axis, emax);
// shrink (only removes overlaps)
if (dmin > 0)
sortMinUp(axis, emin);
if (dmax < 0)
sortMaxDown(axis, emax);
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
}
// sorting a min edge downwards can only ever *add* overlaps
void btAxisSweep3::sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pPrev = pEdge - 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pEdge->m_pos < pPrev->m_pos)
{
Handle* pHandlePrev = getHandle(pPrev->m_handle);
if (pPrev->IsMax())
{
// if previous edge is a maximum check the bounds and add an overlap if necessary
if (updateOverlaps && testOverlap(axis,pHandleEdge, pHandlePrev))
{
addOverlappingPair(pHandleEdge,pHandlePrev);
//AddOverlap(pEdge->m_handle, pPrev->m_handle);
}
// update edge reference in other handle
pHandlePrev->m_maxEdges[axis]++;
}
else
pHandlePrev->m_minEdges[axis]++;
pHandleEdge->m_minEdges[axis]--;
// swap the edges
Edge swap = *pEdge;
*pEdge = *pPrev;
*pPrev = swap;
// decrement
pEdge--;
pPrev--;
}
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
// sorting a min edge upwards can only ever *remove* overlaps
void btAxisSweep3::sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pNext = pEdge + 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
{
Handle* pHandleNext = getHandle(pNext->m_handle);
if (pNext->IsMax())
{
// if next edge is maximum remove any overlap between the two handles
if (updateOverlaps)
{
/*
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pNext->m_handle);
btBroadphasePair tmpPair(*handle0,*handle1);
removeOverlappingPair(tmpPair);
*/
}
// update edge reference in other handle
pHandleNext->m_maxEdges[axis]--;
}
else
pHandleNext->m_minEdges[axis]--;
pHandleEdge->m_minEdges[axis]++;
// swap the edges
Edge swap = *pEdge;
*pEdge = *pNext;
*pNext = swap;
// increment
pEdge++;
pNext++;
}
}
// sorting a max edge downwards can only ever *remove* overlaps
void btAxisSweep3::sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pPrev = pEdge - 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pEdge->m_pos < pPrev->m_pos)
{
Handle* pHandlePrev = getHandle(pPrev->m_handle);
if (!pPrev->IsMax())
{
// if previous edge was a minimum remove any overlap between the two handles
if (updateOverlaps)
{
//this is done during the overlappingpairarray iteration/narrowphase collision
/*
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pPrev->m_handle);
btBroadphasePair* pair = findPair(handle0,handle1);
//assert(pair);
if (pair)
{
removeOverlappingPair(*pair);
}
*/
}
// update edge reference in other handle
pHandlePrev->m_minEdges[axis]++;;
}
else
pHandlePrev->m_maxEdges[axis]++;
pHandleEdge->m_maxEdges[axis]--;
// swap the edges
Edge swap = *pEdge;
*pEdge = *pPrev;
*pPrev = swap;
// decrement
pEdge--;
pPrev--;
}
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
// sorting a max edge upwards can only ever *add* overlaps
void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pNext = pEdge + 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
{
Handle* pHandleNext = getHandle(pNext->m_handle);
if (!pNext->IsMax())
{
// if next edge is a minimum check the bounds and add an overlap if necessary
if (updateOverlaps && testOverlap(axis, pHandleEdge, pHandleNext))
{
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pNext->m_handle);
addOverlappingPair(handle0,handle1);
}
// update edge reference in other handle
pHandleNext->m_minEdges[axis]--;
}
else
pHandleNext->m_maxEdges[axis]--;
pHandleEdge->m_maxEdges[axis]++;
// swap the edges
Edge swap = *pEdge;
*pEdge = *pNext;
*pNext = swap;
// increment
pEdge++;
pNext++;
}
// 1 handle is reserved as sentinel
btAssert(maxHandles > 1 && maxHandles < 2147483647);
}

View File

@@ -19,34 +19,26 @@
#ifndef AXIS_SWEEP_3_H
#define AXIS_SWEEP_3_H
#include "../../LinearMath/btPoint3.h"
#include "../../LinearMath/btVector3.h"
#include "LinearMath/btPoint3.h"
#include "LinearMath/btVector3.h"
#include "btOverlappingPairCache.h"
#include "btBroadphaseInterface.h"
#include "btBroadphaseProxy.h"
//Enable BP_USE_FIXEDPOINT_INT_32 if you need more then 32767 objects
//#define BP_USE_FIXEDPOINT_INT_32 1
#ifdef BP_USE_FIXEDPOINT_INT_32
#define BP_FP_INT_TYPE unsigned int
#define BP_MAX_HANDLES 1500000 //arbitrary maximum number of handles
#define BP_HANDLE_SENTINEL 0x7fffffff
#define BP_HANDLE_MASK 0xfffffffe
#else
#define BP_FP_INT_TYPE unsigned short int
#define BP_MAX_HANDLES 32767
#define BP_HANDLE_SENTINEL 0xffff
#define BP_HANDLE_MASK 0xfffe
#endif //BP_USE_FIXEDPOINT_INT_32
#include "btOverlappingPairCallback.h"
//#define DEBUG_BROADPHASE 1
#define USE_OVERLAP_TEST_ON_REMOVES 1
/// btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase.
/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using integer coordinates instead of floats.
/// The testOverlap check is optimized to check the array index, rather then the actual AABB coordinates/pos
class btAxisSweep3 : public btOverlappingPairCache
/// The internal templace class btAxisSweep3Internal implements the sweep and prune broadphase.
/// It uses quantized integers to represent the begin and end points for each of the 3 axis.
/// Dont use this class directly, use btAxisSweep3 or bt32BitAxisSweep3 instead.
template <typename BP_FP_INT_TYPE>
class btAxisSweep3Internal : public btBroadphaseInterface
{
protected:
BP_FP_INT_TYPE m_bpHandleMask;
BP_FP_INT_TYPE m_handleSentinel;
public:
@@ -57,47 +49,57 @@ public:
BP_FP_INT_TYPE m_pos; // low bit is min/max
BP_FP_INT_TYPE m_handle;
BP_FP_INT_TYPE IsMax() const {return m_pos & 1;}
BP_FP_INT_TYPE IsMax() const {return static_cast<BP_FP_INT_TYPE>(m_pos & 1);}
};
public:
class Handle : public btBroadphaseProxy
class Handle : public btBroadphaseProxy
{
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
// indexes into the edge arrays
BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
BP_FP_INT_TYPE m_handleId;
// BP_FP_INT_TYPE m_uniqueId;
BP_FP_INT_TYPE m_pad;
//void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
inline void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
inline BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];}
SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];}
}; // 24 bytes + 24 for Edge structures = 44 bytes total per entry
private:
protected:
btPoint3 m_worldAabbMin; // overall system bounds
btPoint3 m_worldAabbMax; // overall system bounds
btVector3 m_quantize; // scaling factor for quantization
BP_FP_INT_TYPE m_numHandles; // number of active handles
int m_maxHandles; // max number of handles
BP_FP_INT_TYPE m_maxHandles; // max number of handles
Handle* m_pHandles; // handles pool
BP_FP_INT_TYPE m_firstFreeHandle; // free handles list
Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
void* m_pEdgesRawPtr[3];
int m_invalidPair;
btOverlappingPairCache* m_pairCache;
///btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache.
btOverlappingPairCallback* m_userPairCallback;
bool m_ownsPairCache;
int m_invalidPair;
// allocation/deallocation
BP_FP_INT_TYPE allocHandle();
void freeHandle(BP_FP_INT_TYPE handle);
bool testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB);
bool testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1);
#ifdef DEBUG_BROADPHASE
void debugPrintAxis(int axis,bool checkCardinality=true);
@@ -108,29 +110,803 @@ private:
void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;
void sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
void sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
void sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
void sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
public:
btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles = 16384);
virtual ~btAxisSweep3();
virtual void refreshOverlappingPairs();
btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0);
virtual ~btAxisSweep3Internal();
BP_FP_INT_TYPE getNumHandles() const
{
return m_numHandles;
}
virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask);
void removeHandle(BP_FP_INT_TYPE handle);
void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax);
inline Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher);
void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher);
SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
void processAllOverlappingPairs(btOverlapCallback* callback);
//Broadphase Interface
virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask);
virtual void destroyProxy(btBroadphaseProxy* proxy);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax);
bool testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
btOverlappingPairCache* getOverlappingPairCache()
{
return m_pairCache;
}
const btOverlappingPairCache* getOverlappingPairCache() const
{
return m_pairCache;
}
void setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback)
{
m_userPairCallback = pairCallback;
}
const btOverlappingPairCallback* getOverlappingPairUserCallback() const
{
return m_userPairCallback;
}
///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
///will add some transform later
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
{
aabbMin = m_worldAabbMin;
aabbMax = m_worldAabbMax;
}
virtual void printStats()
{
/* printf("btAxisSweep3.h\n");
printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles);
printf("aabbMin=%f,%f,%f,aabbMax=%f,%f,%f\n",m_worldAabbMin.getX(),m_worldAabbMin.getY(),m_worldAabbMin.getZ(),
m_worldAabbMax.getX(),m_worldAabbMax.getY(),m_worldAabbMax.getZ());
*/
}
};
////////////////////////////////////////////////////////////////////
#ifdef DEBUG_BROADPHASE
#include <stdio.h>
template <typename BP_FP_INT_TYPE>
void btAxisSweep3<BP_FP_INT_TYPE>::debugPrintAxis(int axis, bool checkCardinality)
{
int numEdges = m_pHandles[0].m_maxEdges[axis];
printf("SAP Axis %d, numEdges=%d\n",axis,numEdges);
int i;
for (i=0;i<numEdges+1;i++)
{
Edge* pEdge = m_pEdges[axis] + i;
Handle* pHandlePrev = getHandle(pEdge->m_handle);
int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis];
char beginOrEnd;
beginOrEnd=pEdge->IsMax()?'E':'B';
printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex);
}
if (checkCardinality)
assert(numEdges == m_numHandles*2+1);
}
#endif //DEBUG_BROADPHASE
template <typename BP_FP_INT_TYPE>
btBroadphaseProxy* btAxisSweep3Internal<BP_FP_INT_TYPE>::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
{
(void)shapeType;
BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,multiSapProxy);
Handle* handle = getHandle(handleId);
return handle;
}
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
{
Handle* handle = static_cast<Handle*>(proxy);
removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher);
}
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
{
Handle* handle = static_cast<Handle*>(proxy);
updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher);
}
template <typename BP_FP_INT_TYPE>
btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache )
:m_bpHandleMask(handleMask),
m_handleSentinel(handleSentinel),
m_pairCache(pairCache),
m_userPairCallback(0),
m_ownsPairCache(false),
m_invalidPair(0)
{
BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle
if (!m_pairCache)
{
void* ptr = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16);
m_pairCache = new(ptr) btHashedOverlappingPairCache();
m_ownsPairCache = true;
}
//assert(bounds.HasVolume());
// init bounds
m_worldAabbMin = worldAabbMin;
m_worldAabbMax = worldAabbMax;
btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin;
BP_FP_INT_TYPE maxInt = m_handleSentinel;
m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize;
// allocate handles buffer, using btAlignedAlloc, and put all handles on free list
m_pHandles = new Handle[maxHandles];
m_maxHandles = maxHandles;
m_numHandles = 0;
// handle 0 is reserved as the null index, and is also used as the sentinel
m_firstFreeHandle = 1;
{
for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++)
m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
m_pHandles[maxHandles - 1].SetNextFree(0);
}
{
// allocate edge buffers
for (int i = 0; i < 3; i++)
{
m_pEdgesRawPtr[i] = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16);
m_pEdges[i] = new(m_pEdgesRawPtr[i]) Edge[maxHandles * 2];
}
}
//removed overlap management
// make boundary sentinels
m_pHandles[0].m_clientObject = 0;
for (int axis = 0; axis < 3; axis++)
{
m_pHandles[0].m_minEdges[axis] = 0;
m_pHandles[0].m_maxEdges[axis] = 1;
m_pEdges[axis][0].m_pos = 0;
m_pEdges[axis][0].m_handle = 0;
m_pEdges[axis][1].m_pos = m_handleSentinel;
m_pEdges[axis][1].m_handle = 0;
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
}
template <typename BP_FP_INT_TYPE>
btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
{
for (int i = 2; i >= 0; i--)
{
btAlignedFree(m_pEdgesRawPtr[i]);
}
delete [] m_pHandles;
if (m_ownsPairCache)
{
m_pairCache->~btOverlappingPairCache();
btAlignedFree(m_pairCache);
}
}
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
{
btPoint3 clampedPoint(point);
clampedPoint.setMax(m_worldAabbMin);
clampedPoint.setMin(m_worldAabbMax);
btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax);
out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax);
out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax);
}
template <typename BP_FP_INT_TYPE>
BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
{
assert(m_firstFreeHandle);
BP_FP_INT_TYPE handle = m_firstFreeHandle;
m_firstFreeHandle = getHandle(handle)->GetNextFree();
m_numHandles++;
return handle;
}
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
{
assert(handle > 0 && handle < m_maxHandles);
getHandle(handle)->SetNextFree(m_firstFreeHandle);
m_firstFreeHandle = handle;
m_numHandles--;
}
template <typename BP_FP_INT_TYPE>
BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
{
// quantize the bounds
BP_FP_INT_TYPE min[3], max[3];
quantize(min, aabbMin, 0);
quantize(max, aabbMax, 1);
// allocate a handle
BP_FP_INT_TYPE handle = allocHandle();
Handle* pHandle = getHandle(handle);
pHandle->m_uniqueId = static_cast<int>(handle);
//pHandle->m_pOverlaps = 0;
pHandle->m_clientObject = pOwner;
pHandle->m_collisionFilterGroup = collisionFilterGroup;
pHandle->m_collisionFilterMask = collisionFilterMask;
pHandle->m_multiSapParentProxy = multiSapProxy;
// compute current limit of edge arrays
BP_FP_INT_TYPE limit = static_cast<BP_FP_INT_TYPE>(m_numHandles * 2);
// insert new edges just inside the max boundary edge
for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++)
{
m_pHandles[0].m_maxEdges[axis] += 2;
m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
m_pEdges[axis][limit - 1].m_pos = min[axis];
m_pEdges[axis][limit - 1].m_handle = handle;
m_pEdges[axis][limit].m_pos = max[axis];
m_pEdges[axis][limit].m_handle = handle;
pHandle->m_minEdges[axis] = static_cast<BP_FP_INT_TYPE>(limit - 1);
pHandle->m_maxEdges[axis] = limit;
}
// now sort the new edges to their correct position
sortMinDown(0, pHandle->m_minEdges[0], dispatcher,false);
sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher,false);
sortMinDown(1, pHandle->m_minEdges[1], dispatcher,false);
sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher,false);
sortMinDown(2, pHandle->m_minEdges[2], dispatcher,true);
sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher,true);
return handle;
}
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher)
{
Handle* pHandle = getHandle(handle);
//explicitly remove the pairs containing the proxy
//we could do it also in the sortMinUp (passing true)
//todo: compare performance
if (!m_pairCache->hasDeferredRemoval())
{
m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher);
}
// compute current limit of edge arrays
int limit = static_cast<int>(m_numHandles * 2);
int axis;
for (axis = 0;axis<3;axis++)
{
m_pHandles[0].m_maxEdges[axis] -= 2;
}
// remove the edges by sorting them up to the end of the list
for ( axis = 0; axis < 3; axis++)
{
Edge* pEdges = m_pEdges[axis];
BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis];
pEdges[max].m_pos = m_handleSentinel;
sortMaxUp(axis,max,dispatcher,false);
BP_FP_INT_TYPE i = pHandle->m_minEdges[axis];
pEdges[i].m_pos = m_handleSentinel;
sortMinUp(axis,i,dispatcher,false);
pEdges[limit-1].m_handle = 0;
pEdges[limit-1].m_pos = m_handleSentinel;
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis,false);
#endif //DEBUG_BROADPHASE
}
// free the handle
freeHandle(handle);
}
extern int gOverlappingPairs;
//#include <stdio.h>
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatcher* dispatcher)
{
if (m_pairCache->hasDeferredRemoval())
{
btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray();
//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
m_invalidPair = 0;
int i;
btBroadphasePair previousPair;
previousPair.m_pProxy0 = 0;
previousPair.m_pProxy1 = 0;
previousPair.m_algorithm = 0;
for (i=0;i<overlappingPairArray.size();i++)
{
btBroadphasePair& pair = overlappingPairArray[i];
bool isDuplicate = (pair == previousPair);
previousPair = pair;
bool needsRemoval = false;
if (!isDuplicate)
{
bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
if (hasOverlap)
{
needsRemoval = false;//callback->processOverlap(pair);
} else
{
needsRemoval = true;
}
} else
{
//remove duplicate
needsRemoval = true;
//should have no algorithm
btAssert(!pair.m_algorithm);
}
if (needsRemoval)
{
m_pairCache->cleanOverlappingPair(pair,dispatcher);
// m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
// m_overlappingPairArray.pop_back();
pair.m_pProxy0 = 0;
pair.m_pProxy1 = 0;
m_invalidPair++;
gOverlappingPairs--;
}
}
///if you don't like to skip the invalid pairs in the array, execute following code:
#define CLEAN_INVALID_PAIRS 1
#ifdef CLEAN_INVALID_PAIRS
//perform a sort, to sort 'invalid' pairs to the end
overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
m_invalidPair = 0;
#endif//CLEAN_INVALID_PAIRS
//printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
}
}
template <typename BP_FP_INT_TYPE>
bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
const Handle* pHandleA = static_cast<Handle*>(proxy0);
const Handle* pHandleB = static_cast<Handle*>(proxy1);
//optimization 1: check the array index (memory address), instead of the m_pos
for (int axis = 0; axis < 3; axis++)
{
if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] ||
pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis])
{
return false;
}
}
return true;
}
template <typename BP_FP_INT_TYPE>
bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1)
{
//optimization 1: check the array index (memory address), instead of the m_pos
if (pHandleA->m_maxEdges[axis0] < pHandleB->m_minEdges[axis0] ||
pHandleB->m_maxEdges[axis0] < pHandleA->m_minEdges[axis0] ||
pHandleA->m_maxEdges[axis1] < pHandleB->m_minEdges[axis1] ||
pHandleB->m_maxEdges[axis1] < pHandleA->m_minEdges[axis1])
{
return false;
}
return true;
}
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher)
{
// assert(bounds.IsFinite());
//assert(bounds.HasVolume());
Handle* pHandle = getHandle(handle);
// quantize the new bounds
BP_FP_INT_TYPE min[3], max[3];
quantize(min, aabbMin, 0);
quantize(max, aabbMax, 1);
// update changed edges
for (int axis = 0; axis < 3; axis++)
{
BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis];
BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis];
int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
m_pEdges[axis][emin].m_pos = min[axis];
m_pEdges[axis][emax].m_pos = max[axis];
// expand (only adds overlaps)
if (dmin < 0)
sortMinDown(axis, emin,dispatcher,true);
if (dmax > 0)
sortMaxUp(axis, emax,dispatcher,true);
// shrink (only removes overlaps)
if (dmin > 0)
sortMinUp(axis, emin,dispatcher,true);
if (dmax < 0)
sortMaxDown(axis, emax,dispatcher,true);
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
}
// sorting a min edge downwards can only ever *add* overlaps
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pPrev = pEdge - 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pEdge->m_pos < pPrev->m_pos)
{
Handle* pHandlePrev = getHandle(pPrev->m_handle);
if (pPrev->IsMax())
{
// if previous edge is a maximum check the bounds and add an overlap if necessary
const int axis1 = (1 << axis) & 3;
const int axis2 = (1 << axis1) & 3;
if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev,axis1,axis2))
{
m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev);
if (m_userPairCallback)
m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev);
//AddOverlap(pEdge->m_handle, pPrev->m_handle);
}
// update edge reference in other handle
pHandlePrev->m_maxEdges[axis]++;
}
else
pHandlePrev->m_minEdges[axis]++;
pHandleEdge->m_minEdges[axis]--;
// swap the edges
Edge swap = *pEdge;
*pEdge = *pPrev;
*pPrev = swap;
// decrement
pEdge--;
pPrev--;
}
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
// sorting a min edge upwards can only ever *remove* overlaps
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pNext = pEdge + 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
{
Handle* pHandleNext = getHandle(pNext->m_handle);
if (pNext->IsMax())
{
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pNext->m_handle);
const int axis1 = (1 << axis) & 3;
const int axis2 = (1 << axis1) & 3;
// if next edge is maximum remove any overlap between the two handles
if (updateOverlaps
#ifdef USE_OVERLAP_TEST_ON_REMOVES
&& testOverlap2D(handle0,handle1,axis1,axis2)
#endif //USE_OVERLAP_TEST_ON_REMOVES
)
{
m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher);
if (m_userPairCallback)
m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher);
}
// update edge reference in other handle
pHandleNext->m_maxEdges[axis]--;
}
else
pHandleNext->m_minEdges[axis]--;
pHandleEdge->m_minEdges[axis]++;
// swap the edges
Edge swap = *pEdge;
*pEdge = *pNext;
*pNext = swap;
// increment
pEdge++;
pNext++;
}
}
// sorting a max edge downwards can only ever *remove* overlaps
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pPrev = pEdge - 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pEdge->m_pos < pPrev->m_pos)
{
Handle* pHandlePrev = getHandle(pPrev->m_handle);
if (!pPrev->IsMax())
{
// if previous edge was a minimum remove any overlap between the two handles
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pPrev->m_handle);
const int axis1 = (1 << axis) & 3;
const int axis2 = (1 << axis1) & 3;
if (updateOverlaps
#ifdef USE_OVERLAP_TEST_ON_REMOVES
&& testOverlap2D(handle0,handle1,axis1,axis2)
#endif //USE_OVERLAP_TEST_ON_REMOVES
)
{
//this is done during the overlappingpairarray iteration/narrowphase collision
m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher);
if (m_userPairCallback)
m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher);
}
// update edge reference in other handle
pHandlePrev->m_minEdges[axis]++;;
}
else
pHandlePrev->m_maxEdges[axis]++;
pHandleEdge->m_maxEdges[axis]--;
// swap the edges
Edge swap = *pEdge;
*pEdge = *pPrev;
*pPrev = swap;
// decrement
pEdge--;
pPrev--;
}
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
// sorting a max edge upwards can only ever *add* overlaps
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pNext = pEdge + 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
{
Handle* pHandleNext = getHandle(pNext->m_handle);
const int axis1 = (1 << axis) & 3;
const int axis2 = (1 << axis1) & 3;
if (!pNext->IsMax())
{
// if next edge is a minimum check the bounds and add an overlap if necessary
if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext,axis1,axis2))
{
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pNext->m_handle);
m_pairCache->addOverlappingPair(handle0,handle1);
if (m_userPairCallback)
m_userPairCallback->addOverlappingPair(handle0,handle1);
}
// update edge reference in other handle
pHandleNext->m_minEdges[axis]--;
}
else
pHandleNext->m_maxEdges[axis]--;
pHandleEdge->m_maxEdges[axis]++;
// swap the edges
Edge swap = *pEdge;
*pEdge = *pNext;
*pNext = swap;
// increment
pEdge++;
pNext++;
}
}
////////////////////////////////////////////////////////////////////
/// The btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase.
/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using 16 bit integer coordinates instead of floats.
/// For large worlds and many objects, use bt32BitAxisSweep3 or btDbvtBroadphase instead. bt32BitAxisSweep3 has higher precision and allows more then 16384 objects at the cost of more memory and bit of performance.
class btAxisSweep3 : public btAxisSweep3Internal<unsigned short int>
{
public:
btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0);
};
/// The bt32BitAxisSweep3 allows higher precision quantization and more objects compared to the btAxisSweep3 sweep and prune.
/// This comes at the cost of more memory per handle, and a bit slower performance.
/// It uses arrays rather then lists for storage of the 3 axis.
class bt32BitAxisSweep3 : public btAxisSweep3Internal<unsigned int>
{
public:
bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0);
};

View File

@@ -20,20 +20,34 @@ subject to the following restrictions:
struct btDispatcherInfo;
class btDispatcher;
struct btBroadphaseProxy;
#include "../../LinearMath/btVector3.h"
#include "btBroadphaseProxy.h"
class btOverlappingPairCache;
///BroadphaseInterface for aabb-overlapping object pairs
#include "LinearMath/btVector3.h"
///The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
///Some implementations for this broadphase interface include btAxisSweep3, bt32BitAxisSweep3 and btDbvtBroadphase.
///The actual overlapping pair management, storage, adding and removing of pairs is dealt by the btOverlappingPairCache class.
class btBroadphaseInterface
{
public:
virtual ~btBroadphaseInterface() {}
virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) =0;
virtual void destroyProxy(btBroadphaseProxy* proxy)=0;
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax)=0;
virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy)=0;
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) =0;
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0;
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0;
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0;
virtual btOverlappingPairCache* getOverlappingPairCache()=0;
virtual const btOverlappingPairCache* getOverlappingPairCache() const =0;
///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
///will add some transform later
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0;
virtual void printStats() = 0;
};

View File

@@ -16,7 +16,8 @@ subject to the following restrictions:
#ifndef BROADPHASE_PROXY_H
#define BROADPHASE_PROXY_H
#include "../../LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
#include "LinearMath/btAlignedAllocator.h"
/// btDispatcher uses these types
@@ -38,6 +39,7 @@ IMPLICIT_CONVEX_SHAPES_START_HERE,
CONE_SHAPE_PROXYTYPE,
CONVEX_SHAPE_PROXYTYPE,
CYLINDER_SHAPE_PROXYTYPE,
UNIFORM_SCALING_SHAPE_PROXYTYPE,
MINKOWSKI_SUM_SHAPE_PROXYTYPE,
MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
//concave shapes
@@ -50,6 +52,8 @@ CONCAVE_SHAPES_START_HERE,
TERRAIN_SHAPE_PROXYTYPE,
///Used for GIMPACT Trimesh integration
GIMPACT_SHAPE_PROXYTYPE,
///Multimaterial mesh
MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE,
EMPTY_SHAPE_PROXYTYPE,
STATIC_PLANE_PROXYTYPE,
@@ -57,13 +61,18 @@ CONCAVE_SHAPES_END_HERE,
COMPOUND_SHAPE_PROXYTYPE,
SOFTBODY_SHAPE_PROXYTYPE,
MAX_BROADPHASE_COLLISION_TYPES
};
///btBroadphaseProxy
struct btBroadphaseProxy
///The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
///It stores collision shape type information, collision filter information and a client object, typically a btCollisionObject or btRigidBody.
ATTRIBUTE_ALIGNED16(struct) btBroadphaseProxy
{
BT_DECLARE_ALIGNED_ALLOCATOR();
///optional filtering to cull potential collisions
enum CollisionFilterGroups
@@ -73,44 +82,60 @@ struct btBroadphaseProxy
KinematicFilter = 4,
DebrisFilter = 8,
SensorTrigger = 16,
AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
};
//Usually the client btCollisionObject or Rigidbody class
void* m_clientObject;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
//used for memory pools
btBroadphaseProxy() :m_clientObject(0){}
void* m_multiSapParentProxy;
btBroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask)
int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
SIMD_FORCE_INLINE int getUid() const
{
return m_uniqueId;
}
//used for memory pools
btBroadphaseProxy() :m_clientObject(0),m_multiSapParentProxy(0)
{
}
btBroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
:m_clientObject(userPtr),
m_collisionFilterGroup(collisionFilterGroup),
m_collisionFilterMask(collisionFilterMask)
{
m_multiSapParentProxy = multiSapParentProxy;
}
static inline bool isPolyhedral(int proxyType)
static SIMD_FORCE_INLINE bool isPolyhedral(int proxyType)
{
return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE);
}
static inline bool isConvex(int proxyType)
static SIMD_FORCE_INLINE bool isConvex(int proxyType)
{
return (proxyType < CONCAVE_SHAPES_START_HERE);
}
static inline bool isConcave(int proxyType)
static SIMD_FORCE_INLINE bool isConcave(int proxyType)
{
return ((proxyType > CONCAVE_SHAPES_START_HERE) &&
(proxyType < CONCAVE_SHAPES_END_HERE));
}
static inline bool isCompound(int proxyType)
static SIMD_FORCE_INLINE bool isCompound(int proxyType)
{
return (proxyType == COMPOUND_SHAPE_PROXYTYPE);
}
static inline bool isInfinite(int proxyType)
static SIMD_FORCE_INLINE bool isInfinite(int proxyType)
{
return (proxyType == STATIC_PLANE_PROXYTYPE);
}
@@ -124,8 +149,9 @@ struct btBroadphaseProxy;
/// contains a pair of aabb-overlapping objects
struct btBroadphasePair
///The btBroadphasePair class contains a pair of aabb-overlapping objects.
///A btDispatcher can search a btCollisionAlgorithm that performs exact/narrowphase collision detection on the actual collision shapes.
ATTRIBUTE_ALIGNED16(struct) btBroadphasePair
{
btBroadphasePair ()
:
@@ -136,6 +162,8 @@ struct btBroadphasePair
{
}
BT_DECLARE_ALIGNED_ALLOCATOR();
btBroadphasePair(const btBroadphasePair& other)
: m_pProxy0(other.m_pProxy0),
m_pProxy1(other.m_pProxy1),
@@ -181,6 +209,7 @@ SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePa
*/
class btBroadphasePairSortPredicate
{
public:

View File

@@ -18,6 +18,6 @@ subject to the following restrictions:
btCollisionAlgorithm::btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
{
m_dispatcher = ci.m_dispatcher;
m_dispatcher = ci.m_dispatcher1;
}

View File

@@ -16,7 +16,8 @@ subject to the following restrictions:
#ifndef COLLISION_ALGORITHM_H
#define COLLISION_ALGORITHM_H
#include "../../LinearMath/btScalar.h"
#include "LinearMath/btScalar.h"
#include "LinearMath/btAlignedObjectArray.h"
struct btBroadphaseProxy;
class btDispatcher;
@@ -25,21 +26,22 @@ class btCollisionObject;
struct btDispatcherInfo;
class btPersistentManifold;
typedef btAlignedObjectArray<btPersistentManifold*> btManifoldArray;
struct btCollisionAlgorithmConstructionInfo
{
btCollisionAlgorithmConstructionInfo()
:m_dispatcher(0),
:m_dispatcher1(0),
m_manifold(0)
{
}
btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp)
:m_dispatcher(dispatcher)
:m_dispatcher1(dispatcher)
{
(void)temp;
}
btDispatcher* m_dispatcher;
btDispatcher* m_dispatcher1;
btPersistentManifold* m_manifold;
int getDispatcherId();
@@ -71,6 +73,7 @@ public:
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
virtual void getAllContactManifolds(btManifoldArray& manifoldArray) = 0;
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,547 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
///btDbvtBroadphase implementation by Nathanael Presson
#include "btDbvtBroadphase.h"
//
// Profiling
//
#if DBVT_BP_PROFILE||DBVT_BP_ENABLE_BENCHMARK
#include <stdio.h>
#endif
#if DBVT_BP_PROFILE
struct ProfileScope
{
__forceinline ProfileScope(btClock& clock,unsigned long& value) :
m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())
{
}
__forceinline ~ProfileScope()
{
(*m_value)+=m_clock->getTimeMicroseconds()-m_base;
}
btClock* m_clock;
unsigned long* m_value;
unsigned long m_base;
};
#define SPC(_value_) ProfileScope spc_scope(m_clock,_value_)
#else
#define SPC(_value_)
#endif
//
// Helpers
//
//
template <typename T>
static inline void listappend(T* item,T*& list)
{
item->links[0]=0;
item->links[1]=list;
if(list) list->links[0]=item;
list=item;
}
//
template <typename T>
static inline void listremove(T* item,T*& list)
{
if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
if(item->links[1]) item->links[1]->links[0]=item->links[0];
}
//
template <typename T>
static inline int listcount(T* root)
{
int n=0;
while(root) { ++n;root=root->links[1]; }
return(n);
}
//
template <typename T>
static inline void clear(T& value)
{
static const struct ZeroDummy : T {} zerodummy;
value=zerodummy;
}
//
// Colliders
//
/* Tree collider */
struct btDbvtTreeCollider : btDbvt::ICollide
{
btDbvtBroadphase* pbp;
btDbvtProxy* proxy;
btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
void Process(const btDbvtNode* na,const btDbvtNode* nb)
{
if(na!=nb)
{
btDbvtProxy* pa=(btDbvtProxy*)na->data;
btDbvtProxy* pb=(btDbvtProxy*)nb->data;
#if DBVT_BP_SORTPAIRS
if(pa>pb) btSwap(pa,pb);
#endif
pbp->m_paircache->addOverlappingPair(pa,pb);
++pbp->m_newpairs;
}
}
void Process(const btDbvtNode* n)
{
Process(n,proxy->leaf);
}
};
//
// btDbvtBroadphase
//
//
btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
{
m_deferedcollide = true;//false;
m_needcleanup = true;
m_releasepaircache = (paircache!=0)?false:true;
m_prediction = 1/(btScalar)2;
m_stageCurrent = 0;
m_fixedleft = 0;
m_fupdates = 1;
m_dupdates = 0;
m_cupdates = 10;
m_newpairs = 1;
m_updates_call = 0;
m_updates_done = 0;
m_updates_ratio = 0;
m_paircache = paircache?
paircache :
new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
m_gid = 0;
m_pid = 0;
m_cid = 0;
for(int i=0;i<=STAGECOUNT;++i)
{
m_stageRoots[i]=0;
}
#if DBVT_BP_PROFILE
clear(m_profiling);
#endif
}
//
btDbvtBroadphase::~btDbvtBroadphase()
{
if(m_releasepaircache)
{
m_paircache->~btOverlappingPairCache();
btAlignedFree(m_paircache);
}
}
//
btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin,
const btVector3& aabbMax,
int /*shapeType*/,
void* userPtr,
short int collisionFilterGroup,
short int collisionFilterMask,
btDispatcher* dispatcher,
void* /*multiSapProxy*/)
{
btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( userPtr,
collisionFilterGroup,
collisionFilterMask);
proxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
proxy->stage = m_stageCurrent;
proxy->m_uniqueId = ++m_gid;
proxy->leaf = m_sets[0].insert(proxy->aabb,proxy);
listappend(proxy,m_stageRoots[m_stageCurrent]);
if(!m_deferedcollide)
{
btDbvtTreeCollider collider(this);
collider.proxy=proxy;
btDbvt::collideTV(m_sets[0].m_root,proxy->aabb,collider);
}
return(proxy);
}
//
void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy,
btDispatcher* dispatcher)
{
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
if(proxy->stage==STAGECOUNT)
m_sets[1].remove(proxy->leaf);
else
m_sets[0].remove(proxy->leaf);
listremove(proxy,m_stageRoots[proxy->stage]);
m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
btAlignedFree(proxy);
m_needcleanup=true;
}
//
void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy,
const btVector3& aabbMin,
const btVector3& aabbMax,
btDispatcher* /*dispatcher*/)
{
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
#if DBVT_BP_PREVENTFALSEUPDATE
if(NotEqual(aabb,proxy->leaf->volume))
#endif
{
bool docollide=false;
if(proxy->stage==STAGECOUNT)
{/* fixed -> dynamic set */
m_sets[1].remove(proxy->leaf);
proxy->leaf=m_sets[0].insert(aabb,proxy);
docollide=true;
}
else
{/* dynamic set */
++m_updates_call;
if(Intersect(proxy->leaf->volume,aabb))
{/* Moving */
const btVector3 delta=aabbMin-proxy->aabb.Mins();
btVector3 velocity(aabb.Extents()*m_prediction);
if(delta[0]<0) velocity[0]=-velocity[0];
if(delta[1]<0) velocity[1]=-velocity[1];
if(delta[2]<0) velocity[2]=-velocity[2];
if (
#ifdef DBVT_BP_MARGIN
m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN)
#else
m_sets[0].update(proxy->leaf,aabb,velocity)
#endif
)
{
++m_updates_done;
docollide=true;
}
}
else
{/* Teleporting */
m_sets[0].update(proxy->leaf,aabb);
++m_updates_done;
docollide=true;
}
}
listremove(proxy,m_stageRoots[proxy->stage]);
proxy->aabb = aabb;
proxy->stage = m_stageCurrent;
listappend(proxy,m_stageRoots[m_stageCurrent]);
if(docollide)
{
m_needcleanup=true;
if(!m_deferedcollide)
{
btDbvtTreeCollider collider(this);
btDbvt::collideTT(m_sets[1].m_root,proxy->leaf,collider);
btDbvt::collideTT(m_sets[0].m_root,proxy->leaf,collider);
}
}
}
}
//
void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
{
collide(dispatcher);
#if DBVT_BP_PROFILE
if(0==(m_pid%DBVT_BP_PROFILING_RATE))
{
printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs());
unsigned int total=m_profiling.m_total;
if(total<=0) total=1;
printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE);
const unsigned long sum=m_profiling.m_ddcollide+
m_profiling.m_fdcollide+
m_profiling.m_cleanup;
printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE));
clear(m_profiling);
m_clock.reset();
}
#endif
}
//
void btDbvtBroadphase::collide(btDispatcher* dispatcher)
{
SPC(m_profiling.m_total);
/* optimize */
m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100);
if(m_fixedleft)
{
const int count=1+(m_sets[1].m_leaves*m_fupdates)/100;
m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100);
m_fixedleft=btMax<int>(0,m_fixedleft-count);
}
/* dynamic -> fixed set */
m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
btDbvtProxy* current=m_stageRoots[m_stageCurrent];
if(current)
{
btDbvtTreeCollider collider(this);
do {
btDbvtProxy* next=current->links[1];
listremove(current,m_stageRoots[current->stage]);
listappend(current,m_stageRoots[STAGECOUNT]);
#if DBVT_BP_ACCURATESLEEPING
m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher);
collider.proxy=current;
btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider);
btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider);
#endif
m_sets[0].remove(current->leaf);
current->leaf = m_sets[1].insert(current->aabb,current);
current->stage = STAGECOUNT;
current = next;
} while(current);
m_fixedleft=m_sets[1].m_leaves;
m_needcleanup=true;
}
/* collide dynamics */
{
btDbvtTreeCollider collider(this);
if(m_deferedcollide)
{
SPC(m_profiling.m_fdcollide);
btDbvt::collideTT(m_sets[0].m_root,m_sets[1].m_root,collider);
}
if(m_deferedcollide)
{
SPC(m_profiling.m_ddcollide);
btDbvt::collideTT(m_sets[0].m_root,m_sets[0].m_root,collider);
}
}
/* clean up */
if(m_needcleanup)
{
SPC(m_profiling.m_cleanup);
btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray();
if(pairs.size()>0)
{
const int ci=pairs.size();
int ni=btMin(ci,btMax<int>(m_newpairs,(ci*m_cupdates)/100));
for(int i=0;i<ni;++i)
{
btBroadphasePair& p=pairs[(m_cid+i)%ci];
btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0;
btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1;
if(!Intersect(pa->leaf->volume,pb->leaf->volume))
{
#if DBVT_BP_SORTPAIRS
if(pa>pb) btSwap(pa,pb);
#endif
m_paircache->removeOverlappingPair(pa,pb,dispatcher);
--ni;--i;
}
}
if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0;
}
}
++m_pid;
m_newpairs=1;
m_needcleanup=false;
if(m_updates_call>0)
{ m_updates_ratio=m_updates_done/(btScalar)m_updates_call; }
else
{ m_updates_ratio=0; }
m_updates_done/=2;
m_updates_call/=2;
}
//
void btDbvtBroadphase::optimize()
{
m_sets[0].optimizeTopDown();
m_sets[1].optimizeTopDown();
}
//
btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache()
{
return(m_paircache);
}
//
const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const
{
return(m_paircache);
}
//
void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
{
ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds;
if(!m_sets[0].empty())
if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume,
m_sets[1].m_root->volume,bounds);
else
bounds=m_sets[0].m_root->volume;
else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume;
else
bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);
aabbMin=bounds.Mins();
aabbMax=bounds.Maxs();
}
//
void btDbvtBroadphase::printStats()
{}
//
#if DBVT_BP_ENABLE_BENCHMARK
struct btBroadphaseBenchmark
{
struct Experiment
{
const char* name;
int object_count;
int update_count;
int spawn_count;
int iterations;
btScalar speed;
btScalar amplitude;
};
struct Object
{
btVector3 center;
btVector3 extents;
btBroadphaseProxy* proxy;
btScalar time;
void update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi)
{
time += speed;
center[0] = btCos(time*(btScalar)2.17)*amplitude+
btSin(time)*amplitude/2;
center[1] = btCos(time*(btScalar)1.38)*amplitude+
btSin(time)*amplitude;
center[2] = btSin(time*(btScalar)0.777)*amplitude;
pbi->setAabb(proxy,center-extents,center+extents,0);
}
};
static int UnsignedRand(int range=RAND_MAX-1) { return(rand()%(range+1)); }
static btScalar UnitRand() { return(UnsignedRand(16384)/(btScalar)16384); }
static void OutputTime(const char* name,btClock& c,unsigned count=0)
{
const unsigned long us=c.getTimeMicroseconds();
const unsigned long ms=(us+500)/1000;
const btScalar sec=us/(btScalar)(1000*1000);
if(count>0)
printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec);
else
printf("%s : %u us (%u ms)\r\n",name,us,ms);
}
};
void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi)
{
static const btBroadphaseBenchmark::Experiment experiments[]=
{
{"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100},
/*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
{"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
};
static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]);
btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects;
btClock wallclock;
/* Begin */
for(int iexp=0;iexp<nexperiments;++iexp)
{
const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp];
const int object_count=experiment.object_count;
const int update_count=(object_count*experiment.update_count)/100;
const int spawn_count=(object_count*experiment.spawn_count)/100;
const btScalar speed=experiment.speed;
const btScalar amplitude=experiment.amplitude;
printf("Experiment #%u '%s':\r\n",iexp,experiment.name);
printf("\tObjects: %u\r\n",object_count);
printf("\tUpdate: %u\r\n",update_count);
printf("\tSpawn: %u\r\n",spawn_count);
printf("\tSpeed: %f\r\n",speed);
printf("\tAmplitude: %f\r\n",amplitude);
srand(180673);
/* Create objects */
wallclock.reset();
objects.reserve(object_count);
for(int i=0;i<object_count;++i)
{
btBroadphaseBenchmark::Object* po=new btBroadphaseBenchmark::Object();
po->center[0]=btBroadphaseBenchmark::UnitRand()*50;
po->center[1]=btBroadphaseBenchmark::UnitRand()*50;
po->center[2]=btBroadphaseBenchmark::UnitRand()*50;
po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2;
po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2;
po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2;
po->time=btBroadphaseBenchmark::UnitRand()*2000;
po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0);
objects.push_back(po);
}
btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock);
/* First update */
wallclock.reset();
for(int i=0;i<objects.size();++i)
{
objects[i]->update(speed,amplitude,pbi);
}
btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock);
/* Updates */
wallclock.reset();
for(int i=0;i<experiment.iterations;++i)
{
for(int j=0;j<update_count;++j)
{
objects[j]->update(speed,amplitude,pbi);
}
pbi->calculateOverlappingPairs(0);
}
btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations);
/* Clean up */
wallclock.reset();
for(int i=0;i<objects.size();++i)
{
pbi->destroyProxy(objects[i]->proxy,0);
delete objects[i];
}
objects.resize(0);
btBroadphaseBenchmark::OutputTime("\tRelease",wallclock);
}
}
#else
void btDbvtBroadphase::benchmark(btBroadphaseInterface*)
{}
#endif
#if DBVT_BP_PROFILE
#undef SPC
#endif

View File

@@ -0,0 +1,117 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
///btDbvtBroadphase implementation by Nathanael Presson
#ifndef BT_DBVT_BROADPHASE_H
#define BT_DBVT_BROADPHASE_H
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
//
// Compile time config
//
#define DBVT_BP_PROFILE 0
#define DBVT_BP_SORTPAIRS 1
#define DBVT_BP_PREVENTFALSEUPDATE 0
#define DBVT_BP_ACCURATESLEEPING 0
#define DBVT_BP_ENABLE_BENCHMARK 0
#define DBVT_BP_MARGIN (btScalar)0.05
#if DBVT_BP_PROFILE
#define DBVT_BP_PROFILING_RATE 256
#include "LinearMath/btQuickprof.h"
#endif
//
// btDbvtProxy
//
struct btDbvtProxy : btBroadphaseProxy
{
/* Fields */
btDbvtAabbMm aabb;
btDbvtNode* leaf;
btDbvtProxy* links[2];
int stage;
/* ctor */
btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask)
{
links[0]=links[1]=0;
}
};
typedef btAlignedObjectArray<btDbvtProxy*> btDbvtProxyArray;
///The btDbvtBroadphase implements a broadphase using two dynamic AABB bounding volume hierarchies/trees (see btDbvt).
///One tree is used for static/non-moving objects, and another tree is used for dynamic objects. Objects can move from one tree to the other.
///This is a very fast broadphase, especially for very dynamic worlds where many objects are moving. Its insert/add and remove of objects is generally faster than the sweep and prune broadphases btAxisSweep3 and bt32BitAxisSweep3.
struct btDbvtBroadphase : btBroadphaseInterface
{
/* Config */
enum {
DYNAMIC_SET = 0, /* Dynamic set index */
FIXED_SET = 1, /* Fixed set index */
STAGECOUNT = 2 /* Number of stages */
};
/* Fields */
btDbvt m_sets[2]; // Dbvt sets
btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list
btOverlappingPairCache* m_paircache; // Pair cache
btScalar m_prediction; // Velocity prediction
int m_stageCurrent; // Current stage
int m_fupdates; // % of fixed updates per frame
int m_dupdates; // % of dynamic updates per frame
int m_cupdates; // % of cleanup updates per frame
int m_newpairs; // Number of pairs created
int m_fixedleft; // Fixed optimization left
unsigned m_updates_call; // Number of updates call
unsigned m_updates_done; // Number of updates done
btScalar m_updates_ratio; // m_updates_done/m_updates_call
int m_pid; // Parse id
int m_cid; // Cleanup index
int m_gid; // Gen id
bool m_releasepaircache; // Release pair cache on delete
bool m_deferedcollide; // Defere dynamic/static collision to collide call
bool m_needcleanup; // Need to run cleanup?
bool m_initialize; // Initialization
#if DBVT_BP_PROFILE
btClock m_clock;
struct {
unsigned long m_total;
unsigned long m_ddcollide;
unsigned long m_fdcollide;
unsigned long m_cleanup;
unsigned long m_jobcount;
} m_profiling;
#endif
/* Methods */
btDbvtBroadphase(btOverlappingPairCache* paircache=0);
~btDbvtBroadphase();
void collide(btDispatcher* dispatcher);
void optimize();
/* btBroadphaseInterface Implementation */
btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
void calculateOverlappingPairs(btDispatcher* dispatcher);
btOverlappingPairCache* getOverlappingPairCache();
const btOverlappingPairCache* getOverlappingPairCache() const;
void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
void printStats();
static void benchmark(btBroadphaseInterface*);
};
#endif

View File

@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef _DISPATCHER_H
#define _DISPATCHER_H
#include "../../LinearMath/btScalar.h"
#include "LinearMath/btScalar.h"
class btCollisionAlgorithm;
struct btBroadphaseProxy;
@@ -43,7 +43,9 @@ struct btDispatcherInfo
m_useContinuous(false),
m_debugDraw(0),
m_enableSatConvex(false),
m_enableSPU(false),
m_enableSPU(true),
m_useEpa(true),
m_allowedCcdPenetration(btScalar(0.04)),
m_stackAllocator(0)
{
@@ -51,17 +53,19 @@ struct btDispatcherInfo
btScalar m_timeStep;
int m_stepCount;
int m_dispatchFunc;
btScalar m_timeOfImpact;
mutable btScalar m_timeOfImpact;
bool m_useContinuous;
class btIDebugDraw* m_debugDraw;
bool m_enableSatConvex;
bool m_enableSPU;
bool m_useEpa;
btScalar m_allowedCcdPenetration;
btStackAlloc* m_stackAllocator;
};
/// btDispatcher can be used in combination with broadphase to dispatch overlapping pairs.
/// For example for pairwise collision detection or user callbacks (game logic).
///The btDispatcher interface class can be used in combination with broadphase to dispatch calculations for overlapping pairs.
///For example for pairwise collision detection, calculating contact points stored in btPersistentManifold or user callbacks (game logic).
class btDispatcher
{
@@ -81,12 +85,18 @@ public:
virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0;
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo)=0;
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) =0;
virtual int getNumManifolds() const = 0;
virtual btPersistentManifold* getManifoldByIndexInternal(int index) = 0;
virtual btPersistentManifold** getInternalManifoldPointer() = 0;
virtual void* allocateCollisionAlgorithm(int size) = 0;
virtual void freeCollisionAlgorithm(void* ptr) = 0;
};

View File

@@ -0,0 +1,466 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "btMultiSapBroadphase.h"
#include "btSimpleBroadphase.h"
#include "LinearMath/btAabbUtil2.h"
#include "btQuantizedBvh.h"
/// btSapBroadphaseArray m_sapBroadphases;
/// btOverlappingPairCache* m_overlappingPairs;
extern int gOverlappingPairs;
/*
class btMultiSapSortedOverlappingPairCache : public btSortedOverlappingPairCache
{
public:
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
return btSortedOverlappingPairCache::addOverlappingPair((btBroadphaseProxy*)proxy0->m_multiSapParentProxy,(btBroadphaseProxy*)proxy1->m_multiSapParentProxy);
}
};
*/
btMultiSapBroadphase::btMultiSapBroadphase(int /*maxProxies*/,btOverlappingPairCache* pairCache)
:m_overlappingPairs(pairCache),
m_optimizedAabbTree(0),
m_ownsPairCache(false),
m_invalidPair(0)
{
if (!m_overlappingPairs)
{
m_ownsPairCache = true;
void* mem = btAlignedAlloc(sizeof(btSortedOverlappingPairCache),16);
m_overlappingPairs = new (mem)btSortedOverlappingPairCache();
}
struct btMultiSapOverlapFilterCallback : public btOverlapFilterCallback
{
virtual ~btMultiSapOverlapFilterCallback()
{}
// return true when pairs need collision
virtual bool needBroadphaseCollision(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) const
{
btBroadphaseProxy* multiProxy0 = (btBroadphaseProxy*)childProxy0->m_multiSapParentProxy;
btBroadphaseProxy* multiProxy1 = (btBroadphaseProxy*)childProxy1->m_multiSapParentProxy;
bool collides = (multiProxy0->m_collisionFilterGroup & multiProxy1->m_collisionFilterMask) != 0;
collides = collides && (multiProxy1->m_collisionFilterGroup & multiProxy0->m_collisionFilterMask);
return collides;
}
};
void* mem = btAlignedAlloc(sizeof(btMultiSapOverlapFilterCallback),16);
m_filterCallback = new (mem)btMultiSapOverlapFilterCallback();
m_overlappingPairs->setOverlapFilterCallback(m_filterCallback);
// mem = btAlignedAlloc(sizeof(btSimpleBroadphase),16);
// m_simpleBroadphase = new (mem) btSimpleBroadphase(maxProxies,m_overlappingPairs);
}
btMultiSapBroadphase::~btMultiSapBroadphase()
{
if (m_ownsPairCache)
{
m_overlappingPairs->~btOverlappingPairCache();
btAlignedFree(m_overlappingPairs);
}
}
void btMultiSapBroadphase::buildTree(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
{
m_optimizedAabbTree = new btQuantizedBvh();
m_optimizedAabbTree->setQuantizationValues(bvhAabbMin,bvhAabbMax);
QuantizedNodeArray& nodes = m_optimizedAabbTree->getLeafNodeArray();
for (int i=0;i<m_sapBroadphases.size();i++)
{
btQuantizedBvhNode node;
btVector3 aabbMin,aabbMax;
m_sapBroadphases[i]->getBroadphaseAabb(aabbMin,aabbMax);
m_optimizedAabbTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0);
m_optimizedAabbTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1);
int partId = 0;
node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | i;
nodes.push_back(node);
}
m_optimizedAabbTree->buildInternal();
}
btBroadphaseProxy* btMultiSapBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* /*ignoreMe*/)
{
//void* ignoreMe -> we could think of recursive multi-sap, if someone is interested
void* mem = btAlignedAlloc(sizeof(btMultiSapProxy),16);
btMultiSapProxy* proxy = new (mem)btMultiSapProxy(aabbMin, aabbMax,shapeType,userPtr, collisionFilterGroup,collisionFilterMask);
m_multiSapProxies.push_back(proxy);
///this should deal with inserting/removal into child broadphases
setAabb(proxy,aabbMin,aabbMax,dispatcher);
return proxy;
}
void btMultiSapBroadphase::destroyProxy(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/)
{
///not yet
btAssert(0);
}
void btMultiSapBroadphase::addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface* childBroadphase)
{
void* mem = btAlignedAlloc(sizeof(btBridgeProxy),16);
btBridgeProxy* bridgeProxyRef = new(mem) btBridgeProxy;
bridgeProxyRef->m_childProxy = childProxy;
bridgeProxyRef->m_childBroadphase = childBroadphase;
parentMultiSapProxy->m_bridgeProxies.push_back(bridgeProxyRef);
}
bool boxIsContainedWithinBox(const btVector3& amin,const btVector3& amax,const btVector3& bmin,const btVector3& bmax);
bool boxIsContainedWithinBox(const btVector3& amin,const btVector3& amax,const btVector3& bmin,const btVector3& bmax)
{
return
amin.getX() >= bmin.getX() && amax.getX() <= bmax.getX() &&
amin.getY() >= bmin.getY() && amax.getY() <= bmax.getY() &&
amin.getZ() >= bmin.getZ() && amax.getZ() <= bmax.getZ();
}
//#include <stdio.h>
void btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)
{
btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);
multiProxy->m_aabbMin = aabbMin;
multiProxy->m_aabbMax = aabbMax;
// bool fullyContained = false;
// bool alreadyInSimple = false;
struct MyNodeOverlapCallback : public btNodeOverlapCallback
{
btMultiSapBroadphase* m_multiSap;
btMultiSapProxy* m_multiProxy;
btDispatcher* m_dispatcher;
MyNodeOverlapCallback(btMultiSapBroadphase* multiSap,btMultiSapProxy* multiProxy,btDispatcher* dispatcher)
:m_multiSap(multiSap),
m_multiProxy(multiProxy),
m_dispatcher(dispatcher)
{
}
virtual void processNode(int /*nodeSubPart*/, int broadphaseIndex)
{
btBroadphaseInterface* childBroadphase = m_multiSap->getBroadphaseArray()[broadphaseIndex];
int containingBroadphaseIndex = -1;
//already found?
for (int i=0;i<m_multiProxy->m_bridgeProxies.size();i++)
{
if (m_multiProxy->m_bridgeProxies[i]->m_childBroadphase == childBroadphase)
{
containingBroadphaseIndex = i;
break;
}
}
if (containingBroadphaseIndex<0)
{
//add it
btBroadphaseProxy* childProxy = childBroadphase->createProxy(m_multiProxy->m_aabbMin,m_multiProxy->m_aabbMax,m_multiProxy->m_shapeType,m_multiProxy->m_clientObject,m_multiProxy->m_collisionFilterGroup,m_multiProxy->m_collisionFilterMask, m_dispatcher,m_multiProxy);
m_multiSap->addToChildBroadphase(m_multiProxy,childProxy,childBroadphase);
}
}
};
MyNodeOverlapCallback myNodeCallback(this,multiProxy,dispatcher);
m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
int i;
for ( i=0;i<multiProxy->m_bridgeProxies.size();i++)
{
btVector3 worldAabbMin,worldAabbMax;
multiProxy->m_bridgeProxies[i]->m_childBroadphase->getBroadphaseAabb(worldAabbMin,worldAabbMax);
bool overlapsBroadphase = TestAabbAgainstAabb2(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax);
if (!overlapsBroadphase)
{
//remove it now
btBridgeProxy* bridgeProxy = multiProxy->m_bridgeProxies[i];
btBroadphaseProxy* childProxy = bridgeProxy->m_childProxy;
bridgeProxy->m_childBroadphase->destroyProxy(childProxy,dispatcher);
multiProxy->m_bridgeProxies.swap( i,multiProxy->m_bridgeProxies.size()-1);
multiProxy->m_bridgeProxies.pop_back();
}
}
/*
if (1)
{
//find broadphase that contain this multiProxy
int numChildBroadphases = getBroadphaseArray().size();
for (int i=0;i<numChildBroadphases;i++)
{
btBroadphaseInterface* childBroadphase = getBroadphaseArray()[i];
btVector3 worldAabbMin,worldAabbMax;
childBroadphase->getBroadphaseAabb(worldAabbMin,worldAabbMax);
bool overlapsBroadphase = TestAabbAgainstAabb2(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax);
// fullyContained = fullyContained || boxIsContainedWithinBox(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax);
int containingBroadphaseIndex = -1;
//if already contains this
for (int i=0;i<multiProxy->m_bridgeProxies.size();i++)
{
if (multiProxy->m_bridgeProxies[i]->m_childBroadphase == childBroadphase)
{
containingBroadphaseIndex = i;
}
alreadyInSimple = alreadyInSimple || (multiProxy->m_bridgeProxies[i]->m_childBroadphase == m_simpleBroadphase);
}
if (overlapsBroadphase)
{
if (containingBroadphaseIndex<0)
{
btBroadphaseProxy* childProxy = childBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher);
childProxy->m_multiSapParentProxy = multiProxy;
addToChildBroadphase(multiProxy,childProxy,childBroadphase);
}
} else
{
if (containingBroadphaseIndex>=0)
{
//remove
btBridgeProxy* bridgeProxy = multiProxy->m_bridgeProxies[containingBroadphaseIndex];
btBroadphaseProxy* childProxy = bridgeProxy->m_childProxy;
bridgeProxy->m_childBroadphase->destroyProxy(childProxy,dispatcher);
multiProxy->m_bridgeProxies.swap( containingBroadphaseIndex,multiProxy->m_bridgeProxies.size()-1);
multiProxy->m_bridgeProxies.pop_back();
}
}
}
///If we are in no other child broadphase, stick the proxy in the global 'simple' broadphase (brute force)
///hopefully we don't end up with many entries here (can assert/provide feedback on stats)
if (0)//!multiProxy->m_bridgeProxies.size())
{
///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision
///this is needed to be able to calculate the aabb overlap
btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher);
childProxy->m_multiSapParentProxy = multiProxy;
addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase);
}
}
if (!multiProxy->m_bridgeProxies.size())
{
///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision
///this is needed to be able to calculate the aabb overlap
btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher);
childProxy->m_multiSapParentProxy = multiProxy;
addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase);
}
*/
//update
for ( i=0;i<multiProxy->m_bridgeProxies.size();i++)
{
btBridgeProxy* bridgeProxyRef = multiProxy->m_bridgeProxies[i];
bridgeProxyRef->m_childBroadphase->setAabb(bridgeProxyRef->m_childProxy,aabbMin,aabbMax,dispatcher);
}
}
bool stopUpdating=false;
class btMultiSapBroadphasePairSortPredicate
{
public:
bool operator() ( const btBroadphasePair& a1, const btBroadphasePair& b1 )
{
btMultiSapBroadphase::btMultiSapProxy* aProxy0 = a1.m_pProxy0 ? (btMultiSapBroadphase::btMultiSapProxy*)a1.m_pProxy0->m_multiSapParentProxy : 0;
btMultiSapBroadphase::btMultiSapProxy* aProxy1 = a1.m_pProxy1 ? (btMultiSapBroadphase::btMultiSapProxy*)a1.m_pProxy1->m_multiSapParentProxy : 0;
btMultiSapBroadphase::btMultiSapProxy* bProxy0 = b1.m_pProxy0 ? (btMultiSapBroadphase::btMultiSapProxy*)b1.m_pProxy0->m_multiSapParentProxy : 0;
btMultiSapBroadphase::btMultiSapProxy* bProxy1 = b1.m_pProxy1 ? (btMultiSapBroadphase::btMultiSapProxy*)b1.m_pProxy1->m_multiSapParentProxy : 0;
return aProxy0 > bProxy0 ||
(aProxy0 == bProxy0 && aProxy1 > bProxy1) ||
(aProxy0 == bProxy0 && aProxy1 == bProxy1 && a1.m_algorithm > b1.m_algorithm);
}
};
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
void btMultiSapBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
{
// m_simpleBroadphase->calculateOverlappingPairs(dispatcher);
if (!stopUpdating && getOverlappingPairCache()->hasDeferredRemoval())
{
btBroadphasePairArray& overlappingPairArray = getOverlappingPairCache()->getOverlappingPairArray();
// quicksort(overlappingPairArray,0,overlappingPairArray.size());
overlappingPairArray.quickSort(btMultiSapBroadphasePairSortPredicate());
//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
// overlappingPairArray.heapSort(btMultiSapBroadphasePairSortPredicate());
overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
m_invalidPair = 0;
int i;
btBroadphasePair previousPair;
previousPair.m_pProxy0 = 0;
previousPair.m_pProxy1 = 0;
previousPair.m_algorithm = 0;
for (i=0;i<overlappingPairArray.size();i++)
{
btBroadphasePair& pair = overlappingPairArray[i];
btMultiSapProxy* aProxy0 = pair.m_pProxy0 ? (btMultiSapProxy*)pair.m_pProxy0->m_multiSapParentProxy : 0;
btMultiSapProxy* aProxy1 = pair.m_pProxy1 ? (btMultiSapProxy*)pair.m_pProxy1->m_multiSapParentProxy : 0;
btMultiSapProxy* bProxy0 = previousPair.m_pProxy0 ? (btMultiSapProxy*)previousPair.m_pProxy0->m_multiSapParentProxy : 0;
btMultiSapProxy* bProxy1 = previousPair.m_pProxy1 ? (btMultiSapProxy*)previousPair.m_pProxy1->m_multiSapParentProxy : 0;
bool isDuplicate = (aProxy0 == bProxy0) && (aProxy1 == bProxy1);
previousPair = pair;
bool needsRemoval = false;
if (!isDuplicate)
{
bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
if (hasOverlap)
{
needsRemoval = false;//callback->processOverlap(pair);
} else
{
needsRemoval = true;
}
} else
{
//remove duplicate
needsRemoval = true;
//should have no algorithm
btAssert(!pair.m_algorithm);
}
if (needsRemoval)
{
getOverlappingPairCache()->cleanOverlappingPair(pair,dispatcher);
// m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
// m_overlappingPairArray.pop_back();
pair.m_pProxy0 = 0;
pair.m_pProxy1 = 0;
m_invalidPair++;
gOverlappingPairs--;
}
}
///if you don't like to skip the invalid pairs in the array, execute following code:
#define CLEAN_INVALID_PAIRS 1
#ifdef CLEAN_INVALID_PAIRS
//perform a sort, to sort 'invalid' pairs to the end
//overlappingPairArray.heapSort(btMultiSapBroadphasePairSortPredicate());
overlappingPairArray.quickSort(btMultiSapBroadphasePairSortPredicate());
overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
m_invalidPair = 0;
#endif//CLEAN_INVALID_PAIRS
//printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
}
}
bool btMultiSapBroadphase::testAabbOverlap(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1)
{
btMultiSapProxy* multiSapProxy0 = (btMultiSapProxy*)childProxy0->m_multiSapParentProxy;
btMultiSapProxy* multiSapProxy1 = (btMultiSapProxy*)childProxy1->m_multiSapParentProxy;
return TestAabbAgainstAabb2(multiSapProxy0->m_aabbMin,multiSapProxy0->m_aabbMax,
multiSapProxy1->m_aabbMin,multiSapProxy1->m_aabbMax);
}
void btMultiSapBroadphase::printStats()
{
/* printf("---------------------------------\n");
printf("btMultiSapBroadphase.h\n");
printf("numHandles = %d\n",m_multiSapProxies.size());
//find broadphase that contain this multiProxy
int numChildBroadphases = getBroadphaseArray().size();
for (int i=0;i<numChildBroadphases;i++)
{
btBroadphaseInterface* childBroadphase = getBroadphaseArray()[i];
childBroadphase->printStats();
}
*/
}

View File

@@ -0,0 +1,144 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_MULTI_SAP_BROADPHASE
#define BT_MULTI_SAP_BROADPHASE
#include "btBroadphaseInterface.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "btOverlappingPairCache.h"
class btBroadphaseInterface;
class btSimpleBroadphase;
typedef btAlignedObjectArray<btBroadphaseInterface*> btSapBroadphaseArray;
///The btMultiSapBroadphase is a broadphase that contains multiple SAP broadphases.
///The user can add SAP broadphases that cover the world. A btBroadphaseProxy can be in multiple child broadphases at the same time.
///A btQuantizedBvh acceleration structures finds overlapping SAPs for each btBroadphaseProxy.
///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=328
///and http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329
class btMultiSapBroadphase :public btBroadphaseInterface
{
btSapBroadphaseArray m_sapBroadphases;
btSimpleBroadphase* m_simpleBroadphase;
btOverlappingPairCache* m_overlappingPairs;
class btQuantizedBvh* m_optimizedAabbTree;
bool m_ownsPairCache;
btOverlapFilterCallback* m_filterCallback;
int m_invalidPair;
struct btBridgeProxy
{
btBroadphaseProxy* m_childProxy;
btBroadphaseInterface* m_childBroadphase;
};
public:
struct btMultiSapProxy : public btBroadphaseProxy
{
///array with all the entries that this proxy belongs to
btAlignedObjectArray<btBridgeProxy*> m_bridgeProxies;
btVector3 m_aabbMin;
btVector3 m_aabbMax;
int m_shapeType;
/* void* m_userPtr;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
*/
btMultiSapProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask)
:btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask),
m_aabbMin(aabbMin),
m_aabbMax(aabbMax),
m_shapeType(shapeType)
{
m_multiSapParentProxy =this;
}
};
protected:
btAlignedObjectArray<btMultiSapProxy*> m_multiSapProxies;
public:
btMultiSapBroadphase(int maxProxies = 16384,btOverlappingPairCache* pairCache=0);
btSapBroadphaseArray& getBroadphaseArray()
{
return m_sapBroadphases;
}
const btSapBroadphaseArray& getBroadphaseArray() const
{
return m_sapBroadphases;
}
virtual ~btMultiSapBroadphase();
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy);
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
void addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface* childBroadphase);
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
virtual btOverlappingPairCache* getOverlappingPairCache()
{
return m_overlappingPairs;
}
virtual const btOverlappingPairCache* getOverlappingPairCache() const
{
return m_overlappingPairs;
}
///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
///will add some transform later
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
{
aabbMin.setValue(-1e30f,-1e30f,-1e30f);
aabbMax.setValue(1e30f,1e30f,1e30f);
}
void buildTree(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
virtual void printStats();
void quicksort (btBroadphasePairArray& a, int lo, int hi);
};
#endif //BT_MULTI_SAP_BROADPHASE

View File

@@ -1,4 +1,3 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
@@ -21,44 +20,43 @@ subject to the following restrictions:
#include "btDispatcher.h"
#include "btCollisionAlgorithm.h"
#include <stdio.h>
int gOverlappingPairs = 0;
btOverlappingPairCache::btOverlappingPairCache():
m_blockedForChanges(false),
m_overlapFilterCallback(0)
//m_NumOverlapBroadphasePair(0)
int gRemovePairs =0;
int gAddedPairs =0;
int gFindPairs =0;
btHashedOverlappingPairCache::btHashedOverlappingPairCache():
m_overlapFilterCallback(0),
m_blockedForChanges(false)
{
int initialAllocatedSize= 2;
m_overlappingPairArray.reserve(initialAllocatedSize);
growTables();
}
btOverlappingPairCache::~btOverlappingPairCache()
btHashedOverlappingPairCache::~btHashedOverlappingPairCache()
{
//todo/test: show we erase/delete data, or is it automatic
}
void btOverlappingPairCache::removeOverlappingPair(btBroadphasePair& findPair)
{
int findIndex = m_overlappingPairArray.findLinearSearch(findPair);
if (findIndex < m_overlappingPairArray.size())
{
gOverlappingPairs--;
btBroadphasePair& pair = m_overlappingPairArray[findIndex];
cleanOverlappingPair(pair);
m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.size()-1);
m_overlappingPairArray.pop_back();
}
}
void btOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair)
void btHashedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher)
{
if (pair.m_algorithm)
{
{
delete pair.m_algorithm;;
pair.m_algorithm->~btCollisionAlgorithm();
dispatcher->freeCollisionAlgorithm(pair.m_algorithm);
pair.m_algorithm=0;
}
}
@@ -67,60 +65,20 @@ void btOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair)
void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
//don't add overlap with own
assert(proxy0 != proxy1);
if (!needsBroadphaseCollision(proxy0,proxy1))
return;
btBroadphasePair pair(*proxy0,*proxy1);
m_overlappingPairArray.push_back(pair);
gOverlappingPairs++;
}
///this findPair becomes really slow. Either sort the list to speedup the query, or
///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed.
///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address)
///Also we can use a 2D bitmap, which can be useful for a future GPU implementation
btBroadphasePair* btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
if (!needsBroadphaseCollision(proxy0,proxy1))
return 0;
btBroadphasePair tmpPair(*proxy0,*proxy1);
int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair);
if (findIndex < m_overlappingPairArray.size())
{
//assert(it != m_overlappingPairSet.end());
btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
return pair;
}
return 0;
}
void btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy)
void btHashedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
{
class CleanPairCallback : public btOverlapCallback
{
btBroadphaseProxy* m_cleanProxy;
btOverlappingPairCache* m_pairCache;
btDispatcher* m_dispatcher;
public:
CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache)
CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher)
:m_cleanProxy(cleanProxy),
m_pairCache(pairCache)
m_pairCache(pairCache),
m_dispatcher(dispatcher)
{
}
virtual bool processOverlap(btBroadphasePair& pair)
@@ -128,22 +86,23 @@ void btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy)
if ((pair.m_pProxy0 == m_cleanProxy) ||
(pair.m_pProxy1 == m_cleanProxy))
{
m_pairCache->cleanOverlappingPair(pair);
m_pairCache->cleanOverlappingPair(pair,m_dispatcher);
}
return false;
}
};
CleanPairCallback cleanPairs(proxy,this);
CleanPairCallback cleanPairs(proxy,this,dispatcher);
processAllOverlappingPairs(&cleanPairs);
processAllOverlappingPairs(&cleanPairs,dispatcher);
}
void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy)
void btHashedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
{
class RemovePairCallback : public btOverlapCallback
@@ -166,12 +125,346 @@ void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseP
RemovePairCallback removeCallback(proxy);
processAllOverlappingPairs(&removeCallback);
processAllOverlappingPairs(&removeCallback,dispatcher);
}
void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback)
btBroadphasePair* btHashedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
{
gFindPairs++;
if(proxy0>proxy1) btSwap(proxy0,proxy1);
int proxyId1 = proxy0->getUid();
int proxyId2 = proxy1->getUid();
/*if (proxyId1 > proxyId2)
btSwap(proxyId1, proxyId2);*/
int hash = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1), static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1));
if (hash >= m_hashTable.size())
{
return NULL;
}
int index = m_hashTable[hash];
while (index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
{
index = m_next[index];
}
if (index == BT_NULL_PAIR)
{
return NULL;
}
btAssert(index < m_overlappingPairArray.size());
return &m_overlappingPairArray[index];
}
//#include <stdio.h>
void btHashedOverlappingPairCache::growTables()
{
int newCapacity = m_overlappingPairArray.capacity();
if (m_hashTable.size() < newCapacity)
{
//grow hashtable and next table
int curHashtableSize = m_hashTable.size();
m_hashTable.resize(newCapacity);
m_next.resize(newCapacity);
int i;
for (i= 0; i < newCapacity; ++i)
{
m_hashTable[i] = BT_NULL_PAIR;
}
for (i = 0; i < newCapacity; ++i)
{
m_next[i] = BT_NULL_PAIR;
}
for(i=0;i<curHashtableSize;i++)
{
const btBroadphasePair& pair = m_overlappingPairArray[i];
int proxyId1 = pair.m_pProxy0->getUid();
int proxyId2 = pair.m_pProxy1->getUid();
/*if (proxyId1 > proxyId2)
btSwap(proxyId1, proxyId2);*/
int hashValue = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1),static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask
m_next[i] = m_hashTable[hashValue];
m_hashTable[hashValue] = i;
}
}
}
btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
{
if(proxy0>proxy1) btSwap(proxy0,proxy1);
int proxyId1 = proxy0->getUid();
int proxyId2 = proxy1->getUid();
/*if (proxyId1 > proxyId2)
btSwap(proxyId1, proxyId2);*/
int hash = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1),static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask
btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash);
if (pair != NULL)
{
return pair;
}
/*for(int i=0;i<m_overlappingPairArray.size();++i)
{
if( (m_overlappingPairArray[i].m_pProxy0==proxy0)&&
(m_overlappingPairArray[i].m_pProxy1==proxy1))
{
printf("Adding duplicated %u<>%u\r\n",proxyId1,proxyId2);
internalFindPair(proxy0, proxy1, hash);
}
}*/
int count = m_overlappingPairArray.size();
int oldCapacity = m_overlappingPairArray.capacity();
void* mem = &m_overlappingPairArray.expand();
int newCapacity = m_overlappingPairArray.capacity();
if (oldCapacity < newCapacity)
{
growTables();
//hash with new capacity
hash = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1),static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1));
}
pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
// pair->m_pProxy0 = proxy0;
// pair->m_pProxy1 = proxy1;
pair->m_algorithm = 0;
pair->m_userInfo = 0;
m_next[count] = m_hashTable[hash];
m_hashTable[hash] = count;
return pair;
}
void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
{
gRemovePairs++;
if(proxy0>proxy1) btSwap(proxy0,proxy1);
int proxyId1 = proxy0->getUid();
int proxyId2 = proxy1->getUid();
/*if (proxyId1 > proxyId2)
btSwap(proxyId1, proxyId2);*/
int hash = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1),static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1));
btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash);
if (pair == NULL)
{
return 0;
}
cleanOverlappingPair(*pair,dispatcher);
void* userData = pair->m_userInfo;
btAssert(pair->m_pProxy0->getUid() == proxyId1);
btAssert(pair->m_pProxy1->getUid() == proxyId2);
int pairIndex = int(pair - &m_overlappingPairArray[0]);
btAssert(pairIndex < m_overlappingPairArray.size());
// Remove the pair from the hash table.
int index = m_hashTable[hash];
btAssert(index != BT_NULL_PAIR);
int previous = BT_NULL_PAIR;
while (index != pairIndex)
{
previous = index;
index = m_next[index];
}
if (previous != BT_NULL_PAIR)
{
btAssert(m_next[previous] == pairIndex);
m_next[previous] = m_next[pairIndex];
}
else
{
m_hashTable[hash] = m_next[pairIndex];
}
// We now move the last pair into spot of the
// pair being removed. We need to fix the hash
// table indices to support the move.
int lastPairIndex = m_overlappingPairArray.size() - 1;
// If the removed pair is the last pair, we are done.
if (lastPairIndex == pairIndex)
{
m_overlappingPairArray.pop_back();
return userData;
}
// Remove the last pair from the hash table.
const btBroadphasePair* last = &m_overlappingPairArray[lastPairIndex];
/* missing swap here too, Nat. */
int lastHash = static_cast<int>(getHash(static_cast<unsigned int>(last->m_pProxy0->getUid()), static_cast<unsigned int>(last->m_pProxy1->getUid())) & (m_overlappingPairArray.capacity()-1));
index = m_hashTable[lastHash];
btAssert(index != BT_NULL_PAIR);
previous = BT_NULL_PAIR;
while (index != lastPairIndex)
{
previous = index;
index = m_next[index];
}
if (previous != BT_NULL_PAIR)
{
btAssert(m_next[previous] == lastPairIndex);
m_next[previous] = m_next[lastPairIndex];
}
else
{
m_hashTable[lastHash] = m_next[lastPairIndex];
}
// Copy the last pair into the remove pair's spot.
m_overlappingPairArray[pairIndex] = m_overlappingPairArray[lastPairIndex];
// Insert the last pair into the hash table
m_next[pairIndex] = m_hashTable[lastHash];
m_hashTable[lastHash] = pairIndex;
m_overlappingPairArray.pop_back();
return userData;
}
//#include <stdio.h>
void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher)
{
int i;
// printf("m_overlappingPairArray.size()=%d\n",m_overlappingPairArray.size());
for (i=0;i<m_overlappingPairArray.size();)
{
btBroadphasePair* pair = &m_overlappingPairArray[i];
if (callback->processOverlap(*pair))
{
removeOverlappingPair(pair->m_pProxy0,pair->m_pProxy1,dispatcher);
gOverlappingPairs--;
} else
{
i++;
}
}
}
void* btSortedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1, btDispatcher* dispatcher )
{
if (!hasDeferredRemoval())
{
btBroadphasePair findPair(*proxy0,*proxy1);
int findIndex = m_overlappingPairArray.findLinearSearch(findPair);
if (findIndex < m_overlappingPairArray.size())
{
gOverlappingPairs--;
btBroadphasePair& pair = m_overlappingPairArray[findIndex];
void* userData = pair.m_userInfo;
cleanOverlappingPair(pair,dispatcher);
m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1);
m_overlappingPairArray.pop_back();
return userData;
}
}
return 0;
}
btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
//don't add overlap with own
assert(proxy0 != proxy1);
if (!needsBroadphaseCollision(proxy0,proxy1))
return 0;
void* mem = &m_overlappingPairArray.expand();
btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
gOverlappingPairs++;
gAddedPairs++;
return pair;
}
///this findPair becomes really slow. Either sort the list to speedup the query, or
///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed.
///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address)
///Also we can use a 2D bitmap, which can be useful for a future GPU implementation
btBroadphasePair* btSortedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
if (!needsBroadphaseCollision(proxy0,proxy1))
return 0;
btBroadphasePair tmpPair(*proxy0,*proxy1);
int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair);
if (findIndex < m_overlappingPairArray.size())
{
//assert(it != m_overlappingPairSet.end());
btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
return pair;
}
return 0;
}
//#include <stdio.h>
void btSortedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher)
{
int i;
@@ -182,9 +475,9 @@ void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callb
btBroadphasePair* pair = &m_overlappingPairArray[i];
if (callback->processOverlap(*pair))
{
cleanOverlappingPair(*pair);
cleanOverlappingPair(*pair,dispatcher);
m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
m_overlappingPairArray.swap(i,m_overlappingPairArray.capacity()-1);
m_overlappingPairArray.pop_back();
gOverlappingPairs--;
} else
@@ -194,3 +487,93 @@ void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callb
}
}
btSortedOverlappingPairCache::btSortedOverlappingPairCache():
m_blockedForChanges(false),
m_hasDeferredRemoval(true),
m_overlapFilterCallback(0)
{
int initialAllocatedSize= 2;
m_overlappingPairArray.reserve(initialAllocatedSize);
}
btSortedOverlappingPairCache::~btSortedOverlappingPairCache()
{
//todo/test: show we erase/delete data, or is it automatic
}
void btSortedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher)
{
if (pair.m_algorithm)
{
{
pair.m_algorithm->~btCollisionAlgorithm();
dispatcher->freeCollisionAlgorithm(pair.m_algorithm);
pair.m_algorithm=0;
gRemovePairs--;
}
}
}
void btSortedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
{
class CleanPairCallback : public btOverlapCallback
{
btBroadphaseProxy* m_cleanProxy;
btOverlappingPairCache* m_pairCache;
btDispatcher* m_dispatcher;
public:
CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher)
:m_cleanProxy(cleanProxy),
m_pairCache(pairCache),
m_dispatcher(dispatcher)
{
}
virtual bool processOverlap(btBroadphasePair& pair)
{
if ((pair.m_pProxy0 == m_cleanProxy) ||
(pair.m_pProxy1 == m_cleanProxy))
{
m_pairCache->cleanOverlappingPair(pair,m_dispatcher);
}
return false;
}
};
CleanPairCallback cleanPairs(proxy,this,dispatcher);
processAllOverlappingPairs(&cleanPairs,dispatcher);
}
void btSortedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
{
class RemovePairCallback : public btOverlapCallback
{
btBroadphaseProxy* m_obsoleteProxy;
public:
RemovePairCallback(btBroadphaseProxy* obsoleteProxy)
:m_obsoleteProxy(obsoleteProxy)
{
}
virtual bool processOverlap(btBroadphasePair& pair)
{
return ((pair.m_pProxy0 == m_obsoleteProxy) ||
(pair.m_pProxy1 == m_obsoleteProxy));
}
};
RemovePairCallback removeCallback(proxy);
processAllOverlappingPairs(&removeCallback,dispatcher);
}

View File

@@ -1,4 +1,3 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
@@ -20,9 +19,13 @@ subject to the following restrictions:
#include "btBroadphaseInterface.h"
#include "btBroadphaseProxy.h"
#include "../../LinearMath/btPoint3.h"
#include "../../LinearMath/btAlignedObjectArray.h"
#include "btOverlappingPairCallback.h"
#include "LinearMath/btPoint3.h"
#include "LinearMath/btAlignedObjectArray.h"
class btDispatcher;
typedef btAlignedObjectArray<btBroadphasePair> btBroadphasePairArray;
struct btOverlapCallback
{
@@ -30,6 +33,7 @@ struct btOverlapCallback
{}
//return true for deletion of the pair
virtual bool processOverlap(btBroadphasePair& pair) = 0;
};
struct btOverlapFilterCallback
@@ -40,38 +44,261 @@ struct btOverlapFilterCallback
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
};
///btOverlappingPairCache maintains the objects with overlapping AABB
extern int gRemovePairs;
extern int gAddedPairs;
extern int gFindPairs;
const int BT_NULL_PAIR=0xffffffff;
///The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
///The btHashedOverlappingPairCache and btSortedOverlappingPairCache classes are two implementations.
class btOverlappingPairCache : public btOverlappingPairCallback
{
public:
virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor
virtual btBroadphasePair* getOverlappingPairArrayPtr() = 0;
virtual const btBroadphasePair* getOverlappingPairArrayPtr() const = 0;
virtual btBroadphasePairArray& getOverlappingPairArray() = 0;
virtual void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) = 0;
virtual int getNumOverlappingPairs() const = 0;
virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) = 0;
virtual void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0;
virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher) = 0;
virtual btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) = 0;
virtual bool hasDeferredRemoval() = 0;
};
/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com
class btHashedOverlappingPairCache : public btOverlappingPairCache
{
btBroadphasePairArray m_overlappingPairArray;
btOverlapFilterCallback* m_overlapFilterCallback;
bool m_blockedForChanges;
public:
btHashedOverlappingPairCache();
virtual ~btHashedOverlappingPairCache();
void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
{
if (m_overlapFilterCallback)
return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
// Add a pair and return the new pair. If the pair already exists,
// no new pair is created and the old one is returned.
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
gAddedPairs++;
if (!needsBroadphaseCollision(proxy0,proxy1))
return 0;
return internalAddPair(proxy0,proxy1);
}
void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
virtual btBroadphasePair* getOverlappingPairArrayPtr()
{
return &m_overlappingPairArray[0];
}
const btBroadphasePair* getOverlappingPairArrayPtr() const
{
return &m_overlappingPairArray[0];
}
btBroadphasePairArray& getOverlappingPairArray()
{
return m_overlappingPairArray;
}
const btBroadphasePairArray& getOverlappingPairArray() const
{
return m_overlappingPairArray;
}
void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1);
int GetCount() const { return m_overlappingPairArray.size(); }
// btBroadphasePair* GetPairs() { return m_pairs; }
btOverlapFilterCallback* getOverlapFilterCallback()
{
return m_overlapFilterCallback;
}
void setOverlapFilterCallback(btOverlapFilterCallback* callback)
{
m_overlapFilterCallback = callback;
}
int getNumOverlappingPairs() const
{
return m_overlappingPairArray.size();
}
private:
btBroadphasePair* internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
void growTables();
SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2)
{
return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2;
}
/*
// Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
// This assumes proxyId1 and proxyId2 are 16-bit.
SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2)
{
int key = (proxyId2 << 16) | proxyId1;
key = ~key + (key << 15);
key = key ^ (key >> 12);
key = key + (key << 2);
key = key ^ (key >> 4);
key = key * 2057;
key = key ^ (key >> 16);
return key;
}
*/
SIMD_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
{
int key = static_cast<int>(((unsigned int)proxyId1) | (((unsigned int)proxyId2) <<16));
// Thomas Wang's hash
key += ~(key << 15);
key ^= (key >> 10);
key += (key << 3);
key ^= (key >> 6);
key += ~(key << 11);
key ^= (key >> 16);
return static_cast<unsigned int>(key);
}
SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash)
{
int proxyId1 = proxy0->getUid();
int proxyId2 = proxy1->getUid();
#if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat.
if (proxyId1 > proxyId2)
btSwap(proxyId1, proxyId2);
#endif
int index = m_hashTable[hash];
while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
{
index = m_next[index];
}
if ( index == BT_NULL_PAIR )
{
return NULL;
}
btAssert(index < m_overlappingPairArray.size());
return &m_overlappingPairArray[index];
}
virtual bool hasDeferredRemoval()
{
return false;
}
public:
btAlignedObjectArray<int> m_hashTable;
btAlignedObjectArray<int> m_next;
};
///btSortedOverlappingPairCache maintains the objects with overlapping AABB
///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
class btOverlappingPairCache : public btBroadphaseInterface
class btSortedOverlappingPairCache : public btOverlappingPairCache
{
protected:
//avoid brute-force finding all the time
btAlignedObjectArray<btBroadphasePair> m_overlappingPairArray;
btBroadphasePairArray m_overlappingPairArray;
//during the dispatch, check that user doesn't destroy/create proxy
bool m_blockedForChanges;
///by default, do the removal during the pair traversal
bool m_hasDeferredRemoval;
//if set, use the callback instead of the built in filter in needBroadphaseCollision
btOverlapFilterCallback* m_overlapFilterCallback;
public:
btOverlappingPairCache();
virtual ~btOverlappingPairCache();
btSortedOverlappingPairCache();
virtual ~btSortedOverlappingPairCache();
virtual void processAllOverlappingPairs(btOverlapCallback*);
virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
void removeOverlappingPair(btBroadphasePair& pair);
void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
void cleanOverlappingPair(btBroadphasePair& pair);
void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
void addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
void cleanProxyFromPairs(btBroadphaseProxy* proxy);
void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy);
void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
@@ -84,10 +311,19 @@ class btOverlappingPairCache : public btBroadphaseInterface
return collides;
}
btBroadphasePairArray& getOverlappingPairArray()
{
return m_overlappingPairArray;
}
const btBroadphasePairArray& getOverlappingPairArray() const
{
return m_overlappingPairArray;
}
virtual void refreshOverlappingPairs() =0;
btBroadphasePair* getOverlappingPairArrayPtr()
{
@@ -114,7 +350,88 @@ class btOverlappingPairCache : public btBroadphaseInterface
m_overlapFilterCallback = callback;
}
virtual bool hasDeferredRemoval()
{
return m_hasDeferredRemoval;
}
};
///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and testing.
class btNullPairCache : public btOverlappingPairCache
{
btBroadphasePairArray m_overlappingPairArray;
public:
virtual btBroadphasePair* getOverlappingPairArrayPtr()
{
return &m_overlappingPairArray[0];
}
const btBroadphasePair* getOverlappingPairArrayPtr() const
{
return &m_overlappingPairArray[0];
}
btBroadphasePairArray& getOverlappingPairArray()
{
return m_overlappingPairArray;
}
virtual void cleanOverlappingPair(btBroadphasePair& /*pair*/,btDispatcher* /*dispatcher*/)
{
}
virtual int getNumOverlappingPairs() const
{
return 0;
}
virtual void cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/)
{
}
virtual void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/)
{
}
virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* /*dispatcher*/)
{
}
virtual btBroadphasePair* findPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/)
{
return 0;
}
virtual bool hasDeferredRemoval()
{
return true;
}
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/)
{
return 0;
}
virtual void* removeOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/,btDispatcher* /*dispatcher*/)
{
return 0;
}
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
{
}
};
#endif //OVERLAPPING_PAIR_CACHE_H

View File

@@ -0,0 +1,40 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OVERLAPPING_PAIR_CALLBACK_H
#define OVERLAPPING_PAIR_CALLBACK_H
class btDispatcher;
struct btBroadphasePair;
///The btOverlappingPairCallback class is an additional optional broadphase user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache.
class btOverlappingPairCallback
{
public:
virtual ~btOverlappingPairCallback()
{
}
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0;
virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher) = 0;
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher) = 0;
};
#endif //OVERLAPPING_PAIR_CALLBACK_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,486 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef QUANTIZED_BVH_H
#define QUANTIZED_BVH_H
//#define DEBUG_CHECK_DEQUANTIZATION 1
#ifdef DEBUG_CHECK_DEQUANTIZATION
#ifdef __SPU__
#define printf spu_printf
#endif //__SPU__
#include <stdio.h>
#include <stdlib.h>
#endif //DEBUG_CHECK_DEQUANTIZATION
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedAllocator.h"
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp
//Note: currently we have 16 bytes per quantized node
#define MAX_SUBTREE_SIZE_IN_BYTES 2048
// 10 gives the potential for 1024 parts, with at most 2^21 (2097152) (minus one
// actually) triangles each (since the sign bit is reserved
#define MAX_NUM_PARTS_IN_BITS 10
///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode
{
BT_DECLARE_ALIGNED_ALLOCATOR();
//12 bytes
unsigned short int m_quantizedAabbMin[3];
unsigned short int m_quantizedAabbMax[3];
//4 bytes
int m_escapeIndexOrTriangleIndex;
bool isLeafNode() const
{
//skipindex is negative (internal node), triangleindex >=0 (leafnode)
return (m_escapeIndexOrTriangleIndex >= 0);
}
int getEscapeIndex() const
{
btAssert(!isLeafNode());
return -m_escapeIndexOrTriangleIndex;
}
int getTriangleIndex() const
{
btAssert(isLeafNode());
// Get only the lower bits where the triangle index is stored
return (m_escapeIndexOrTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS)));
}
int getPartId() const
{
btAssert(isLeafNode());
// Get only the highest bits where the part index is stored
return (m_escapeIndexOrTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS));
}
}
;
/// btOptimizedBvhNode contains both internal and leaf node information.
/// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes.
ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode
{
BT_DECLARE_ALIGNED_ALLOCATOR();
//32 bytes
btVector3 m_aabbMinOrg;
btVector3 m_aabbMaxOrg;
//4
int m_escapeIndex;
//8
//for child nodes
int m_subPart;
int m_triangleIndex;
int m_padding[5];//bad, due to alignment
};
///btBvhSubtreeInfo provides info to gather a subtree of limited size
ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo
{
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
//12 bytes
unsigned short int m_quantizedAabbMin[3];
unsigned short int m_quantizedAabbMax[3];
//4 bytes, points to the root of the subtree
int m_rootNodeIndex;
//4 bytes
int m_subtreeSize;
int m_padding[3];
btBvhSubtreeInfo()
{
//memset(&m_padding[0], 0, sizeof(m_padding));
}
void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode)
{
m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0];
m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1];
m_quantizedAabbMin[2] = quantizedNode.m_quantizedAabbMin[2];
m_quantizedAabbMax[0] = quantizedNode.m_quantizedAabbMax[0];
m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1];
m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2];
}
}
;
class btNodeOverlapCallback
{
public:
virtual ~btNodeOverlapCallback() {};
virtual void processNode(int subPart, int triangleIndex) = 0;
};
#include "LinearMath/btAlignedAllocator.h"
#include "LinearMath/btAlignedObjectArray.h"
///for code readability:
typedef btAlignedObjectArray<btOptimizedBvhNode> NodeArray;
typedef btAlignedObjectArray<btQuantizedBvhNode> QuantizedNodeArray;
typedef btAlignedObjectArray<btBvhSubtreeInfo> BvhSubtreeInfoArray;
///The btQuantizedBvh class stores an AABB tree that can be quickly traversed on CPU and Cell SPU.
///It is used by the btBvhTriangleMeshShape as midphase, and by the btMultiSapBroadphase.
///It is recommended to use quantization for better performance and lower memory requirements.
ATTRIBUTE_ALIGNED16(class) btQuantizedBvh
{
protected:
NodeArray m_leafNodes;
NodeArray m_contiguousNodes;
QuantizedNodeArray m_quantizedLeafNodes;
QuantizedNodeArray m_quantizedContiguousNodes;
int m_curNodeIndex;
//quantization data
bool m_useQuantization;
btVector3 m_bvhAabbMin;
btVector3 m_bvhAabbMax;
btVector3 m_bvhQuantization;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
enum btTraversalMode
{
TRAVERSAL_STACKLESS = 0,
TRAVERSAL_STACKLESS_CACHE_FRIENDLY,
TRAVERSAL_RECURSIVE
};
protected:
btTraversalMode m_traversalMode;
BvhSubtreeInfoArray m_SubtreeHeaders;
//This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
int m_subtreeHeaderCount;
///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!)
///this might be refactored into a virtual, it is usually not calculated at run-time
void setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin)
{
if (m_useQuantization)
{
quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin,0);
} else
{
m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin;
}
}
void setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax)
{
if (m_useQuantization)
{
quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax,1);
} else
{
m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax;
}
}
btVector3 getAabbMin(int nodeIndex) const
{
if (m_useQuantization)
{
return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMin[0]);
}
//non-quantized
return m_leafNodes[nodeIndex].m_aabbMinOrg;
}
btVector3 getAabbMax(int nodeIndex) const
{
if (m_useQuantization)
{
return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]);
}
//non-quantized
return m_leafNodes[nodeIndex].m_aabbMaxOrg;
}
void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex)
{
if (m_useQuantization)
{
m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex;
}
else
{
m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex;
}
}
void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax)
{
if (m_useQuantization)
{
unsigned short int quantizedAabbMin[3];
unsigned short int quantizedAabbMax[3];
quantize(quantizedAabbMin,newAabbMin,0);
quantize(quantizedAabbMax,newAabbMax,1);
for (int i=0;i<3;i++)
{
if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i])
m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i];
if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i])
m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i];
}
} else
{
//non-quantized
m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin);
m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax);
}
}
void swapLeafNodes(int firstIndex,int secondIndex);
void assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex);
protected:
void buildTree (int startIndex,int endIndex);
int calcSplittingAxis(int startIndex,int endIndex);
int sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis);
void walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
void walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const;
///tree traversal designed for small-memory processors like PS3 SPU
void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal
void walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal
void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const;
#define USE_BANCHLESS 1
#ifdef USE_BANCHLESS
//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
{
return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
& (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
& (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
1, 0));
}
#else
SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
{
bool overlap = true;
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
return overlap;
}
#endif //USE_BANCHLESS
void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex);
public:
btQuantizedBvh();
virtual ~btQuantizedBvh();
///***************************************** expert/internal use only *************************
void setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0));
QuantizedNodeArray& getLeafNodeArray() { return m_quantizedLeafNodes; }
///buildInternal is expert use only: assumes that setQuantizationValues and LeafNodeArray are initialized
void buildInternal();
///***************************************** expert/internal use only *************************
void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
void reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const;
void reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const;
SIMD_FORCE_INLINE void quantize(unsigned short* out, const btVector3& point,int isMax) const
{
btAssert(m_useQuantization);
btAssert(point.getX() <= m_bvhAabbMax.getX());
btAssert(point.getY() <= m_bvhAabbMax.getY());
btAssert(point.getZ() <= m_bvhAabbMax.getZ());
btAssert(point.getX() >= m_bvhAabbMin.getX());
btAssert(point.getY() >= m_bvhAabbMin.getY());
btAssert(point.getZ() >= m_bvhAabbMin.getZ());
btVector3 v = (point - m_bvhAabbMin) * m_bvhQuantization;
///Make sure rounding is done in a way that unQuantize(quantizeWithClamp(...)) is conservative
///end-points always set the first bit, so that they are sorted properly (so that neighbouring AABBs overlap properly)
///todo: double-check this
if (isMax)
{
out[0] = (unsigned short) (((unsigned short)(v.getX()+btScalar(1.)) | 1));
out[1] = (unsigned short) (((unsigned short)(v.getY()+btScalar(1.)) | 1));
out[2] = (unsigned short) (((unsigned short)(v.getZ()+btScalar(1.)) | 1));
} else
{
out[0] = (unsigned short) (((unsigned short)(v.getX()) & 0xfffe));
out[1] = (unsigned short) (((unsigned short)(v.getY()) & 0xfffe));
out[2] = (unsigned short) (((unsigned short)(v.getZ()) & 0xfffe));
}
#ifdef DEBUG_CHECK_DEQUANTIZATION
btVector3 newPoint = unQuantize(out);
if (isMax)
{
if (newPoint.getX() < point.getX())
{
printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX());
}
if (newPoint.getY() < point.getY())
{
printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY());
}
if (newPoint.getZ() < point.getZ())
{
printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ());
}
} else
{
if (newPoint.getX() > point.getX())
{
printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX());
}
if (newPoint.getY() > point.getY())
{
printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY());
}
if (newPoint.getZ() > point.getZ())
{
printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ());
}
}
#endif //DEBUG_CHECK_DEQUANTIZATION
}
SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const btVector3& point2,int isMax) const
{
btAssert(m_useQuantization);
btVector3 clampedPoint(point2);
clampedPoint.setMax(m_bvhAabbMin);
clampedPoint.setMin(m_bvhAabbMax);
quantize(out,clampedPoint,isMax);
}
SIMD_FORCE_INLINE btVector3 unQuantize(const unsigned short* vecIn) const
{
btVector3 vecOut;
vecOut.setValue(
(btScalar)(vecIn[0]) / (m_bvhQuantization.getX()),
(btScalar)(vecIn[1]) / (m_bvhQuantization.getY()),
(btScalar)(vecIn[2]) / (m_bvhQuantization.getZ()));
vecOut += m_bvhAabbMin;
return vecOut;
}
///setTraversalMode let's you choose between stackless, recursive or stackless cache friendly tree traversal. Note this is only implemented for quantized trees.
void setTraversalMode(btTraversalMode traversalMode)
{
m_traversalMode = traversalMode;
}
SIMD_FORCE_INLINE QuantizedNodeArray& getQuantizedNodeArray()
{
return m_quantizedContiguousNodes;
}
SIMD_FORCE_INLINE BvhSubtreeInfoArray& getSubtreeInfoArray()
{
return m_SubtreeHeaders;
}
/////Calculate space needed to store BVH for serialization
unsigned calculateSerializeBufferSize();
/// Data buffer MUST be 16 byte aligned
virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian);
///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
static btQuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian);
static unsigned int getAlignmentSerializationPadding();
SIMD_FORCE_INLINE bool isQuantized()
{
return m_useQuantization;
}
private:
// Special "copy" constructor that allows for in-place deserialization
// Prevents btVector3's default constructor from being called, but doesn't inialize much else
// ownsMemory should most likely be false if deserializing, and if you are not, don't call this (it also changes the function signature, which we need)
btQuantizedBvh(btQuantizedBvh &other, bool ownsMemory);
}
;
#endif //QUANTIZED_BVH_H

View File

@@ -14,83 +14,84 @@ subject to the following restrictions:
*/
#include "btSimpleBroadphase.h"
#include <BulletCollision/BroadphaseCollision/btDispatcher.h>
#include <BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h>
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include <new>
extern int gOverlappingPairs;
void btSimpleBroadphase::validate()
{
for (int i=0;i<m_numProxies;i++)
for (int i=0;i<m_numHandles;i++)
{
for (int j=i+1;j<m_numProxies;j++)
for (int j=i+1;j<m_numHandles;j++)
{
assert(m_pProxies[i] != m_pProxies[j]);
btAssert(&m_pHandles[i] != &m_pHandles[j]);
}
}
}
btSimpleBroadphase::btSimpleBroadphase(int maxProxies)
:btOverlappingPairCache(),
m_firstFreeProxy(0),
m_numProxies(0),
m_maxProxies(maxProxies)
btSimpleBroadphase::btSimpleBroadphase(int maxProxies, btOverlappingPairCache* overlappingPairCache)
:m_pairCache(overlappingPairCache),
m_ownsPairCache(false),
m_invalidPair(0)
{
m_proxies = new btSimpleBroadphaseProxy[maxProxies];
m_freeProxies = new int[maxProxies];
m_pProxies = new btSimpleBroadphaseProxy*[maxProxies];
if (!overlappingPairCache)
{
void* mem = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16);
m_pairCache = new (mem)btHashedOverlappingPairCache();
m_ownsPairCache = true;
}
// allocate handles buffer and put all handles on free list
m_pHandlesRawPtr = btAlignedAlloc(sizeof(btSimpleBroadphaseProxy)*maxProxies,16);
m_pHandles = new(m_pHandlesRawPtr) btSimpleBroadphaseProxy[maxProxies];
m_maxHandles = maxProxies;
m_numHandles = 0;
m_firstFreeHandle = 0;
int i;
for (i=0;i<m_maxProxies;i++)
{
m_freeProxies[i] = i;
for (int i = m_firstFreeHandle; i < maxProxies; i++)
{
m_pHandles[i].SetNextFree(i + 1);
m_pHandles[i].m_uniqueId = i+2;//any UID will do, we just avoid too trivial values (0,1) for debugging purposes
}
m_pHandles[maxProxies - 1].SetNextFree(0);
}
}
btSimpleBroadphase::~btSimpleBroadphase()
{
delete[] m_proxies;
delete []m_freeProxies;
delete [] m_pProxies;
btAlignedFree(m_pHandlesRawPtr);
/*int i;
for (i=m_numProxies-1;i>=0;i--)
if (m_ownsPairCache)
{
BP_Proxy* proxy = m_pProxies[i];
destroyProxy(proxy);
m_pairCache->~btOverlappingPairCache();
btAlignedFree(m_pairCache);
}
*/
}
btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask)
btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* /*dispatcher*/,void* multiSapProxy)
{
if (m_numProxies >= m_maxProxies)
if (m_numHandles >= m_maxHandles)
{
assert(0);
btAssert(0);
return 0; //should never happen, but don't let the game crash ;-)
}
assert(min[0]<= max[0] && min[1]<= max[1] && min[2]<= max[2]);
assert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
int freeIndex= m_freeProxies[m_firstFreeProxy];
btSimpleBroadphaseProxy* proxy = new (&m_proxies[freeIndex])btSimpleBroadphaseProxy(min,max,shapeType,userPtr,collisionFilterGroup,collisionFilterMask);
m_firstFreeProxy++;
btSimpleBroadphaseProxy* proxy1 = &m_proxies[0];
int index = int(proxy - proxy1);
btAssert(index == freeIndex);
m_pProxies[m_numProxies] = proxy;
m_numProxies++;
//validate();
int newHandleIndex = allocHandle();
btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy);
return proxy;
}
@@ -124,34 +125,19 @@ protected:
};
};
void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg)
void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher)
{
int i;
btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
btSimpleBroadphaseProxy* proxy1 = &m_proxies[0];
int index = int(proxy0 - proxy1);
btAssert (index < m_maxProxies);
m_freeProxies[--m_firstFreeProxy] = index;
freeHandle(proxy0);
m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher);
removeOverlappingPairsContainingProxy(proxyOrg);
for (i=0;i<m_numProxies;i++)
{
if (m_pProxies[i] == proxyOrg)
{
m_pProxies[i] = m_pProxies[m_numProxies-1];
break;
}
}
m_numProxies--;
//validate();
}
void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax)
void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/)
{
btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
sbp->m_min = aabbMin;
@@ -186,37 +172,129 @@ public:
}
};
void btSimpleBroadphase::refreshOverlappingPairs()
void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
{
//first check for new overlapping pairs
int i,j;
for (i=0;i<m_numProxies;i++)
if (m_numHandles >= 0)
{
btBroadphaseProxy* proxy0 = m_pProxies[i];
for (j=i+1;j<m_numProxies;j++)
{
btBroadphaseProxy* proxy1 = m_pProxies[j];
btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
if (aabbOverlap(p0,p1))
for (i=0;i<m_numHandles;i++)
{
btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i];
for (j=i+1;j<m_numHandles;j++)
{
if ( !findPair(proxy0,proxy1))
btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j];
btAssert(proxy0 != proxy1);
btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
if (aabbOverlap(p0,p1))
{
addOverlappingPair(proxy0,proxy1);
if ( !m_pairCache->findPair(proxy0,proxy1))
{
m_pairCache->addOverlappingPair(proxy0,proxy1);
}
} else
{
if (!m_pairCache->hasDeferredRemoval())
{
if ( m_pairCache->findPair(proxy0,proxy1))
{
m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher);
}
}
}
}
}
if (m_ownsPairCache && m_pairCache->hasDeferredRemoval())
{
btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray();
//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
m_invalidPair = 0;
btBroadphasePair previousPair;
previousPair.m_pProxy0 = 0;
previousPair.m_pProxy1 = 0;
previousPair.m_algorithm = 0;
for (i=0;i<overlappingPairArray.size();i++)
{
btBroadphasePair& pair = overlappingPairArray[i];
bool isDuplicate = (pair == previousPair);
previousPair = pair;
bool needsRemoval = false;
if (!isDuplicate)
{
bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
if (hasOverlap)
{
needsRemoval = false;//callback->processOverlap(pair);
} else
{
needsRemoval = true;
}
} else
{
//remove duplicate
needsRemoval = true;
//should have no algorithm
btAssert(!pair.m_algorithm);
}
if (needsRemoval)
{
m_pairCache->cleanOverlappingPair(pair,dispatcher);
// m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
// m_overlappingPairArray.pop_back();
pair.m_pProxy0 = 0;
pair.m_pProxy1 = 0;
m_invalidPair++;
gOverlappingPairs--;
}
}
///if you don't like to skip the invalid pairs in the array, execute following code:
#define CLEAN_INVALID_PAIRS 1
#ifdef CLEAN_INVALID_PAIRS
//perform a sort, to sort 'invalid' pairs to the end
overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
m_invalidPair = 0;
#endif//CLEAN_INVALID_PAIRS
}
}
CheckOverlapCallback checkOverlap;
processAllOverlappingPairs(&checkOverlap);
}
bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
return aabbOverlap(p0,p1);
}

View File

@@ -24,35 +24,69 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy
{
btVector3 m_min;
btVector3 m_max;
int m_nextFree;
// int m_handleId;
btSimpleBroadphaseProxy() {};
btSimpleBroadphaseProxy(const btPoint3& minpt,const btPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask)
:btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask),
btSimpleBroadphaseProxy(const btPoint3& minpt,const btPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy)
:btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy),
m_min(minpt),m_max(maxpt)
{
(void)shapeType;
}
SIMD_FORCE_INLINE void SetNextFree(int next) {m_nextFree = next;}
SIMD_FORCE_INLINE int GetNextFree() const {return m_nextFree;}
};
///SimpleBroadphase is a brute force aabb culling broadphase based on O(n^2) aabb checks
class btSimpleBroadphase : public btOverlappingPairCache
///The SimpleBroadphase is just a unit-test for btAxisSweep3, bt32BitAxisSweep3, or btDbvtBroadphase, so use those classes instead.
///It is a brute force aabb culling broadphase based on O(n^2) aabb checks
class btSimpleBroadphase : public btBroadphaseInterface
{
protected:
btSimpleBroadphaseProxy* m_proxies;
int* m_freeProxies;
int m_firstFreeProxy;
btSimpleBroadphaseProxy** m_pProxies;
int m_numProxies;
int m_numHandles; // number of active handles
int m_maxHandles; // max number of handles
btSimpleBroadphaseProxy* m_pHandles; // handles pool
void* m_pHandlesRawPtr;
int m_firstFreeHandle; // free handles list
int allocHandle()
{
btAssert(m_numHandles < m_maxHandles);
int freeHandle = m_firstFreeHandle;
m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree();
m_numHandles++;
return freeHandle;
}
void freeHandle(btSimpleBroadphaseProxy* proxy)
{
int handle = int(proxy-m_pHandles);
btAssert(handle >= 0 && handle < m_maxHandles);
proxy->SetNextFree(m_firstFreeHandle);
m_firstFreeHandle = handle;
m_numHandles--;
}
btOverlappingPairCache* m_pairCache;
bool m_ownsPairCache;
int m_invalidPair;
int m_maxProxies;
inline btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy)
@@ -67,26 +101,48 @@ protected:
protected:
virtual void refreshOverlappingPairs();
public:
btSimpleBroadphase(int maxProxies=16384);
btSimpleBroadphase(int maxProxies=16384,btOverlappingPairCache* overlappingPairCache=0);
virtual ~btSimpleBroadphase();
static bool aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1);
virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask);
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy);
virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
virtual void destroyProxy(btBroadphaseProxy* proxy);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax);
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
btOverlappingPairCache* getOverlappingPairCache()
{
return m_pairCache;
}
const btOverlappingPairCache* getOverlappingPairCache() const
{
return m_pairCache;
}
bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
///will add some transform later
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
{
aabbMin.setValue(-1e30f,-1e30f,-1e30f);
aabbMax.setValue(1e30f,1e30f,1e30f);
}
virtual void printStats()
{
// printf("btSimpleBroadphase.h\n");
// printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles);
}
};

View File

@@ -5,56 +5,149 @@ ${BULLET_PHYSICS_SOURCE_DIR}/src }
ADD_LIBRARY(LibBulletCollision
BroadphaseCollision/btAxisSweep3.cpp
BroadphaseCollision/btAxisSweep3.h
BroadphaseCollision/btBroadphaseProxy.cpp
BroadphaseCollision/btBroadphaseProxy.h
BroadphaseCollision/btCollisionAlgorithm.cpp
BroadphaseCollision/btCollisionAlgorithm.h
BroadphaseCollision/btDispatcher.cpp
BroadphaseCollision/btDispatcher.h
BroadphaseCollision/btDbvtBroadphase.cpp
BroadphaseCollision/btDbvtBroadphase.h
BroadphaseCollision/btDbvt.cpp
BroadphaseCollision/btDbvt.h
BroadphaseCollision/btMultiSapBroadphase.cpp
BroadphaseCollision/btMultiSapBroadphase.h
BroadphaseCollision/btOverlappingPairCache.cpp
BroadphaseCollision/btOverlappingPairCache.h
BroadphaseCollision/btOverlappingPairCallback.h
BroadphaseCollision/btQuantizedBvh.cpp
BroadphaseCollision/btQuantizedBvh.h
BroadphaseCollision/btSimpleBroadphase.cpp
BroadphaseCollision/btSimpleBroadphase.h
CollisionDispatch/btCollisionDispatcher.cpp
CollisionDispatch/btCollisionDispatcher.h
CollisionDispatch/btCollisionObject.cpp
CollisionDispatch/btCollisionObject.h
CollisionDispatch/btCollisionWorld.cpp
CollisionDispatch/btCollisionWorld.h
CollisionDispatch/btCompoundCollisionAlgorithm.cpp
CollisionDispatch/btCompoundCollisionAlgorithm.h
CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
CollisionDispatch/btDefaultCollisionConfiguration.cpp
CollisionDispatch/btDefaultCollisionConfiguration.h
CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
CollisionDispatch/btSphereSphereCollisionAlgorithm.h
CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
CollisionDispatch/btBoxBoxCollisionAlgorithm.h
CollisionDispatch/btBoxBoxDetector.cpp
CollisionDispatch/btBoxBoxDetector.h
CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
CollisionDispatch/btSphereBoxCollisionAlgorithm.h
CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
CollisionDispatch/btConvexConvexAlgorithm.cpp
CollisionDispatch/btConvexConvexAlgorithm.h
CollisionDispatch/btEmptyCollisionAlgorithm.cpp
CollisionDispatch/btEmptyCollisionAlgorithm.h
CollisionDispatch/btManifoldResult.cpp
CollisionDispatch/btManifoldResult.h
CollisionDispatch/btSimulationIslandManager.cpp
CollisionDispatch/btSimulationIslandManager.h
CollisionDispatch/btUnionFind.cpp
CollisionDispatch/btUnionFind.h
CollisionDispatch/SphereTriangleDetector.cpp
CollisionDispatch/SphereTriangleDetector.h
CollisionShapes/btBoxShape.cpp
CollisionShapes/btBoxShape.h
CollisionShapes/btBvhTriangleMeshShape.cpp
CollisionShapes/btBvhTriangleMeshShape.h
CollisionShapes/btCapsuleShape.cpp
CollisionShapes/btCapsuleShape.h
CollisionShapes/btCollisionShape.cpp
CollisionShapes/btCollisionShape.h
CollisionShapes/btCompoundShape.cpp
CollisionShapes/btCompoundShape.h
CollisionShapes/btConcaveShape.cpp
CollisionShapes/btConcaveShape.h
CollisionShapes/btConeShape.cpp
CollisionShapes/btConeShape.h
CollisionShapes/btConvexHullShape.cpp
CollisionShapes/btConvexHullShape.h
CollisionShapes/btConvexShape.cpp
CollisionShapes/btConvexShape.h
CollisionShapes/btConvexInternalShape.cpp
CollisionShapes/btConvexInternalShape.h
CollisionShapes/btConvexTriangleMeshShape.cpp
CollisionShapes/btConvexTriangleMeshShape.h
CollisionShapes/btCylinderShape.cpp
CollisionShapes/btCylinderShape.h
CollisionShapes/btEmptyShape.cpp
CollisionShapes/btEmptyShape.h
CollisionShapes/btHeightfieldTerrainShape.cpp
CollisionShapes/btHeightfieldTerrainShape.h
CollisionShapes/btMinkowskiSumShape.cpp
CollisionShapes/btMinkowskiSumShape.h
CollisionShapes/btMaterial.h
CollisionShapes/btMultimaterialTriangleMeshShape.cpp
CollisionShapes/btMultimaterialTriangleMeshShape.h
CollisionShapes/btMultiSphereShape.cpp
CollisionShapes/btMultiSphereShape.h
CollisionShapes/btOptimizedBvh.cpp
CollisionShapes/btOptimizedBvh.h
CollisionShapes/btPolyhedralConvexShape.cpp
CollisionShapes/btPolyhedralConvexShape.h
CollisionShapes/btScaledBvhTriangleMeshShape.cpp
CollisionShapes/btScaledBvhTriangleMeshShape.h
CollisionShapes/btTetrahedronShape.cpp
CollisionShapes/btTetrahedronShape.h
CollisionShapes/btSphereShape.cpp
CollisionShapes/btSphereShape.h
CollisionShapes/btShapeHull.h
CollisionShapes/btShapeHull.cpp
CollisionShapes/btStaticPlaneShape.cpp
CollisionShapes/btStaticPlaneShape.h
CollisionShapes/btStridingMeshInterface.cpp
CollisionShapes/btStridingMeshInterface.h
CollisionShapes/btTriangleCallback.cpp
CollisionShapes/btTriangleCallback.h
CollisionShapes/btTriangleBuffer.cpp
CollisionShapes/btTriangleBuffer.h
CollisionShapes/btTriangleIndexVertexArray.cpp
CollisionShapes/btTriangleIndexVertexArray.h
CollisionShapes/btTriangleIndexVertexMaterialArray.h
CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
CollisionShapes/btTriangleMesh.cpp
CollisionShapes/btTriangleMesh.h
CollisionShapes/btTriangleMeshShape.cpp
CollisionShapes/btTriangleMeshShape.h
CollisionShapes/btUniformScalingShape.cpp
CollisionShapes/btUniformScalingShape.h
NarrowPhaseCollision/btContinuousConvexCollision.cpp
NarrowPhaseCollision/btContinuousConvexCollision.h
NarrowPhaseCollision/btGjkEpa.cpp
NarrowPhaseCollision/btGjkEpa.h
NarrowPhaseCollision/btGjkEpa2.cpp
NarrowPhaseCollision/btGjkEpa2.h
NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
NarrowPhaseCollision/btConvexCast.cpp
NarrowPhaseCollision/btConvexCast.h
NarrowPhaseCollision/btGjkConvexCast.cpp
NarrowPhaseCollision/btGjkConvexCast.h
NarrowPhaseCollision/btGjkPairDetector.cpp
NarrowPhaseCollision/btGjkPairDetector.h
NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
NarrowPhaseCollision/btPersistentManifold.cpp
NarrowPhaseCollision/btPersistentManifold.h
NarrowPhaseCollision/btRaycastCallback.cpp
NarrowPhaseCollision/btRaycastCallback.h
NarrowPhaseCollision/btSubSimplexConvexCast.cpp
NarrowPhaseCollision/btSubSimplexConvexCast.h
NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
NarrowPhaseCollision/btVoronoiSimplexSolver.h
)

View File

@@ -26,7 +26,7 @@ m_triangle(triangle)
}
void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
{
(void)debugDraw;
@@ -42,7 +42,16 @@ void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact))
{
output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth);
if (swapResults)
{
btVector3 normalOnB = transformB.getBasis()*normal;
btVector3 normalOnA = -normalOnB;
btVector3 pointOnA = transformB*point+normalOnB*depth;
output.addContactPoint(normalOnA,pointOnA,depth);
} else
{
output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth);
}
}
}
@@ -53,6 +62,8 @@ void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
// See also geometrictools.com
// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv
btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest);
btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) {
btVector3 diff = p - from;
btVector3 v = to - from;

View File

@@ -16,8 +16,8 @@ subject to the following restrictions:
#ifndef SPHERE_TRIANGLE_DETECTOR_H
#define SPHERE_TRIANGLE_DETECTOR_H
#include "../NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "../../LinearMath/btPoint3.h"
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "LinearMath/btPoint3.h"
class btSphereShape;
@@ -28,7 +28,7 @@ class btTriangleShape;
/// sphere-triangle to match the btDiscreteCollisionDetectorInterface
struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
{
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw);
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle);

View File

@@ -0,0 +1,85 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "btBoxBoxCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/CollisionShapes/btBoxShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "btBoxBoxDetector.h"
#define USE_PERSISTENT_CONTACTS 1
btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
: btCollisionAlgorithm(ci),
m_ownManifold(false),
m_manifoldPtr(mf)
{
if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0,obj1))
{
m_manifoldPtr = m_dispatcher->getNewManifold(obj0,obj1);
m_ownManifold = true;
}
}
btBoxBoxCollisionAlgorithm::~btBoxBoxCollisionAlgorithm()
{
if (m_ownManifold)
{
if (m_manifoldPtr)
m_dispatcher->releaseManifold(m_manifoldPtr);
}
}
void btBoxBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
return;
btCollisionObject* col0 = body0;
btCollisionObject* col1 = body1;
btBoxShape* box0 = (btBoxShape*)col0->getCollisionShape();
btBoxShape* box1 = (btBoxShape*)col1->getCollisionShape();
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut->setPersistentManifold(m_manifoldPtr);
#ifndef USE_PERSISTENT_CONTACTS
m_manifoldPtr->clearManifold();
#endif //USE_PERSISTENT_CONTACTS
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
input.m_maximumDistanceSquared = 1e30f;
input.m_transformA = body0->getWorldTransform();
input.m_transformB = body1->getWorldTransform();
btBoxBoxDetector detector(box0,box1);
detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
#ifdef USE_PERSISTENT_CONTACTS
// refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added
if (m_ownManifold)
{
resultOut->refreshContactPoints();
}
#endif //USE_PERSISTENT_CONTACTS
}
btScalar btBoxBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/)
{
//not yet
return 1.f;
}

View File

@@ -0,0 +1,66 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BOX_BOX__COLLISION_ALGORITHM_H
#define BOX_BOX__COLLISION_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
///box-box collision detection
class btBoxBoxCollisionAlgorithm : public btCollisionAlgorithm
{
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
public:
btBoxBoxCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btCollisionAlgorithm(ci) {}
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
virtual ~btBoxBoxCollisionAlgorithm();
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
{
if (m_manifoldPtr && m_ownManifold)
{
manifoldArray.push_back(m_manifoldPtr);
}
}
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
int bbsize = sizeof(btBoxBoxCollisionAlgorithm);
void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
return new(ptr) btBoxBoxCollisionAlgorithm(0,ci,body0,body1);
}
};
};
#endif //BOX_BOX__COLLISION_ALGORITHM_H

View File

@@ -0,0 +1,683 @@
/*
* Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith
* Original version is from Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.
* All rights reserved. Email: russ@q12.org Web: www.q12.org
Bullet Continuous Collision Detection and Physics Library
Bullet is Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
///ODE box-box collision detection is adapted to work with Bullet
#include "btBoxBoxDetector.h"
#include "BulletCollision/CollisionShapes/btBoxShape.h"
#include <float.h>
#include <string.h>
btBoxBoxDetector::btBoxBoxDetector(btBoxShape* box1,btBoxShape* box2)
: m_box1(box1),
m_box2(box2)
{
}
// given two boxes (p1,R1,side1) and (p2,R2,side2), collide them together and
// generate contact points. this returns 0 if there is no contact otherwise
// it returns the number of contacts generated.
// `normal' returns the contact normal.
// `depth' returns the maximum penetration depth along that normal.
// `return_code' returns a number indicating the type of contact that was
// detected:
// 1,2,3 = box 2 intersects with a face of box 1
// 4,5,6 = box 1 intersects with a face of box 2
// 7..15 = edge-edge contact
// `maxc' is the maximum number of contacts allowed to be generated, i.e.
// the size of the `contact' array.
// `contact' and `skip' are the contact array information provided to the
// collision functions. this function only fills in the position and depth
// fields.
struct dContactGeom;
#define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)])
#define dInfinity FLT_MAX
/*PURE_INLINE btScalar dDOT (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); }
PURE_INLINE btScalar dDOT13 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,3); }
PURE_INLINE btScalar dDOT31 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,1); }
PURE_INLINE btScalar dDOT33 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,3); }
*/
static btScalar dDOT (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); }
static btScalar dDOT44 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,4); }
static btScalar dDOT41 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,1); }
static btScalar dDOT14 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,4); }
#define dMULTIPLYOP1_331(A,op,B,C) \
{\
(A)[0] op dDOT41((B),(C)); \
(A)[1] op dDOT41((B+1),(C)); \
(A)[2] op dDOT41((B+2),(C)); \
}
#define dMULTIPLYOP0_331(A,op,B,C) \
{ \
(A)[0] op dDOT((B),(C)); \
(A)[1] op dDOT((B+4),(C)); \
(A)[2] op dDOT((B+8),(C)); \
}
#define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C)
#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C)
typedef btScalar dMatrix3[4*3];
void dLineClosestApproach (const btVector3& pa, const btVector3& ua,
const btVector3& pb, const btVector3& ub,
btScalar *alpha, btScalar *beta);
void dLineClosestApproach (const btVector3& pa, const btVector3& ua,
const btVector3& pb, const btVector3& ub,
btScalar *alpha, btScalar *beta)
{
btVector3 p;
p[0] = pb[0] - pa[0];
p[1] = pb[1] - pa[1];
p[2] = pb[2] - pa[2];
btScalar uaub = dDOT(ua,ub);
btScalar q1 = dDOT(ua,p);
btScalar q2 = -dDOT(ub,p);
btScalar d = 1-uaub*uaub;
if (d <= btScalar(0.0001f)) {
// @@@ this needs to be made more robust
*alpha = 0;
*beta = 0;
}
else {
d = 1.f/d;
*alpha = (q1 + uaub*q2)*d;
*beta = (uaub*q1 + q2)*d;
}
}
// find all the intersection points between the 2D rectangle with vertices
// at (+/-h[0],+/-h[1]) and the 2D quadrilateral with vertices (p[0],p[1]),
// (p[2],p[3]),(p[4],p[5]),(p[6],p[7]).
//
// the intersection points are returned as x,y pairs in the 'ret' array.
// the number of intersection points is returned by the function (this will
// be in the range 0 to 8).
static int intersectRectQuad2 (btScalar h[2], btScalar p[8], btScalar ret[16])
{
// q (and r) contain nq (and nr) coordinate points for the current (and
// chopped) polygons
int nq=4,nr=0;
btScalar buffer[16];
btScalar *q = p;
btScalar *r = ret;
for (int dir=0; dir <= 1; dir++) {
// direction notation: xy[0] = x axis, xy[1] = y axis
for (int sign=-1; sign <= 1; sign += 2) {
// chop q along the line xy[dir] = sign*h[dir]
btScalar *pq = q;
btScalar *pr = r;
nr = 0;
for (int i=nq; i > 0; i--) {
// go through all points in q and all lines between adjacent points
if (sign*pq[dir] < h[dir]) {
// this point is inside the chopping line
pr[0] = pq[0];
pr[1] = pq[1];
pr += 2;
nr++;
if (nr & 8) {
q = r;
goto done;
}
}
btScalar *nextq = (i > 1) ? pq+2 : q;
if ((sign*pq[dir] < h[dir]) ^ (sign*nextq[dir] < h[dir])) {
// this line crosses the chopping line
pr[1-dir] = pq[1-dir] + (nextq[1-dir]-pq[1-dir]) /
(nextq[dir]-pq[dir]) * (sign*h[dir]-pq[dir]);
pr[dir] = sign*h[dir];
pr += 2;
nr++;
if (nr & 8) {
q = r;
goto done;
}
}
pq += 2;
}
q = r;
r = (q==ret) ? buffer : ret;
nq = nr;
}
}
done:
if (q != ret) memcpy (ret,q,nr*2*sizeof(btScalar));
return nr;
}
#define M__PI 3.14159265f
// given n points in the plane (array p, of size 2*n), generate m points that
// best represent the whole set. the definition of 'best' here is not
// predetermined - the idea is to select points that give good box-box
// collision detection behavior. the chosen point indexes are returned in the
// array iret (of size m). 'i0' is always the first entry in the array.
// n must be in the range [1..8]. m must be in the range [1..n]. i0 must be
// in the range [0..n-1].
void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[]);
void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[])
{
// compute the centroid of the polygon in cx,cy
int i,j;
btScalar a,cx,cy,q;
if (n==1) {
cx = p[0];
cy = p[1];
}
else if (n==2) {
cx = btScalar(0.5)*(p[0] + p[2]);
cy = btScalar(0.5)*(p[1] + p[3]);
}
else {
a = 0;
cx = 0;
cy = 0;
for (i=0; i<(n-1); i++) {
q = p[i*2]*p[i*2+3] - p[i*2+2]*p[i*2+1];
a += q;
cx += q*(p[i*2]+p[i*2+2]);
cy += q*(p[i*2+1]+p[i*2+3]);
}
q = p[n*2-2]*p[1] - p[0]*p[n*2-1];
a = 1.f/(btScalar(3.0)*(a+q));
cx = a*(cx + q*(p[n*2-2]+p[0]));
cy = a*(cy + q*(p[n*2-1]+p[1]));
}
// compute the angle of each point w.r.t. the centroid
btScalar A[8];
for (i=0; i<n; i++) A[i] = btAtan2(p[i*2+1]-cy,p[i*2]-cx);
// search for points that have angles closest to A[i0] + i*(2*pi/m).
int avail[8];
for (i=0; i<n; i++) avail[i] = 1;
avail[i0] = 0;
iret[0] = i0;
iret++;
for (j=1; j<m; j++) {
a = btScalar(j)*(2*M__PI/m) + A[i0];
if (a > M__PI) a -= 2*M__PI;
btScalar maxdiff=1e9,diff;
#if defined(DEBUG) || defined (_DEBUG)
*iret = i0; // iret is not allowed to keep this value
#endif
for (i=0; i<n; i++) {
if (avail[i]) {
diff = btFabs (A[i]-a);
if (diff > M__PI) diff = 2*M__PI - diff;
if (diff < maxdiff) {
maxdiff = diff;
*iret = i;
}
}
}
#if defined(DEBUG) || defined (_DEBUG)
btAssert (*iret != i0); // ensure iret got set
#endif
avail[*iret] = 0;
iret++;
}
}
int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
const btVector3& side1, const btVector3& p2,
const dMatrix3 R2, const btVector3& side2,
btVector3& normal, btScalar *depth, int *return_code,
int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output);
int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
const btVector3& side1, const btVector3& p2,
const dMatrix3 R2, const btVector3& side2,
btVector3& normal, btScalar *depth, int *return_code,
int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output)
{
const btScalar fudge_factor = btScalar(1.05);
btVector3 p,pp,normalC;
const btScalar *normalR = 0;
btScalar A[3],B[3],R11,R12,R13,R21,R22,R23,R31,R32,R33,
Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33,s,s2,l;
int i,j,invert_normal,code;
// get vector from centers of box 1 to box 2, relative to box 1
p = p2 - p1;
dMULTIPLY1_331 (pp,R1,p); // get pp = p relative to body 1
// get side lengths / 2
A[0] = side1[0]*btScalar(0.5);
A[1] = side1[1]*btScalar(0.5);
A[2] = side1[2]*btScalar(0.5);
B[0] = side2[0]*btScalar(0.5);
B[1] = side2[1]*btScalar(0.5);
B[2] = side2[2]*btScalar(0.5);
// Rij is R1'*R2, i.e. the relative rotation between R1 and R2
R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2);
R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2);
R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2);
Q11 = btFabs(R11); Q12 = btFabs(R12); Q13 = btFabs(R13);
Q21 = btFabs(R21); Q22 = btFabs(R22); Q23 = btFabs(R23);
Q31 = btFabs(R31); Q32 = btFabs(R32); Q33 = btFabs(R33);
// for all 15 possible separating axes:
// * see if the axis separates the boxes. if so, return 0.
// * find the depth of the penetration along the separating axis (s2)
// * if this is the largest depth so far, record it.
// the normal vector will be set to the separating axis with the smallest
// depth. note: normalR is set to point to a column of R1 or R2 if that is
// the smallest depth normal so far. otherwise normalR is 0 and normalC is
// set to a vector relative to body 1. invert_normal is 1 if the sign of
// the normal should be flipped.
#define TST(expr1,expr2,norm,cc) \
s2 = btFabs(expr1) - (expr2); \
if (s2 > 0) return 0; \
if (s2 > s) { \
s = s2; \
normalR = norm; \
invert_normal = ((expr1) < 0); \
code = (cc); \
}
s = -dInfinity;
invert_normal = 0;
code = 0;
// separating axis = u1,u2,u3
TST (pp[0],(A[0] + B[0]*Q11 + B[1]*Q12 + B[2]*Q13),R1+0,1);
TST (pp[1],(A[1] + B[0]*Q21 + B[1]*Q22 + B[2]*Q23),R1+1,2);
TST (pp[2],(A[2] + B[0]*Q31 + B[1]*Q32 + B[2]*Q33),R1+2,3);
// separating axis = v1,v2,v3
TST (dDOT41(R2+0,p),(A[0]*Q11 + A[1]*Q21 + A[2]*Q31 + B[0]),R2+0,4);
TST (dDOT41(R2+1,p),(A[0]*Q12 + A[1]*Q22 + A[2]*Q32 + B[1]),R2+1,5);
TST (dDOT41(R2+2,p),(A[0]*Q13 + A[1]*Q23 + A[2]*Q33 + B[2]),R2+2,6);
// note: cross product axes need to be scaled when s is computed.
// normal (n1,n2,n3) is relative to box 1.
#undef TST
#define TST(expr1,expr2,n1,n2,n3,cc) \
s2 = btFabs(expr1) - (expr2); \
if (s2 > 0) return 0; \
l = btSqrt((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \
if (l > 0) { \
s2 /= l; \
if (s2*fudge_factor > s) { \
s = s2; \
normalR = 0; \
normalC[0] = (n1)/l; normalC[1] = (n2)/l; normalC[2] = (n3)/l; \
invert_normal = ((expr1) < 0); \
code = (cc); \
} \
}
// separating axis = u1 x (v1,v2,v3)
TST(pp[2]*R21-pp[1]*R31,(A[1]*Q31+A[2]*Q21+B[1]*Q13+B[2]*Q12),0,-R31,R21,7);
TST(pp[2]*R22-pp[1]*R32,(A[1]*Q32+A[2]*Q22+B[0]*Q13+B[2]*Q11),0,-R32,R22,8);
TST(pp[2]*R23-pp[1]*R33,(A[1]*Q33+A[2]*Q23+B[0]*Q12+B[1]*Q11),0,-R33,R23,9);
// separating axis = u2 x (v1,v2,v3)
TST(pp[0]*R31-pp[2]*R11,(A[0]*Q31+A[2]*Q11+B[1]*Q23+B[2]*Q22),R31,0,-R11,10);
TST(pp[0]*R32-pp[2]*R12,(A[0]*Q32+A[2]*Q12+B[0]*Q23+B[2]*Q21),R32,0,-R12,11);
TST(pp[0]*R33-pp[2]*R13,(A[0]*Q33+A[2]*Q13+B[0]*Q22+B[1]*Q21),R33,0,-R13,12);
// separating axis = u3 x (v1,v2,v3)
TST(pp[1]*R11-pp[0]*R21,(A[0]*Q21+A[1]*Q11+B[1]*Q33+B[2]*Q32),-R21,R11,0,13);
TST(pp[1]*R12-pp[0]*R22,(A[0]*Q22+A[1]*Q12+B[0]*Q33+B[2]*Q31),-R22,R12,0,14);
TST(pp[1]*R13-pp[0]*R23,(A[0]*Q23+A[1]*Q13+B[0]*Q32+B[1]*Q31),-R23,R13,0,15);
#undef TST
if (!code) return 0;
// if we get to this point, the boxes interpenetrate. compute the normal
// in global coordinates.
if (normalR) {
normal[0] = normalR[0];
normal[1] = normalR[4];
normal[2] = normalR[8];
}
else {
dMULTIPLY0_331 (normal,R1,normalC);
}
if (invert_normal) {
normal[0] = -normal[0];
normal[1] = -normal[1];
normal[2] = -normal[2];
}
*depth = -s;
// compute contact point(s)
if (code > 6) {
// an edge from box 1 touches an edge from box 2.
// find a point pa on the intersecting edge of box 1
btVector3 pa;
btScalar sign;
for (i=0; i<3; i++) pa[i] = p1[i];
for (j=0; j<3; j++) {
sign = (dDOT14(normal,R1+j) > 0) ? btScalar(1.0) : btScalar(-1.0);
for (i=0; i<3; i++) pa[i] += sign * A[j] * R1[i*4+j];
}
// find a point pb on the intersecting edge of box 2
btVector3 pb;
for (i=0; i<3; i++) pb[i] = p2[i];
for (j=0; j<3; j++) {
sign = (dDOT14(normal,R2+j) > 0) ? btScalar(-1.0) : btScalar(1.0);
for (i=0; i<3; i++) pb[i] += sign * B[j] * R2[i*4+j];
}
btScalar alpha,beta;
btVector3 ua,ub;
for (i=0; i<3; i++) ua[i] = R1[((code)-7)/3 + i*4];
for (i=0; i<3; i++) ub[i] = R2[((code)-7)%3 + i*4];
dLineClosestApproach (pa,ua,pb,ub,&alpha,&beta);
for (i=0; i<3; i++) pa[i] += ua[i]*alpha;
for (i=0; i<3; i++) pb[i] += ub[i]*beta;
{
//contact[0].pos[i] = btScalar(0.5)*(pa[i]+pb[i]);
//contact[0].depth = *depth;
btVector3 pointInWorld;
#ifdef USE_CENTER_POINT
for (i=0; i<3; i++)
pointInWorld[i] = (pa[i]+pb[i])*btScalar(0.5);
output.addContactPoint(-normal,pointInWorld,-*depth);
#else
output.addContactPoint(-normal,pb,-*depth);
#endif //
*return_code = code;
}
return 1;
}
// okay, we have a face-something intersection (because the separating
// axis is perpendicular to a face). define face 'a' to be the reference
// face (i.e. the normal vector is perpendicular to this) and face 'b' to be
// the incident face (the closest face of the other box).
const btScalar *Ra,*Rb,*pa,*pb,*Sa,*Sb;
if (code <= 3) {
Ra = R1;
Rb = R2;
pa = p1;
pb = p2;
Sa = A;
Sb = B;
}
else {
Ra = R2;
Rb = R1;
pa = p2;
pb = p1;
Sa = B;
Sb = A;
}
// nr = normal vector of reference face dotted with axes of incident box.
// anr = absolute values of nr.
btVector3 normal2,nr,anr;
if (code <= 3) {
normal2[0] = normal[0];
normal2[1] = normal[1];
normal2[2] = normal[2];
}
else {
normal2[0] = -normal[0];
normal2[1] = -normal[1];
normal2[2] = -normal[2];
}
dMULTIPLY1_331 (nr,Rb,normal2);
anr[0] = btFabs (nr[0]);
anr[1] = btFabs (nr[1]);
anr[2] = btFabs (nr[2]);
// find the largest compontent of anr: this corresponds to the normal
// for the indident face. the other axis numbers of the indicent face
// are stored in a1,a2.
int lanr,a1,a2;
if (anr[1] > anr[0]) {
if (anr[1] > anr[2]) {
a1 = 0;
lanr = 1;
a2 = 2;
}
else {
a1 = 0;
a2 = 1;
lanr = 2;
}
}
else {
if (anr[0] > anr[2]) {
lanr = 0;
a1 = 1;
a2 = 2;
}
else {
a1 = 0;
a2 = 1;
lanr = 2;
}
}
// compute center point of incident face, in reference-face coordinates
btVector3 center;
if (nr[lanr] < 0) {
for (i=0; i<3; i++) center[i] = pb[i] - pa[i] + Sb[lanr] * Rb[i*4+lanr];
}
else {
for (i=0; i<3; i++) center[i] = pb[i] - pa[i] - Sb[lanr] * Rb[i*4+lanr];
}
// find the normal and non-normal axis numbers of the reference box
int codeN,code1,code2;
if (code <= 3) codeN = code-1; else codeN = code-4;
if (codeN==0) {
code1 = 1;
code2 = 2;
}
else if (codeN==1) {
code1 = 0;
code2 = 2;
}
else {
code1 = 0;
code2 = 1;
}
// find the four corners of the incident face, in reference-face coordinates
btScalar quad[8]; // 2D coordinate of incident face (x,y pairs)
btScalar c1,c2,m11,m12,m21,m22;
c1 = dDOT14 (center,Ra+code1);
c2 = dDOT14 (center,Ra+code2);
// optimize this? - we have already computed this data above, but it is not
// stored in an easy-to-index format. for now it's quicker just to recompute
// the four dot products.
m11 = dDOT44 (Ra+code1,Rb+a1);
m12 = dDOT44 (Ra+code1,Rb+a2);
m21 = dDOT44 (Ra+code2,Rb+a1);
m22 = dDOT44 (Ra+code2,Rb+a2);
{
btScalar k1 = m11*Sb[a1];
btScalar k2 = m21*Sb[a1];
btScalar k3 = m12*Sb[a2];
btScalar k4 = m22*Sb[a2];
quad[0] = c1 - k1 - k3;
quad[1] = c2 - k2 - k4;
quad[2] = c1 - k1 + k3;
quad[3] = c2 - k2 + k4;
quad[4] = c1 + k1 + k3;
quad[5] = c2 + k2 + k4;
quad[6] = c1 + k1 - k3;
quad[7] = c2 + k2 - k4;
}
// find the size of the reference face
btScalar rect[2];
rect[0] = Sa[code1];
rect[1] = Sa[code2];
// intersect the incident and reference faces
btScalar ret[16];
int n = intersectRectQuad2 (rect,quad,ret);
if (n < 1) return 0; // this should never happen
// convert the intersection points into reference-face coordinates,
// and compute the contact position and depth for each point. only keep
// those points that have a positive (penetrating) depth. delete points in
// the 'ret' array as necessary so that 'point' and 'ret' correspond.
btScalar point[3*8]; // penetrating contact points
btScalar dep[8]; // depths for those points
btScalar det1 = 1.f/(m11*m22 - m12*m21);
m11 *= det1;
m12 *= det1;
m21 *= det1;
m22 *= det1;
int cnum = 0; // number of penetrating contact points found
for (j=0; j < n; j++) {
btScalar k1 = m22*(ret[j*2]-c1) - m12*(ret[j*2+1]-c2);
btScalar k2 = -m21*(ret[j*2]-c1) + m11*(ret[j*2+1]-c2);
for (i=0; i<3; i++) point[cnum*3+i] =
center[i] + k1*Rb[i*4+a1] + k2*Rb[i*4+a2];
dep[cnum] = Sa[codeN] - dDOT(normal2,point+cnum*3);
if (dep[cnum] >= 0) {
ret[cnum*2] = ret[j*2];
ret[cnum*2+1] = ret[j*2+1];
cnum++;
}
}
if (cnum < 1) return 0; // this should never happen
// we can't generate more contacts than we actually have
if (maxc > cnum) maxc = cnum;
if (maxc < 1) maxc = 1;
if (cnum <= maxc) {
// we have less contacts than we need, so we use them all
for (j=0; j < cnum; j++) {
//AddContactPoint...
//dContactGeom *con = CONTACT(contact,skip*j);
//for (i=0; i<3; i++) con->pos[i] = point[j*3+i] + pa[i];
//con->depth = dep[j];
btVector3 pointInWorld;
for (i=0; i<3; i++)
pointInWorld[i] = point[j*3+i] + pa[i];
output.addContactPoint(-normal,pointInWorld,-dep[j]);
}
}
else {
// we have more contacts than are wanted, some of them must be culled.
// find the deepest point, it is always the first contact.
int i1 = 0;
btScalar maxdepth = dep[0];
for (i=1; i<cnum; i++) {
if (dep[i] > maxdepth) {
maxdepth = dep[i];
i1 = i;
}
}
int iret[8];
cullPoints2 (cnum,ret,maxc,i1,iret);
for (j=0; j < maxc; j++) {
// dContactGeom *con = CONTACT(contact,skip*j);
// for (i=0; i<3; i++) con->pos[i] = point[iret[j]*3+i] + pa[i];
// con->depth = dep[iret[j]];
btVector3 posInWorld;
for (i=0; i<3; i++)
posInWorld[i] = point[iret[j]*3+i] + pa[i];
output.addContactPoint(-normal,posInWorld,-dep[iret[j]]);
}
cnum = maxc;
}
*return_code = code;
return cnum;
}
void btBoxBoxDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* /*debugDraw*/,bool /*swapResults*/)
{
const btTransform& transformA = input.m_transformA;
const btTransform& transformB = input.m_transformB;
int skip = 0;
dContactGeom *contact = 0;
dMatrix3 R1;
dMatrix3 R2;
for (int j=0;j<3;j++)
{
R1[0+4*j] = transformA.getBasis()[j].x();
R2[0+4*j] = transformB.getBasis()[j].x();
R1[1+4*j] = transformA.getBasis()[j].y();
R2[1+4*j] = transformB.getBasis()[j].y();
R1[2+4*j] = transformA.getBasis()[j].z();
R2[2+4*j] = transformB.getBasis()[j].z();
}
btVector3 normal;
btScalar depth;
int return_code;
int maxc = 4;
dBoxBox2 (transformA.getOrigin(),
R1,
2.f*m_box1->getHalfExtentsWithMargin(),
transformB.getOrigin(),
R2,
2.f*m_box2->getHalfExtentsWithMargin(),
normal, &depth, &return_code,
maxc, contact, skip,
output
);
}

View File

@@ -0,0 +1,44 @@
/*
* Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith
* Original version is from Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.
* All rights reserved. Email: russ@q12.org Web: www.q12.org
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BOX_BOX_DETECTOR_H
#define BOX_BOX_DETECTOR_H
class btBoxShape;
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
/// btBoxBoxDetector wraps the ODE box-box collision detector
/// re-distributed under the Zlib license with permission from Russell L. Smith
struct btBoxBoxDetector : public btDiscreteCollisionDetectorInterface
{
btBoxShape* m_box1;
btBoxShape* m_box2;
public:
btBoxBoxDetector(btBoxShape* box1,btBoxShape* box2);
virtual ~btBoxBoxDetector() {};
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
};
#endif //BT_BOX_BOX_DETECTOR_H

View File

@@ -0,0 +1,47 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_COLLISION_CONFIGURATION
#define BT_COLLISION_CONFIGURATION
struct btCollisionAlgorithmCreateFunc;
class btStackAlloc;
class btPoolAllocator;
///btCollisionConfiguration allows to configure Bullet collision detection
///stack allocator size, default collision algorithms and persistent manifold pool size
///todo: describe the meaning
class btCollisionConfiguration
{
public:
virtual ~btCollisionConfiguration()
{
}
///memory pools
virtual btPoolAllocator* getPersistentManifoldPool() = 0;
virtual btPoolAllocator* getCollisionAlgorithmPool() = 0;
virtual btStackAlloc* getStackAllocator() = 0;
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0;
};
#endif //BT_COLLISION_CONFIGURATION

View File

@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef COLLISION_CREATE_FUNC
#define COLLISION_CREATE_FUNC
#include "../../LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
class btCollisionAlgorithm;
class btCollisionObject;

View File

@@ -19,69 +19,39 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
#include "LinearMath/btPoolAllocator.h"
#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
int gNumManifold = 0;
#ifdef BT_DEBUG
#include <stdio.h>
#endif
btCollisionDispatcher::btCollisionDispatcher(bool noDefaultAlgorithms):
m_count(0),
m_useIslands(true),
m_convexConvexCreateFunc(0),
m_convexConcaveCreateFunc(0),
m_swappedConvexConcaveCreateFunc(0),
m_compoundCreateFunc(0),
m_swappedCompoundCreateFunc(0),
m_emptyCreateFunc(0)
{
(void)noDefaultAlgorithms;
int i;
setNearCallback(defaultNearCallback);
m_emptyCreateFunc = new btEmptyAlgorithm::CreateFunc;
for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
{
for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
{
m_doubleDispatch[i][j] = m_emptyCreateFunc;
}
}
}
//if you want to not link with the default collision algorithms, you can
//define BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
//in your Bullet library build system
#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
btCollisionDispatcher::btCollisionDispatcher ():
btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration):
m_count(0),
m_useIslands(true)
m_useIslands(true),
m_staticWarningReported(false),
m_collisionConfiguration(collisionConfiguration)
{
int i;
setNearCallback(defaultNearCallback);
//default CreationFunctions, filling the m_doubleDispatch table
m_convexConvexCreateFunc = new btConvexConvexAlgorithm::CreateFunc;
m_convexConcaveCreateFunc = new btConvexConcaveCollisionAlgorithm::CreateFunc;
m_swappedConvexConcaveCreateFunc = new btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
m_compoundCreateFunc = new btCompoundCollisionAlgorithm::CreateFunc;
m_swappedCompoundCreateFunc = new btCompoundCollisionAlgorithm::SwappedCreateFunc;
m_emptyCreateFunc = new btEmptyAlgorithm::CreateFunc;
m_collisionAlgorithmPoolAllocator = collisionConfiguration->getCollisionAlgorithmPool();
m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool();
for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
{
for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
{
m_doubleDispatch[i][j] = internalFindCreateFunc(i,j);
m_doubleDispatch[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i,j);
assert(m_doubleDispatch[i][j]);
}
}
@@ -89,8 +59,6 @@ btCollisionDispatcher::btCollisionDispatcher ():
};
#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
{
@@ -99,12 +67,6 @@ void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int prox
btCollisionDispatcher::~btCollisionDispatcher()
{
delete m_convexConvexCreateFunc;
delete m_convexConcaveCreateFunc;
delete m_swappedConvexConcaveCreateFunc;
delete m_compoundCreateFunc;
delete m_swappedCompoundCreateFunc;
delete m_emptyCreateFunc;
}
btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
@@ -117,7 +79,18 @@ btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
btCollisionObject* body0 = (btCollisionObject*)b0;
btCollisionObject* body1 = (btCollisionObject*)b1;
btPersistentManifold* manifold = new btPersistentManifold (body0,body1);
void* mem = 0;
if (m_persistentManifoldPoolAllocator->getFreeCount())
{
mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold));
} else
{
mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
}
btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0);
manifold->m_index1a = m_manifoldsPtr.size();
m_manifoldsPtr.push_back(manifold);
return manifold;
@@ -137,13 +110,19 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
//printf("releaseManifold: gNumManifold %d\n",gNumManifold);
clearManifold(manifold);
///todo: this can be improved a lot, linear search might be slow part!
int findIndex = m_manifoldsPtr.findLinearSearch(manifold);
if (findIndex < m_manifoldsPtr.size())
int findIndex = manifold->m_index1a;
btAssert(findIndex < m_manifoldsPtr.size());
m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
m_manifoldsPtr[findIndex]->m_index1a = findIndex;
m_manifoldsPtr.pop_back();
manifold->~btPersistentManifold();
if (m_persistentManifoldPoolAllocator->validPtr(manifold))
{
m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
m_manifoldsPtr.pop_back();
delete manifold;
m_persistentManifoldPoolAllocator->freeMemory(manifold);
} else
{
btAlignedFree(manifold);
}
}
@@ -152,99 +131,19 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold)
{
#ifdef USE_DISPATCH_REGISTRY_ARRAY
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher = this;
ci.m_dispatcher1 = this;
ci.m_manifold = sharedManifold;
btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]
->CreateCollisionAlgorithm(ci,body0,body1);
#else
btCollisionAlgorithm* algo = internalFindAlgorithm(body0,body1);
#endif //USE_DISPATCH_REGISTRY_ARRAY
btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0,body1);
return algo;
}
#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
btCollisionAlgorithmCreateFunc* btCollisionDispatcher::internalFindCreateFunc(int proxyType0,int proxyType1)
{
if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
{
return m_convexConvexCreateFunc;
}
if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
{
return m_convexConcaveCreateFunc;
}
if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
{
return m_swappedConvexConcaveCreateFunc;
}
if (btBroadphaseProxy::isCompound(proxyType0))
{
return m_compoundCreateFunc;
} else
{
if (btBroadphaseProxy::isCompound(proxyType1))
{
return m_swappedCompoundCreateFunc;
}
}
//failed to find an algorithm
return m_emptyCreateFunc;
}
#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
#ifndef USE_DISPATCH_REGISTRY_ARRAY
btCollisionAlgorithm* btCollisionDispatcher::internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold)
{
m_count++;
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher = this;
if (body0->getCollisionShape()->isConvex() && body1->getCollisionShape()->isConvex() )
{
return new btConvexConvexAlgorithm(sharedManifold,ci,body0,body1);
}
if (body0->getCollisionShape()->isConvex() && body1->getCollisionShape()->isConcave())
{
return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
}
if (body1->getCollisionShape()->isConvex() && body0->getCollisionShape()->isConcave())
{
return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
}
if (body0->getCollisionShape()->isCompound())
{
return new btCompoundCollisionAlgorithm(ci,body0,body1,false);
} else
{
if (body1->getCollisionShape()->isCompound())
{
return new btCompoundCollisionAlgorithm(ci,body0,body1,true);
}
}
//failed to find an algorithm
return new btEmptyAlgorithm(ci);
}
#endif //USE_DISPATCH_REGISTRY_ARRAY
bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1)
{
@@ -264,13 +163,19 @@ bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionO
bool needsCollision = true;
//broadphase filtering already deals with this
if ((body0->isStaticObject() || body0->isKinematicObject()) &&
(body1->isStaticObject() || body1->isKinematicObject()))
#ifdef BT_DEBUG
if (!m_staticWarningReported)
{
printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
//broadphase filtering already deals with this
if ((body0->isStaticObject() || body0->isKinematicObject()) &&
(body1->isStaticObject() || body1->isKinematicObject()))
{
m_staticWarningReported = true;
printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
}
}
#endif //BT_DEBUG
if ((!body0->isActive()) && (!body1->isActive()))
needsCollision = false;
else if (!body0->checkCollideWith(body1))
@@ -286,23 +191,25 @@ bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionO
///this is useful for the collision dispatcher.
class btCollisionPairCallback : public btOverlapCallback
{
btDispatcherInfo& m_dispatchInfo;
const btDispatcherInfo& m_dispatchInfo;
btCollisionDispatcher* m_dispatcher;
public:
btCollisionPairCallback(btDispatcherInfo& dispatchInfo,btCollisionDispatcher* dispatcher)
btCollisionPairCallback(const btDispatcherInfo& dispatchInfo,btCollisionDispatcher* dispatcher)
:m_dispatchInfo(dispatchInfo),
m_dispatcher(dispatcher)
{
}
btCollisionPairCallback& operator=(btCollisionPairCallback& other)
/*btCollisionPairCallback& operator=(btCollisionPairCallback& other)
{
m_dispatchInfo = other.m_dispatchInfo;
m_dispatcher = other.m_dispatcher;
return *this;
}
*/
virtual ~btCollisionPairCallback() {}
@@ -316,13 +223,14 @@ public:
};
void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo)
void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher)
{
//m_blockedForChanges = true;
btCollisionPairCallback collisionCallback(dispatchInfo,this);
pairCache->processAllOverlappingPairs(&collisionCallback);
pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher);
//m_blockedForChanges = false;
@@ -332,7 +240,7 @@ void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pa
//by default, Bullet will use this near callback
void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo)
void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
{
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
@@ -365,3 +273,26 @@ void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair,
}
}
void* btCollisionDispatcher::allocateCollisionAlgorithm(int size)
{
if (m_collisionAlgorithmPoolAllocator->getFreeCount())
{
return m_collisionAlgorithmPoolAllocator->allocate(size);
}
//warn user for overflow?
return btAlignedAlloc(static_cast<size_t>(size), 16);
}
void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr)
{
if (m_collisionAlgorithmPoolAllocator->validPtr(ptr))
{
m_collisionAlgorithmPoolAllocator->freeMemory(ptr);
} else
{
btAlignedFree(ptr);
}
}

View File

@@ -16,17 +16,18 @@ subject to the following restrictions:
#ifndef COLLISION__DISPATCHER_H
#define COLLISION__DISPATCHER_H
#include "../BroadphaseCollision/btDispatcher.h"
#include "../NarrowPhaseCollision/btPersistentManifold.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
#include "../CollisionDispatch/btManifoldResult.h"
#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../../LinearMath/btAlignedObjectArray.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "LinearMath/btAlignedObjectArray.h"
class btIDebugDraw;
class btOverlappingPairCache;
class btPoolAllocator;
class btCollisionConfiguration;
#include "btCollisionCreateFunc.h"
@@ -34,7 +35,7 @@ class btOverlappingPairCache;
class btCollisionDispatcher;
///user can override this nearcallback for collision filtering and more finegrained control over collision detection
typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo);
typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo);
///btCollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs.
@@ -46,26 +47,22 @@ class btCollisionDispatcher : public btDispatcher
btAlignedObjectArray<btPersistentManifold*> m_manifoldsPtr;
bool m_useIslands;
bool m_staticWarningReported;
btManifoldResult m_defaultManifoldResult;
btNearCallback m_nearCallback;
btPoolAllocator* m_collisionAlgorithmPoolAllocator;
btPoolAllocator* m_persistentManifoldPoolAllocator;
btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
btCollisionAlgorithmCreateFunc* internalFindCreateFunc(int proxyType0,int proxyType1);
//default CreationFunctions, filling the m_doubleDispatch table
btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc;
btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc;
btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc;
btCollisionAlgorithmCreateFunc* m_compoundCreateFunc;
btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc;
btCollisionAlgorithmCreateFunc* m_emptyCreateFunc;
btCollisionConfiguration* m_collisionConfiguration;
#ifndef USE_DISPATCH_REGISTRY_ARRAY
btCollisionAlgorithm* internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold = 0);
#endif //USE_DISPATCH_REGISTRY_ARRAY
public:
@@ -92,11 +89,7 @@ public:
return m_manifoldsPtr[index];
}
///the default constructor creates/register default collision algorithms, for convex, compound and concave shape support
btCollisionDispatcher ();
///a special constructor that doesn't create/register the default collision algorithms
btCollisionDispatcher(bool noDefaultAlgorithms);
btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration);
virtual ~btCollisionDispatcher();
@@ -114,7 +107,7 @@ public:
virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1);
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo);
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ;
void setNearCallback(btNearCallback nearCallback)
{
@@ -127,7 +120,26 @@ public:
}
//by default, Bullet will use this near callback
static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo);
static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo);
virtual void* allocateCollisionAlgorithm(int size);
virtual void freeCollisionAlgorithm(void* ptr);
btCollisionConfiguration* getCollisionConfiguration()
{
return m_collisionConfiguration;
}
const btCollisionConfiguration* getCollisionConfiguration() const
{
return m_collisionConfiguration;
}
void setCollisionConfiguration(btCollisionConfiguration* config)
{
m_collisionConfiguration = config;
}
};

View File

@@ -13,18 +13,25 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "btCollisionObject.h"
btCollisionObject::btCollisionObject()
: m_broadphaseHandle(0),
m_collisionShape(0),
m_collisionFlags(0),
m_rootCollisionShape(0),
m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT),
m_islandTag1(-1),
m_companionId(-1),
m_activationState1(1),
m_deactivationTime(btScalar(0.)),
m_friction(btScalar(0.5)),
m_restitution(btScalar(0.)),
m_userObjectPointer(0),
m_internalType(CO_COLLISION_OBJECT),
m_hitFraction(btScalar(1.)),
m_ccdSweptSphereRadius(btScalar(0.)),
m_ccdSquareMotionThreshold(btScalar(0.)),
m_ccdMotionThreshold(btScalar(0.)),
m_checkCollideWith(false)
{
@@ -55,3 +62,4 @@ void btCollisionObject::activate(bool forceActivation)
}

View File

@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef COLLISION_OBJECT_H
#define COLLISION_OBJECT_H
#include "../../LinearMath/btTransform.h"
#include "LinearMath/btTransform.h"
//island management, m_activationState1
#define ACTIVE_TAG 1
@@ -27,7 +27,8 @@ subject to the following restrictions:
struct btBroadphaseProxy;
class btCollisionShape;
#include "../../LinearMath/btMotionState.h"
#include "LinearMath/btMotionState.h"
#include "LinearMath/btAlignedAllocator.h"
@@ -50,6 +51,11 @@ protected:
btVector3 m_interpolationAngularVelocity;
btBroadphaseProxy* m_broadphaseHandle;
btCollisionShape* m_collisionShape;
///m_rootCollisionShape is temporarily used to store the original collision shape
///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
///If it is NULL, the m_collisionShape is not temporarily replaced.
btCollisionShape* m_rootCollisionShape;
int m_collisionFlags;
@@ -65,8 +71,9 @@ protected:
///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
void* m_userObjectPointer;
///m_internalOwner is reserved to point to Bullet's btRigidBody. Don't use this, use m_userObjectPointer instead.
void* m_internalOwner;
///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody etc.
///do not assign your own m_internalType unless you write a new dynamics object class.
int m_internalType;
///time of impact calculation
btScalar m_hitFraction;
@@ -74,21 +81,23 @@ protected:
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
btScalar m_ccdSweptSphereRadius;
/// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold
btScalar m_ccdSquareMotionThreshold;
/// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
btScalar m_ccdMotionThreshold;
/// If some object should have elaborate collision filtering by sub-classes
bool m_checkCollideWith;
char m_pad[7];
virtual bool checkCollideWithOverride(btCollisionObject* co)
virtual bool checkCollideWithOverride(btCollisionObject* /* co */)
{
return true;
}
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
enum CollisionFlags
{
CF_STATIC_OBJECT= 1,
@@ -97,29 +106,35 @@ public:
CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution)
};
enum CollisionObjectTypes
{
CO_COLLISION_OBJECT =1,
CO_RIGID_BODY,
CO_SOFT_BODY
};
inline bool mergesSimulationIslands() const
SIMD_FORCE_INLINE bool mergesSimulationIslands() const
{
///static objects, kinematic and object without contact response don't merge islands
return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0);
}
inline bool isStaticObject() const {
SIMD_FORCE_INLINE bool isStaticObject() const {
return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
}
inline bool isKinematicObject() const
SIMD_FORCE_INLINE bool isKinematicObject() const
{
return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0;
}
inline bool isStaticOrKinematicObject() const
SIMD_FORCE_INLINE bool isStaticOrKinematicObject() const
{
return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ;
}
inline bool hasContactResponse() const {
SIMD_FORCE_INLINE bool hasContactResponse() const {
return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0;
}
@@ -131,20 +146,35 @@ public:
void setCollisionShape(btCollisionShape* collisionShape)
{
m_collisionShape = collisionShape;
m_rootCollisionShape = collisionShape;
}
const btCollisionShape* getCollisionShape() const
SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const
{
return m_collisionShape;
}
btCollisionShape* getCollisionShape()
SIMD_FORCE_INLINE btCollisionShape* getCollisionShape()
{
return m_collisionShape;
}
SIMD_FORCE_INLINE const btCollisionShape* getRootCollisionShape() const
{
return m_rootCollisionShape;
}
SIMD_FORCE_INLINE btCollisionShape* getRootCollisionShape()
{
return m_rootCollisionShape;
}
///Avoid using this internal API call
///internalSetTemporaryCollisionShape is used to temporary replace the actual collision shape by a child collision shape.
void internalSetTemporaryCollisionShape(btCollisionShape* collisionShape)
{
m_collisionShape = collisionShape;
}
int getActivationState() const { return m_activationState1;}
@@ -186,14 +216,9 @@ public:
}
///reserved for Bullet internal usage
void* getInternalOwner()
int getInternalType() const
{
return m_internalOwner;
}
const void* getInternalOwner() const
{
return m_internalOwner;
return m_internalType;
}
btTransform& getWorldTransform()
@@ -243,6 +268,15 @@ public:
m_interpolationWorldTransform = trans;
}
void setInterpolationLinearVelocity(const btVector3& linvel)
{
m_interpolationLinearVelocity = linvel;
}
void setInterpolationAngularVelocity(const btVector3& angvel)
{
m_interpolationAngularVelocity = angvel;
}
const btVector3& getInterpolationLinearVelocity() const
{
@@ -307,16 +341,22 @@ public:
m_ccdSweptSphereRadius = radius;
}
btScalar getCcdMotionThreshold() const
{
return m_ccdMotionThreshold;
}
btScalar getCcdSquareMotionThreshold() const
{
return m_ccdSquareMotionThreshold;
return m_ccdMotionThreshold*m_ccdMotionThreshold;
}
/// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold
void setCcdSquareMotionThreshold(btScalar ccdSquareMotionThreshold)
/// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
void setCcdMotionThreshold(btScalar ccdMotionThreshold)
{
m_ccdSquareMotionThreshold = ccdSquareMotionThreshold;
m_ccdMotionThreshold = ccdMotionThreshold*ccdMotionThreshold;
}
///users can point to their objects, userPointer is not used by Bullet
@@ -331,6 +371,7 @@ public:
m_userObjectPointer = userPointer;
}
inline bool checkCollideWith(btCollisionObject* co)
{
if (m_checkCollideWith)
@@ -338,9 +379,6 @@ public:
return true;
}
}
;
};
#endif //COLLISION_OBJECT_H

View File

@@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
@@ -18,59 +18,57 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting
#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" //for raycasting
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting
#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "LinearMath/btAabbUtil2.h"
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btStackAlloc.h"
//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize)
btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration)
:m_dispatcher1(dispatcher),
m_broadphasePairCache(pairCache),
m_ownsDispatcher(false),
m_ownsBroadphasePairCache(false)
m_debugDrawer(0)
{
m_stackAlloc = new btStackAlloc(stackSize);
m_stackAlloc = collisionConfiguration->getStackAllocator();
m_dispatchInfo.m_stackAllocator = m_stackAlloc;
}
btCollisionWorld::~btCollisionWorld()
{
m_stackAlloc->destroy();
delete m_stackAlloc;
//clean up remaining objects
int i;
for (i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* collisionObject= m_collisionObjects[i];
btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
if (bp)
{
//
// only clear the cached algorithms
//
getBroadphase()->cleanProxyFromPairs(bp);
getBroadphase()->destroyProxy(bp);
getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
getBroadphase()->destroyProxy(bp,m_dispatcher1);
}
}
if (m_ownsDispatcher)
delete m_dispatcher1;
if (m_ownsBroadphasePairCache)
delete m_broadphasePairCache;
}
@@ -105,66 +103,105 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
type,
collisionObject,
collisionFilterGroup,
collisionFilterMask
collisionFilterMask,
m_dispatcher1,0
)) ;
}
void btCollisionWorld::updateAabbs()
{
BT_PROFILE("updateAabbs");
btTransform predictedTrans;
for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
//only update aabb of active objects
if (colObj->isActive())
{
btPoint3 minAabb,maxAabb;
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
//need to increase the aabb for contact thresholds
btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
minAabb -= contactThreshold;
maxAabb += contactThreshold;
btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
//moving objects should be moderately sized, probably something wrong if not
if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
{
bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
} else
{
//something went wrong, investigate
//this assert is unwanted in 3D modelers (danger of loosing work)
colObj->setActivationState(DISABLE_SIMULATION);
static bool reportMe = true;
if (reportMe && m_debugDrawer)
{
reportMe = false;
m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
m_debugDrawer->reportErrorWarning("Thanks.\n");
}
}
}
}
}
void btCollisionWorld::performDiscreteCollisionDetection()
{
BT_PROFILE("performDiscreteCollisionDetection");
btDispatcherInfo& dispatchInfo = getDispatchInfo();
BEGIN_PROFILE("perform Broadphase Collision Detection");
updateAabbs();
//update aabb (of all moved objects)
btVector3 aabbMin,aabbMax;
for (int i=0;i<m_collisionObjects.size();i++)
{
m_collisionObjects[i]->getCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),aabbMin,aabbMax);
m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax);
BT_PROFILE("calculateOverlappingPairs");
m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
}
m_broadphasePairCache->refreshOverlappingPairs();
END_PROFILE("perform Broadphase Collision Detection");
BEGIN_PROFILE("performDiscreteCollisionDetection");
btDispatcher* dispatcher = getDispatcher();
if (dispatcher)
dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache,dispatchInfo);
END_PROFILE("performDiscreteCollisionDetection");
{
BT_PROFILE("dispatchAllCollisionPairs");
if (dispatcher)
dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1);
}
}
void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
{
//bool removeFromBroadphase = false;
{
btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
if (bp)
{
//
// only clear the cached algorithms
//
getBroadphase()->cleanProxyFromPairs(bp);
getBroadphase()->destroyProxy(bp);
getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
getBroadphase()->destroyProxy(bp,m_dispatcher1);
collisionObject->setBroadphaseHandle(0);
}
}
@@ -181,172 +218,412 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback,short int collisionFilterMask)
RayResultCallback& resultCallback)
{
btSphereShape pointShape(btScalar(0.0));
pointShape.setMargin(0.f);
const btConvexShape* castShape = &pointShape;
objectQuerySingle(&pointShape,rayFromTrans,rayToTrans,
collisionObject,
collisionShape,
colObjWorldTransform,
resultCallback,collisionFilterMask);
if (collisionShape->isConvex())
{
btConvexCast::CastResult castResult;
castResult.m_fraction = resultCallback.m_closestHitFraction;
btConvexShape* convexShape = (btConvexShape*) collisionShape;
btVoronoiSimplexSolver simplexSolver;
#define USE_SUBSIMPLEX_CONVEX_CAST 1
#ifdef USE_SUBSIMPLEX_CONVEX_CAST
btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
#else
//btGjkConvexCast convexCaster(castShape,convexShape,&simplexSolver);
//btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
#endif //#USE_SUBSIMPLEX_CONVEX_CAST
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
{
//add hit
if (castResult.m_normal.length2() > btScalar(0.0001))
{
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
{
#ifdef USE_SUBSIMPLEX_CONVEX_CAST
//rotate normal into worldspace
castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
#endif //USE_SUBSIMPLEX_CONVEX_CAST
castResult.m_normal.normalize();
btCollisionWorld::LocalRayResult localRayResult
(
collisionObject,
0,
castResult.m_normal,
castResult.m_fraction
);
bool normalInWorldSpace = true;
resultCallback.addSingleResult(localRayResult, normalInWorldSpace);
}
}
}
} else {
if (collisionShape->isConcave())
{
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
///optimized version for btBvhTriangleMeshShape
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
//ConvexCast::CastResult
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
{
btCollisionWorld::RayResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
btTriangleRaycastCallback(from,to),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
{
}
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
btCollisionWorld::LocalRayResult rayResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
}
};
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
} else
{
btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
//ConvexCast::CastResult
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
{
btCollisionWorld::RayResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
btTriangleRaycastCallback(from,to),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
{
}
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
btCollisionWorld::LocalRayResult rayResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
}
};
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 rayAabbMinLocal = rayFromLocal;
rayAabbMinLocal.setMin(rayToLocal);
btVector3 rayAabbMaxLocal = rayFromLocal;
rayAabbMaxLocal.setMax(rayToLocal);
triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
}
} else {
//todo: use AABB tree or other BVH acceleration structure!
if (collisionShape->isCompound())
{
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
int i=0;
for (i=0;i<compoundShape->getNumChildShapes();i++)
{
btTransform childTrans = compoundShape->getChildTransform(i);
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
btTransform childWorldTrans = colObjWorldTransform * childTrans;
// replace collision shape so that callback can determine the triangle
btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
rayTestSingle(rayFromTrans,rayToTrans,
collisionObject,
childCollisionShape,
childWorldTrans,
resultCallback);
// restore
collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
}
}
}
}
}
void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& rayFromTrans,const btTransform& rayToTrans,
void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback,short int collisionFilterMask)
ConvexResultCallback& resultCallback, btScalar allowedPenetration)
{
if (collisionShape->isConvex())
{
btConvexCast::CastResult castResult;
castResult.m_allowedPenetration = allowedPenetration;
castResult.m_fraction = btScalar(1.);//??
btConvexShape* convexShape = (btConvexShape*) collisionShape;
btVoronoiSimplexSolver simplexSolver;
btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver;
btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
//btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
//btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
btConvexCast* castPtr = &convexCaster1;
if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
{
//add hit
if (castResult.m_normal.length2() > btScalar(0.0001))
{
btConvexCast::CastResult castResult;
castResult.m_fraction = btScalar(1.);//??
btConvexShape* convexShape = (btConvexShape*) collisionShape;
btVoronoiSimplexSolver simplexSolver;
btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
//GjkConvexCast convexCaster(castShape,convexShape,&simplexSolver);
//ContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
{
//add hit
if (castResult.m_normal.length2() > btScalar(0.0001))
{
castResult.m_normal.normalize();
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
{
btCollisionWorld::LocalRayResult localRayResult
castResult.m_normal.normalize();
btCollisionWorld::LocalConvexResult localConvexResult
(
collisionObject,
collisionObject,
0,
castResult.m_normal,
castResult.m_hitPoint,
castResult.m_fraction
);
resultCallback.AddSingleResult(localRayResult);
bool normalInWorldSpace = true;
resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
}
}
}
}
else
}
} else {
if (collisionShape->isConcave())
{
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
if (collisionShape->isConcave())
{
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
// rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
//ConvexCast::CastResult
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
//ConvexCast::CastResult
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
{
btCollisionWorld::RayResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
btTriangleRaycastCallback(from,to),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
{
}
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
btCollisionWorld::LocalRayResult rayResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitFraction);
return m_resultCallback->AddSingleResult(rayResult);
}
};
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 rayAabbMinLocal = rayFromLocal;
rayAabbMinLocal.setMin(rayToLocal);
btVector3 rayAabbMaxLocal = rayFromLocal;
rayAabbMaxLocal.setMax(rayToLocal);
triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
} else
{
//todo: use AABB tree or other BVH acceleration structure!
if (collisionShape->isCompound())
{
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
int i=0;
for (i=0;i<compoundShape->getNumChildShapes();i++)
{
btTransform childTrans = compoundShape->getChildTransform(i);
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
btTransform childWorldTrans = colObjWorldTransform * childTrans;
objectQuerySingle(castShape, rayFromTrans,rayToTrans,
collisionObject,
childCollisionShape,
childWorldTrans,
resultCallback, collisionFilterMask);
}
}
virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
if (hitFraction <= m_resultCallback->m_closestHitFraction)
{
btCollisionWorld::LocalConvexResult convexResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitPointLocal,
hitFraction);
bool normalInWorldSpace = true;
return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
}
return hitFraction;
}
};
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
} else
{
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
// rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
//ConvexCast::CastResult
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
{
}
virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
if (hitFraction <= m_resultCallback->m_closestHitFraction)
{
btCollisionWorld::LocalConvexResult convexResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitPointLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
}
return hitFraction;
}
};
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
btVector3 rayAabbMinLocal = convexFromLocal;
rayAabbMinLocal.setMin(convexToLocal);
btVector3 rayAabbMaxLocal = convexFromLocal;
rayAabbMaxLocal.setMax(convexToLocal);
rayAabbMinLocal += boxMinLocal;
rayAabbMaxLocal += boxMaxLocal;
triangleMesh->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
}
} else {
//todo: use AABB tree or other BVH acceleration structure!
if (collisionShape->isCompound())
{
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
int i=0;
for (i=0;i<compoundShape->getNumChildShapes();i++)
{
btTransform childTrans = compoundShape->getChildTransform(i);
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
btTransform childWorldTrans = colObjWorldTransform * childTrans;
// replace collision shape so that callback can determine the triangle
btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
objectQuerySingle(castShape, convexFromTrans,convexToTrans,
collisionObject,
childCollisionShape,
childWorldTrans,
resultCallback, allowedPenetration);
// restore
collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
}
}
}
}
}
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask)
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
{
btTransform rayFromTrans,rayToTrans;
rayFromTrans.setIdentity();
rayFromTrans.setOrigin(rayFromWorld);
rayToTrans.setIdentity();
rayToTrans.setOrigin(rayToWorld);
/// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
int i;
for (i=0;i<m_collisionObjects.size();i++)
{
///terminate further ray tests, once the closestHitFraction reached zero
if (resultCallback.m_closestHitFraction == btScalar(0.f))
break;
btCollisionObject* collisionObject= m_collisionObjects[i];
//only perform raycast if filterMask matches
if(collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) {
if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
btScalar hitLambda = resultCallback.m_closestHitFraction;
btVector3 hitNormal;
if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
{
@@ -355,7 +632,52 @@ void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& r
collisionObject->getCollisionShape(),
collisionObject->getWorldTransform(),
resultCallback);
}
}
}
}
}
void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback) const
{
btTransform convexFromTrans,convexToTrans;
convexFromTrans = convexFromWorld;
convexToTrans = convexToWorld;
btVector3 castShapeAabbMin, castShapeAabbMax;
/* Compute AABB that encompasses angular movement */
{
btVector3 linVel, angVel;
btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
btTransform R;
R.setIdentity ();
R.setRotation (convexFromTrans.getRotation());
castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
}
/// go over all objects, and if the ray intersects their aabb + cast shape aabb,
// do a ray-shape query using convexCaster (CCD)
int i;
for (i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* collisionObject= m_collisionObjects[i];
//only perform raycast if filterMask matches
if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
btVector3 hitNormal;
if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
{
objectQuerySingle(castShape, convexFromTrans,convexToTrans,
collisionObject,
collisionObject->getCollisionShape(),
collisionObject->getWorldTransform(),
resultCallback,
getDispatchInfo().m_allowedCcdPenetration);
}
}
}

View File

@@ -68,12 +68,12 @@ class btStackAlloc;
class btCollisionShape;
class btConvexShape;
class btBroadphaseInterface;
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "btCollisionObject.h"
#include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray
#include "../BroadphaseCollision/btOverlappingPairCache.h"
#include "../../LinearMath/btAlignedObjectArray.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
#include "LinearMath/btAlignedObjectArray.h"
///CollisionWorld is interface and container for the collision detection
class btCollisionWorld
@@ -90,18 +90,22 @@ protected:
btStackAlloc* m_stackAlloc;
btOverlappingPairCache* m_broadphasePairCache;
bool m_ownsDispatcher;
bool m_ownsBroadphasePairCache;
btBroadphaseInterface* m_broadphasePairCache;
btIDebugDraw* m_debugDrawer;
public:
//this constructor doesn't own the dispatcher and paircache/broadphase
btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize = 2*1024*1024);
btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration);
virtual ~btCollisionWorld();
void setBroadphase(btBroadphaseInterface* pairCache)
{
m_broadphasePairCache = pairCache;
}
btBroadphaseInterface* getBroadphase()
{
@@ -110,7 +114,7 @@ public:
btOverlappingPairCache* getPairCache()
{
return m_broadphasePairCache;
return m_broadphasePairCache->getOverlappingPairCache();
}
@@ -119,6 +123,24 @@ public:
return m_dispatcher1;
}
const btDispatcher* getDispatcher() const
{
return m_dispatcher1;
}
virtual void updateAabbs();
virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
{
m_debugDrawer = debugDrawer;
}
virtual btIDebugDraw* getDebugDrawer()
{
return m_debugDrawer;
}
///LocalShapeInfo gives extra information for complex shapes
///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart
struct LocalShapeInfo
@@ -153,28 +175,43 @@ public:
///RayResultCallback is used to report new raycast results
struct RayResultCallback
{
btScalar m_closestHitFraction;
btCollisionObject* m_collisionObject;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
virtual ~RayResultCallback()
{
}
btScalar m_closestHitFraction;
bool HasHit()
bool hasHit() const
{
return (m_closestHitFraction < btScalar(1.));
return (m_collisionObject != 0);
}
RayResultCallback()
:m_closestHitFraction(btScalar(1.))
:m_closestHitFraction(btScalar(1.)),
m_collisionObject(0),
m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
m_collisionFilterMask(btBroadphaseProxy::AllFilter)
{
}
virtual btScalar AddSingleResult(LocalRayResult& rayResult) = 0;
virtual bool needsCollision(btBroadphaseProxy* proxy0) const
{
bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0;
};
struct ClosestRayResultCallback : public RayResultCallback
{
ClosestRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld)
:m_rayFromWorld(rayFromWorld),
m_rayToWorld(rayToWorld),
m_collisionObject(0)
m_rayToWorld(rayToWorld)
{
}
@@ -183,24 +220,121 @@ public:
btVector3 m_hitNormalWorld;
btVector3 m_hitPointWorld;
btCollisionObject* m_collisionObject;
virtual btScalar AddSingleResult(LocalRayResult& rayResult)
virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace)
{
//caller already does the filter on the m_closestHitFraction
assert(rayResult.m_hitFraction <= m_closestHitFraction);
//caller already does the filter on the m_closestHitFraction
btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
m_closestHitFraction = rayResult.m_hitFraction;
m_collisionObject = rayResult.m_collisionObject;
m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
if (normalInWorldSpace)
{
m_hitNormalWorld = rayResult.m_hitNormalLocal;
} else
{
///need to transform normal into worldspace
m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
}
m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction);
return rayResult.m_hitFraction;
}
};
struct LocalConvexResult
{
LocalConvexResult(btCollisionObject* hitCollisionObject,
LocalShapeInfo* localShapeInfo,
const btVector3& hitNormalLocal,
const btVector3& hitPointLocal,
btScalar hitFraction
)
:m_hitCollisionObject(hitCollisionObject),
m_localShapeInfo(localShapeInfo),
m_hitNormalLocal(hitNormalLocal),
m_hitPointLocal(hitPointLocal),
m_hitFraction(hitFraction)
{
}
btCollisionObject* m_hitCollisionObject;
LocalShapeInfo* m_localShapeInfo;
btVector3 m_hitNormalLocal;
btVector3 m_hitPointLocal;
btScalar m_hitFraction;
};
///RayResultCallback is used to report new raycast results
struct ConvexResultCallback
{
btScalar m_closestHitFraction;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
ConvexResultCallback()
:m_closestHitFraction(btScalar(1.)),
m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
m_collisionFilterMask(btBroadphaseProxy::AllFilter)
{
}
virtual ~ConvexResultCallback()
{
}
bool hasHit() const
{
return (m_closestHitFraction < btScalar(1.));
}
virtual bool needsCollision(btBroadphaseProxy* proxy0) const
{
bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) = 0;
};
struct ClosestConvexResultCallback : public ConvexResultCallback
{
ClosestConvexResultCallback(const btVector3& convexFromWorld,const btVector3& convexToWorld)
:m_convexFromWorld(convexFromWorld),
m_convexToWorld(convexToWorld),
m_hitCollisionObject(0)
{
}
btVector3 m_convexFromWorld;//used to calculate hitPointWorld from hitFraction
btVector3 m_convexToWorld;
btVector3 m_hitNormalWorld;
btVector3 m_hitPointWorld;
btCollisionObject* m_hitCollisionObject;
virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace)
{
//caller already does the filter on the m_closestHitFraction
btAssert(convexResult.m_hitFraction <= m_closestHitFraction);
m_closestHitFraction = convexResult.m_hitFraction;
m_hitCollisionObject = convexResult.m_hitCollisionObject;
if (normalInWorldSpace)
{
m_hitNormalWorld = convexResult.m_hitNormalLocal;
} else
{
///need to transform normal into worldspace
m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
}
m_hitPointWorld = convexResult.m_hitPointLocal;
return convexResult.m_hitFraction;
}
};
int getNumCollisionObjects() const
{
@@ -209,7 +343,12 @@ public:
/// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
/// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback, short int collisionFilterMask=-1);
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback) const;
/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
/// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
@@ -218,16 +357,16 @@ public:
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback, short int collisionFilterMask=-1);
RayResultCallback& resultCallback);
/// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest.
static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans,
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback, short int collisionFilterMask=-1);
ConvexResultCallback& resultCallback, btScalar allowedPenetration);
void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=1,short int collisionFilterMask=1);
void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
btCollisionObjectArray& getCollisionObjectArray()
{
@@ -249,6 +388,11 @@ public:
return m_dispatchInfo;
}
const btDispatcherInfo& getDispatchInfo() const
{
return m_dispatchInfo;
}
};

View File

@@ -16,11 +16,17 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btAabbUtil2.h"
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
:m_isSwapped(isSwapped)
:btCollisionAlgorithm(ci),
m_isSwapped(isSwapped),
m_sharedManifold(ci.m_manifold)
{
m_ownsManifold = false;
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
assert (colObj->getCollisionShape()->isCompound());
@@ -32,11 +38,17 @@ btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlg
m_childCollisionAlgorithms.resize(numChildren);
for (i=0;i<numChildren;i++)
{
btCollisionShape* childShape = compoundShape->getChildShape(i);
btCollisionShape* orgShape = colObj->getCollisionShape();
colObj->setCollisionShape( childShape );
m_childCollisionAlgorithms[i] = ci.m_dispatcher->findAlgorithm(colObj,otherObj);
colObj->setCollisionShape( orgShape );
if (compoundShape->getDynamicAabbTree())
{
m_childCollisionAlgorithms[i] = 0;
} else
{
btCollisionShape* tmpShape = colObj->getCollisionShape();
btCollisionShape* childShape = compoundShape->getChildShape(i);
colObj->internalSetTemporaryCollisionShape( childShape );
m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj,m_sharedManifold);
colObj->internalSetTemporaryCollisionShape( tmpShape );
}
}
}
@@ -47,10 +59,109 @@ btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
int i;
for (i=0;i<numChildren;i++)
{
delete m_childCollisionAlgorithms[i];
if (m_childCollisionAlgorithms[i])
{
m_childCollisionAlgorithms[i]->~btCollisionAlgorithm();
m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
}
}
}
struct btCompoundLeafCallback : btDbvt::ICollide
{
public:
btCollisionObject* m_compoundColObj;
btCollisionObject* m_otherObj;
btDispatcher* m_dispatcher;
const btDispatcherInfo& m_dispatchInfo;
btManifoldResult* m_resultOut;
btCollisionAlgorithm** m_childCollisionAlgorithms;
btPersistentManifold* m_sharedManifold;
btCompoundLeafCallback (btCollisionObject* compoundObj,btCollisionObject* otherObj,btDispatcher* dispatcher,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut,btCollisionAlgorithm** childCollisionAlgorithms,btPersistentManifold* sharedManifold)
:m_compoundColObj(compoundObj),m_otherObj(otherObj),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
m_childCollisionAlgorithms(childCollisionAlgorithms),
m_sharedManifold(sharedManifold)
{
}
void ProcessChildShape(btCollisionShape* childShape,int index)
{
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
//backup
btTransform orgTrans = m_compoundColObj->getWorldTransform();
btTransform orgInterpolationTrans = m_compoundColObj->getInterpolationWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(index);
btTransform newChildWorldTrans = orgTrans*childTrans ;
//perform an AABB check first
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
m_otherObj->getCollisionShape()->getAabb(m_otherObj->getWorldTransform(),aabbMin1,aabbMax1);
if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
{
m_compoundColObj->setWorldTransform( newChildWorldTrans);
m_compoundColObj->setInterpolationWorldTransform(newChildWorldTrans);
//the contactpoint is still projected back using the original inverted worldtrans
btCollisionShape* tmpShape = m_compoundColObj->getCollisionShape();
m_compoundColObj->internalSetTemporaryCollisionShape( childShape );
if (!m_childCollisionAlgorithms[index])
m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(m_compoundColObj,m_otherObj,m_sharedManifold);
m_childCollisionAlgorithms[index]->processCollision(m_compoundColObj,m_otherObj,m_dispatchInfo,m_resultOut);
if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 worldAabbMin,worldAabbMax;
m_dispatchInfo.m_debugDraw->drawAabb(aabbMin0,aabbMax0,btVector3(1,1,1));
m_dispatchInfo.m_debugDraw->drawAabb(aabbMin1,aabbMax1,btVector3(1,1,1));
}
//revert back transform
m_compoundColObj->internalSetTemporaryCollisionShape( tmpShape);
m_compoundColObj->setWorldTransform( orgTrans );
m_compoundColObj->setInterpolationWorldTransform(orgInterpolationTrans);
}
}
void Process(const btDbvtNode* leaf)
{
int index = leaf->dataAsInt;
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
btCollisionShape* childShape = compoundShape->getChildShape(index);
if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 worldAabbMin,worldAabbMax;
btTransform orgTrans = m_compoundColObj->getWorldTransform();
btTransformAabb(leaf->volume.Mins(),leaf->volume.Maxs(),0.,orgTrans,worldAabbMin,worldAabbMax);
m_dispatchInfo.m_debugDraw->drawAabb(worldAabbMin,worldAabbMax,btVector3(1,0,0));
}
ProcessChildShape(childShape,index);
}
};
void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
btCollisionObject* colObj = m_isSwapped? body1 : body0;
@@ -59,33 +170,69 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
assert (colObj->getCollisionShape()->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
//We will use the OptimizedBVH, AABB tree to cull potential child-overlaps
//If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals
//given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means:
//determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1
//then use each overlapping node AABB against Tree0
//and vise versa.
btDbvt* tree = compoundShape->getDynamicAabbTree();
//use a dynamic aabb tree to cull potential child-overlaps
btCompoundLeafCallback callback(colObj,otherObj,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
int numChildren = m_childCollisionAlgorithms.size();
int i;
for (i=0;i<numChildren;i++)
if (tree)
{
//temporarily exchange parent btCollisionShape with childShape, and recurse
btCollisionShape* childShape = compoundShape->getChildShape(i);
//backup
btTransform orgTrans = colObj->getWorldTransform();
btCollisionShape* orgShape = colObj->getCollisionShape();
btVector3 localAabbMin,localAabbMax;
btTransform otherInCompoundSpace;
otherInCompoundSpace = colObj->getWorldTransform().inverse() * otherObj->getWorldTransform();
otherObj->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax);
const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
//process all children, that overlap with the given AABB bounds
tree->collideTV(tree->m_root,bounds,callback);
} else
{
//iterate over all children, perform an AABB check inside ProcessChildShape
int numChildren = m_childCollisionAlgorithms.size();
int i;
for (i=0;i<numChildren;i++)
{
callback.ProcessChildShape(compoundShape->getChildShape(i),i);
}
}
{
//iterate over all children, perform an AABB check inside ProcessChildShape
int numChildren = m_childCollisionAlgorithms.size();
int i;
btManifoldArray manifoldArray;
for (i=0;i<numChildren;i++)
{
if (m_childCollisionAlgorithms[i])
{
btCollisionShape* childShape = compoundShape->getChildShape(i);
//if not longer overlapping, remove the algorithm
btTransform orgTrans = colObj->getWorldTransform();
btTransform orgInterpolationTrans = colObj->getInterpolationWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(i);
btTransform newChildWorldTrans = orgTrans*childTrans ;
//perform an AABB check first
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
otherObj->getCollisionShape()->getAabb(otherObj->getWorldTransform(),aabbMin1,aabbMax1);
if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
{
m_childCollisionAlgorithms[i]->~btCollisionAlgorithm();
m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
m_childCollisionAlgorithms[i] = 0;
}
}
}
const btTransform& childTrans = compoundShape->getChildTransform(i);
//btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->setWorldTransform( orgTrans*childTrans );
//the contactpoint is still projected back using the original inverted worldtrans
colObj->setCollisionShape( childShape );
m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut);
//revert back
colObj->setCollisionShape( orgShape);
colObj->setWorldTransform( orgTrans );
}
}
@@ -117,20 +264,20 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
//backup
btTransform orgTrans = colObj->getWorldTransform();
btCollisionShape* orgShape = colObj->getCollisionShape();
const btTransform& childTrans = compoundShape->getChildTransform(i);
//btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->setWorldTransform( orgTrans*childTrans );
colObj->setCollisionShape( childShape );
btCollisionShape* tmpShape = colObj->getCollisionShape();
colObj->internalSetTemporaryCollisionShape( childShape );
btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
if (frac<hitFraction)
{
hitFraction = frac;
}
//revert back
colObj->setCollisionShape( orgShape);
colObj->internalSetTemporaryCollisionShape( tmpShape);
colObj->setWorldTransform( orgTrans);
}
return hitFraction;

View File

@@ -16,22 +16,25 @@ subject to the following restrictions:
#ifndef COMPOUND_COLLISION_ALGORITHM_H
#define COMPOUND_COLLISION_ALGORITHM_H
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btDispatcher.h"
#include "../BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "../NarrowPhaseCollision/btPersistentManifold.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
class btDispatcher;
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "btCollisionCreateFunc.h"
#include "../../LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
class btDispatcher;
/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
/// Place holder, not fully implemented yet
class btCompoundCollisionAlgorithm : public btCollisionAlgorithm
{
btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
bool m_isSwapped;
class btPersistentManifold* m_sharedManifold;
bool m_ownsManifold;
public:
@@ -43,11 +46,22 @@ public:
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
{
int i;
for (i=0;i<m_childCollisionAlgorithms.size();i++)
{
if (m_childCollisionAlgorithms[i])
m_childCollisionAlgorithms[i]->getAllContactManifolds(manifoldArray);
}
}
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
return new btCompoundCollisionAlgorithm(ci,body0,body1,false);
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,false);
}
};
@@ -55,7 +69,8 @@ public:
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
return new btCompoundCollisionAlgorithm(ci,body0,body1,true);
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,true);
}
};

View File

@@ -29,7 +29,7 @@ subject to the following restrictions:
btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
: btCollisionAlgorithm(ci),
m_isSwapped(isSwapped),
m_btConvexTriangleCallback(ci.m_dispatcher,body0,body1,isSwapped)
m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
{
}
@@ -37,6 +37,13 @@ btConvexConcaveCollisionAlgorithm::~btConvexConcaveCollisionAlgorithm()
{
}
void btConvexConcaveCollisionAlgorithm::getAllContactManifolds(btManifoldArray& manifoldArray)
{
if (m_btConvexTriangleCallback.m_manifoldPtr)
{
manifoldArray.push_back(m_btConvexTriangleCallback.m_manifoldPtr);
}
}
btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped):
@@ -79,7 +86,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
//aabb filter is already applied!
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher = m_dispatcher;
ci.m_dispatcher1 = m_dispatcher;
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
@@ -109,13 +116,11 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
{
btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
tm.setMargin(m_collisionMarginTriangle);
btCollisionShape* tmpShape = ob->getCollisionShape();
ob->setCollisionShape( &tm );
ob->internalSetTemporaryCollisionShape( &tm );
btCollisionAlgorithm* colAlgo = ci.m_dispatcher->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
///this should use the btDispatcher, so the actual registered algorithm is used
// btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
@@ -123,12 +128,11 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
// cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex);
// cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
delete colAlgo;
ob->setCollisionShape( tmpShape );
colAlgo->~btCollisionAlgorithm();
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
ob->internalSetTemporaryCollisionShape( tmpShape);
}
}
@@ -188,9 +192,10 @@ void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* bod
concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax());
resultOut->refreshContactPoints();
}
}
}

View File

@@ -16,13 +16,13 @@ subject to the following restrictions:
#ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btDispatcher.h"
#include "../BroadphaseCollision/btBroadphaseInterface.h"
#include "../CollisionShapes/btTriangleCallback.h"
#include "../NarrowPhaseCollision/btPersistentManifold.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
class btDispatcher;
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "btCollisionCreateFunc.h"
///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called.
@@ -55,11 +55,11 @@ int m_triangleCount;
void clearCache();
inline const btVector3& getAabbMin() const
SIMD_FORCE_INLINE const btVector3& getAabbMin() const
{
return m_aabbMin;
}
inline const btVector3& getAabbMax() const
SIMD_FORCE_INLINE const btVector3& getAabbMax() const
{
return m_aabbMax;
}
@@ -88,13 +88,16 @@ public:
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void getAllContactManifolds(btManifoldArray& manifoldArray);
void clearCache();
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
}
};
@@ -102,7 +105,8 @@ public:
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
}
};

View File

@@ -15,7 +15,7 @@ subject to the following restrictions:
#include "btConvexConvexAlgorithm.h"
#include <stdio.h>
//#include <stdio.h>
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
@@ -33,7 +33,6 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h"
@@ -48,26 +47,16 @@ subject to the following restrictions:
btConvexConvexAlgorithm::CreateFunc::CreateFunc()
{
m_ownsSolvers = true;
m_simplexSolver = new btVoronoiSimplexSolver();
m_pdSolver = new btGjkEpaPenetrationDepthSolver;
}
btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
{
m_ownsSolvers = false;
m_simplexSolver = simplexSolver;
m_pdSolver = pdSolver;
}
btConvexConvexAlgorithm::CreateFunc::~CreateFunc()
{
if (m_ownsSolvers){
delete m_simplexSolver;
delete m_pdSolver;
}
}
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
@@ -152,6 +141,11 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
#endif
if (m_ownManifold)
{
resultOut->refreshContactPoints();
}
}

View File

@@ -16,12 +16,13 @@ subject to the following restrictions:
#ifndef CONVEX_CONVEX_ALGORITHM_H
#define CONVEX_CONVEX_ALGORITHM_H
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../NarrowPhaseCollision/btGjkPairDetector.h"
#include "../NarrowPhaseCollision/btPersistentManifold.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "btCollisionCreateFunc.h"
#include "btCollisionDispatcher.h"
class btConvexPenetrationDepthSolver;
@@ -46,6 +47,14 @@ public:
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
{
///should we use m_ownManifold to avoid adding duplicates?
if (m_manifoldPtr && m_ownManifold)
manifoldArray.push_back(m_manifoldPtr);
}
void setLowLevelOfDetail(bool useLowLevel);
@@ -58,15 +67,15 @@ public:
{
btConvexPenetrationDepthSolver* m_pdSolver;
btSimplexSolverInterface* m_simplexSolver;
bool m_ownsSolvers;
CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
CreateFunc();
virtual ~CreateFunc();
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
return new btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver);
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm));
return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver);
}
};

View File

@@ -0,0 +1,108 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "btConvexPlaneCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
//#include <stdio.h>
btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
: btCollisionAlgorithm(ci),
m_ownManifold(false),
m_manifoldPtr(mf),
m_isSwapped(isSwapped)
{
btCollisionObject* convexObj = m_isSwapped? col1 : col0;
btCollisionObject* planeObj = m_isSwapped? col0 : col1;
if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj))
{
m_manifoldPtr = m_dispatcher->getNewManifold(convexObj,planeObj);
m_ownManifold = true;
}
}
btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm()
{
if (m_ownManifold)
{
if (m_manifoldPtr)
m_dispatcher->releaseManifold(m_manifoldPtr);
}
}
void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)dispatchInfo;
(void)resultOut;
if (!m_manifoldPtr)
return;
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
btCollisionObject* planeObj = m_isSwapped? body0: body1;
btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
const btScalar& planeConstant = planeShape->getPlaneConstant();
btTransform planeInConvex;
planeInConvex= convexObj->getWorldTransform().inverse() * planeObj->getWorldTransform();
btTransform convexInPlaneTrans;
convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexObj->getWorldTransform();
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
btVector3 vtxInPlane = convexInPlaneTrans(vtx);
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
btVector3 vtxInPlaneWorld = planeObj->getWorldTransform() * vtxInPlaneProjected;
hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold();
resultOut->setPersistentManifold(m_manifoldPtr);
if (hasCollision)
{
/// report a contact. internally this will be kept persistent, and contact reduction is done
btVector3 normalOnSurfaceB = planeObj->getWorldTransform().getBasis() * planeNormal;
btVector3 pOnB = vtxInPlaneWorld;
resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
}
if (m_ownManifold)
{
if (m_manifoldPtr->getNumContacts())
{
resultOut->refreshContactPoints();
}
}
}
btScalar btConvexPlaneCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)resultOut;
(void)dispatchInfo;
(void)col0;
(void)col1;
//not yet
return btScalar(1.);
}

View File

@@ -0,0 +1,71 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_PLANE_COLLISION_ALGORITHM_H
#define CONVEX_PLANE_COLLISION_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
#include "btCollisionDispatcher.h"
#include "LinearMath/btVector3.h"
/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm
{
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
bool m_isSwapped;
public:
btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
virtual ~btConvexPlaneCollisionAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
{
if (m_manifoldPtr && m_ownManifold)
{
manifoldArray.push_back(m_manifoldPtr);
}
}
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm));
if (!m_swapped)
{
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false);
} else
{
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true);
}
}
};
};
#endif //CONVEX_PLANE_COLLISION_ALGORITHM_H

View File

@@ -0,0 +1,291 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "btDefaultCollisionConfiguration.h"
#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "LinearMath/btStackAlloc.h"
#include "LinearMath/btPoolAllocator.h"
btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
//btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool)
{
void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16);
m_simplexSolver = new (mem)btVoronoiSimplexSolver();
#define USE_EPA 1
#ifdef USE_EPA
mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16);
m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver;
#else
mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver),16);
m_pdSolver = new (mem)btMinkowskiPenetrationDepthSolver;
#endif//USE_EPA
//default CreationFunctions, filling the m_doubleDispatch table
mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16);
m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver);
mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc;
mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16);
m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc;
mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16);
m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc;
mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16);
m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc;
mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16);
m_sphereSphereCF = new(mem) btSphereSphereCollisionAlgorithm::CreateFunc;
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc;
mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc;
m_boxSphereCF->m_swapped = true;
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
m_triangleSphereCF->m_swapped = true;
mem = btAlignedAlloc(sizeof(btBoxBoxCollisionAlgorithm::CreateFunc),16);
m_boxBoxCF = new(mem)btBoxBoxCollisionAlgorithm::CreateFunc;
//convex versus plane
mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
m_convexPlaneCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
m_planeConvexCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
m_planeConvexCF->m_swapped = true;
///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
int maxSize = sizeof(btConvexConvexAlgorithm);
int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
int maxSize4 = sizeof(btEmptyAlgorithm);
int collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2);
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);
if (constructionInfo.m_stackAlloc)
{
m_ownsStackAllocator = false;
this->m_stackAlloc = constructionInfo.m_stackAlloc;
} else
{
m_ownsStackAllocator = true;
void* mem = btAlignedAlloc(sizeof(btStackAlloc),16);
m_stackAlloc = new(mem)btStackAlloc(constructionInfo.m_defaultStackAllocatorSize);
}
if (constructionInfo.m_persistentManifoldPool)
{
m_ownsPersistentManifoldPool = false;
m_persistentManifoldPool = constructionInfo.m_persistentManifoldPool;
} else
{
m_ownsPersistentManifoldPool = true;
void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),constructionInfo.m_defaultMaxPersistentManifoldPoolSize);
}
if (constructionInfo.m_collisionAlgorithmPool)
{
m_ownsCollisionAlgorithmPool = false;
m_collisionAlgorithmPool = constructionInfo.m_collisionAlgorithmPool;
} else
{
m_ownsCollisionAlgorithmPool = true;
void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
}
}
btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
{
if (m_ownsStackAllocator)
{
m_stackAlloc->destroy();
m_stackAlloc->~btStackAlloc();
btAlignedFree(m_stackAlloc);
}
if (m_ownsCollisionAlgorithmPool)
{
m_collisionAlgorithmPool->~btPoolAllocator();
btAlignedFree(m_collisionAlgorithmPool);
}
if (m_ownsPersistentManifoldPool)
{
m_persistentManifoldPool->~btPoolAllocator();
btAlignedFree(m_persistentManifoldPool);
}
m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_convexConvexCreateFunc);
m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_convexConcaveCreateFunc);
m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_swappedConvexConcaveCreateFunc);
m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_compoundCreateFunc);
m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_swappedCompoundCreateFunc);
m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_emptyCreateFunc);
m_sphereSphereCF->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_sphereSphereCF);
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
m_sphereBoxCF->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_sphereBoxCF);
m_boxSphereCF->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_boxSphereCF);
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_sphereTriangleCF);
m_triangleSphereCF->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_triangleSphereCF);
m_boxBoxCF->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_boxBoxCF);
m_convexPlaneCF->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_convexPlaneCF);
m_planeConvexCF->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_planeConvexCF);
m_simplexSolver->~btVoronoiSimplexSolver();
btAlignedFree(m_simplexSolver);
m_pdSolver->~btConvexPenetrationDepthSolver();
btAlignedFree(m_pdSolver);
}
btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
{
if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
{
return m_sphereSphereCF;
}
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE))
{
return m_sphereBoxCF;
}
if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
{
return m_boxSphereCF;
}
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE))
{
return m_sphereTriangleCF;
}
if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
{
return m_triangleSphereCF;
}
if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
{
return m_boxBoxCF;
}
if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE))
{
return m_convexPlaneCF;
}
if (btBroadphaseProxy::isConvex(proxyType1) && (proxyType0 == STATIC_PLANE_PROXYTYPE))
{
return m_planeConvexCF;
}
if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
{
return m_convexConvexCreateFunc;
}
if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
{
return m_convexConcaveCreateFunc;
}
if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
{
return m_swappedConvexConcaveCreateFunc;
}
if (btBroadphaseProxy::isCompound(proxyType0))
{
return m_compoundCreateFunc;
} else
{
if (btBroadphaseProxy::isCompound(proxyType1))
{
return m_swappedCompoundCreateFunc;
}
}
//failed to find an algorithm
return m_emptyCreateFunc;
}

View File

@@ -0,0 +1,115 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_DEFAULT_COLLISION_CONFIGURATION
#define BT_DEFAULT_COLLISION_CONFIGURATION
#include "btCollisionConfiguration.h"
class btVoronoiSimplexSolver;
class btConvexPenetrationDepthSolver;
struct btDefaultCollisionConstructionInfo
{
btStackAlloc* m_stackAlloc;
btPoolAllocator* m_persistentManifoldPool;
btPoolAllocator* m_collisionAlgorithmPool;
int m_defaultMaxPersistentManifoldPoolSize;
int m_defaultMaxCollisionAlgorithmPoolSize;
int m_defaultStackAllocatorSize;
btDefaultCollisionConstructionInfo()
:m_stackAlloc(0),
m_persistentManifoldPool(0),
m_collisionAlgorithmPool(0),
m_defaultMaxPersistentManifoldPoolSize(65535),
m_defaultMaxCollisionAlgorithmPoolSize(65535),
m_defaultStackAllocatorSize(5*1024*1024)
{
}
};
///btCollisionConfiguration allows to configure Bullet collision detection
///stack allocator, pool memory allocators
///todo: describe the meaning
class btDefaultCollisionConfiguration : public btCollisionConfiguration
{
int m_persistentManifoldPoolSize;
btStackAlloc* m_stackAlloc;
bool m_ownsStackAllocator;
btPoolAllocator* m_persistentManifoldPool;
bool m_ownsPersistentManifoldPool;
btPoolAllocator* m_collisionAlgorithmPool;
bool m_ownsCollisionAlgorithmPool;
//default simplex/penetration depth solvers
btVoronoiSimplexSolver* m_simplexSolver;
btConvexPenetrationDepthSolver* m_pdSolver;
//default CreationFunctions, filling the m_doubleDispatch table
btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc;
btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc;
btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc;
btCollisionAlgorithmCreateFunc* m_compoundCreateFunc;
btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc;
btCollisionAlgorithmCreateFunc* m_emptyCreateFunc;
btCollisionAlgorithmCreateFunc* m_sphereSphereCF;
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
btCollisionAlgorithmCreateFunc* m_sphereBoxCF;
btCollisionAlgorithmCreateFunc* m_boxSphereCF;
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
btCollisionAlgorithmCreateFunc* m_boxBoxCF;
btCollisionAlgorithmCreateFunc* m_sphereTriangleCF;
btCollisionAlgorithmCreateFunc* m_triangleSphereCF;
btCollisionAlgorithmCreateFunc* m_planeConvexCF;
btCollisionAlgorithmCreateFunc* m_convexPlaneCF;
public:
btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo());
virtual ~btDefaultCollisionConfiguration();
///memory pools
virtual btPoolAllocator* getPersistentManifoldPool()
{
return m_persistentManifoldPool;
}
virtual btPoolAllocator* getCollisionAlgorithmPool()
{
return m_collisionAlgorithmPool;
}
virtual btStackAlloc* getStackAllocator()
{
return m_stackAlloc;
}
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
};
#endif //BT_DEFAULT_COLLISION_CONFIGURATION

View File

@@ -15,8 +15,9 @@ subject to the following restrictions:
#ifndef EMPTY_ALGORITH
#define EMPTY_ALGORITH
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "btCollisionCreateFunc.h"
#include "btCollisionDispatcher.h"
#define ATTRIBUTE_ALIGNED(a)
@@ -33,13 +34,18 @@ public:
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
{
}
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
(void)body0;
(void)body1;
return new btEmptyAlgorithm(ci);
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btEmptyAlgorithm));
return new(mem) btEmptyAlgorithm(ci);
}
};

View File

@@ -79,12 +79,30 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
}
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
newPt.m_positionWorldOnA = pointA;
newPt.m_positionWorldOnB = pointInWorld;
int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1);
newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1);
//BP mod, store contact triangles.
newPt.m_partId0 = m_partId0;
newPt.m_partId1 = m_partId1;
newPt.m_index0 = m_index0;
newPt.m_index1 = m_index1;
///todo, check this for any side effects
if (insertIndex >= 0)
{
//const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
} else
{
insertIndex = m_manifoldPtr->addManifoldPoint(newPt);
}
//User can override friction and/or restitution
if (gContactAddedCallback &&
//and if either of the two bodies requires custom material
@@ -94,16 +112,8 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
//experimental feature info, for per-triangle material etc.
btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
(*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1);
(*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0,m_partId0,m_index0,obj1,m_partId1,m_index1);
}
if (insertIndex >= 0)
{
//const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
} else
{
m_manifoldPtr->AddManifoldPoint(newPt);
}
}

View File

@@ -18,12 +18,12 @@ subject to the following restrictions:
#define MANIFOLD_RESULT_H
class btCollisionObject;
class btPersistentManifold;
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
class btManifoldPoint;
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "../../LinearMath/btTransform.h"
#include "LinearMath/btTransform.h"
typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1);
extern ContactAddedCallback gContactAddedCallback;
@@ -60,6 +60,15 @@ public:
m_manifoldPtr = manifoldPtr;
}
const btPersistentManifold* getPersistentManifold() const
{
return m_manifoldPtr;
}
btPersistentManifold* getPersistentManifold()
{
return m_manifoldPtr;
}
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1)
{
m_partId0=partId0;
@@ -70,6 +79,22 @@ public:
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth);
SIMD_FORCE_INLINE void refreshContactPoints()
{
btAssert(m_manifoldPtr);
if (!m_manifoldPtr->getNumContacts())
return;
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
if (isSwapped)
{
m_manifoldPtr->refreshContactPoints(m_rootTransB,m_rootTransA);
} else
{
m_manifoldPtr->refreshContactPoints(m_rootTransA,m_rootTransB);
}
}
};

View File

@@ -1,3 +1,17 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "LinearMath/btScalar.h"
@@ -7,7 +21,7 @@
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
#include <stdio.h>
//#include <stdio.h>
#include "LinearMath/btQuickprof.h"
btSimulationIslandManager::btSimulationIslandManager()
@@ -25,17 +39,17 @@ void btSimulationIslandManager::initUnionFind(int n)
}
void btSimulationIslandManager::findUnions(btDispatcher* dispatcher)
void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btCollisionWorld* colWorld)
{
{
for (int i=0;i<dispatcher->getNumManifolds();i++)
{
const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
//static objects (invmass btScalar(0.)) don't merge !
btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0());
const btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1());
for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
{
const btBroadphasePair& collisionPair = pairPtr[i];
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
((colObj1) && ((colObj1)->mergesSimulationIslands())))
@@ -71,7 +85,7 @@ void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld
}
// do the union find
findUnions(dispatcher);
findUnions(dispatcher,colWorld);
@@ -129,30 +143,13 @@ class btPersistentManifoldSortPredicate
};
//
// todo: this is random access, it can be walked 'cache friendly'!
//
void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects)
{
BT_PROFILE("islandUnionFindAndQuickSort");
/*if (0)
{
int maxNumManifolds = dispatcher->getNumManifolds();
btCollisionDispatcher* colDis = (btCollisionDispatcher*)dispatcher;
btPersistentManifold** manifold = colDis->getInternalManifoldPointer();
callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, 0);
return;
}
*/
m_islandmanifold.resize(0);
BEGIN_PROFILE("islandUnionFindAndHeapSort");
//we are going to sort the unionfind array, and store the element id in the size
//afterwards, we clean unionfind, to make sure no-one uses it anymore
@@ -183,7 +180,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
btCollisionObject* colObj0 = collisionObjects[i];
if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
{
printf("error in island management\n");
// printf("error in island management\n");
}
assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
@@ -210,7 +207,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
btCollisionObject* colObj0 = collisionObjects[i];
if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
{
printf("error in island management\n");
// printf("error in island management\n");
}
assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
@@ -231,7 +228,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
btCollisionObject* colObj0 = collisionObjects[i];
if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
{
printf("error in island management\n");
// printf("error in island management\n");
}
assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
@@ -247,11 +244,17 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
}
}
btAlignedObjectArray<btPersistentManifold*> islandmanifold;
int i;
int maxNumManifolds = dispatcher->getNumManifolds();
islandmanifold.reserve(maxNumManifolds);
#define SPLIT_ISLANDS 1
#ifdef SPLIT_ISLANDS
#endif //SPLIT_ISLANDS
for (i=0;i<maxNumManifolds ;i++)
{
btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
@@ -265,29 +268,52 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
{
//kinematic objects don't merge islands, but wake up all connected objects
if (colObj0->isStaticOrKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
{
colObj1->activate();
}
if (colObj1->isStaticOrKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
{
colObj0->activate();
}
//filtering for response
#ifdef SPLIT_ISLANDS
// //filtering for response
if (dispatcher->needsResponse(colObj0,colObj1))
islandmanifold.push_back(manifold);
m_islandmanifold.push_back(manifold);
#endif //SPLIT_ISLANDS
}
}
}
int numManifolds = int (islandmanifold.size());
//
// todo: this is random access, it can be walked 'cache friendly'!
//
void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
{
buildIslands(dispatcher,collisionObjects);
int endIslandIndex=1;
int startIslandIndex;
int numElem = getUnionFind().getNumElements();
BT_PROFILE("processIslands");
#ifndef SPLIT_ISLANDS
btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer();
callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1);
#else
// Sort manifolds, based on islands
// Sort the vector using predicate and std::sort
//std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
int numManifolds = int (m_islandmanifold.size());
//we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
islandmanifold.heapSort(btPersistentManifoldSortPredicate());
m_islandmanifold.quickSort(btPersistentManifoldSortPredicate());
//now process all active islands (sets of manifolds for now)
@@ -296,10 +322,9 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
//int islandId;
END_PROFILE("islandUnionFindAndHeapSort");
btAlignedObjectArray<btCollisionObject*> islandBodies;
// printf("Start Islands\n");
//traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
@@ -313,7 +338,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
{
int i = getUnionFind().getElement(endIslandIndex).m_sz;
btCollisionObject* colObj0 = collisionObjects[i];
islandBodies.push_back(colObj0);
m_islandBodies.push_back(colObj0);
if (!colObj0->isActive())
islandSleeping = true;
}
@@ -325,12 +350,12 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
if (startManifoldIndex<numManifolds)
{
int curIslandId = getIslandId(islandmanifold[startManifoldIndex]);
int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]);
if (curIslandId == islandId)
{
startManifold = &islandmanifold[startManifoldIndex];
startManifold = &m_islandmanifold[startManifoldIndex];
for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(islandmanifold[endManifoldIndex]));endManifoldIndex++)
for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++)
{
}
@@ -342,7 +367,8 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
if (!islandSleeping)
{
callback->ProcessIsland(&islandBodies[0],islandBodies.size(),startManifold,numIslandManifolds, islandId);
callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
// printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
}
if (numIslandManifolds)
@@ -350,8 +376,9 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
startManifoldIndex = endManifoldIndex;
}
islandBodies.resize(0);
m_islandBodies.resize(0);
}
#endif //SPLIT_ISLANDS
}

View File

@@ -16,18 +16,26 @@ subject to the following restrictions:
#ifndef SIMULATION_ISLAND_MANAGER_H
#define SIMULATION_ISLAND_MANAGER_H
#include "../CollisionDispatch/btUnionFind.h"
#include "BulletCollision/CollisionDispatch/btUnionFind.h"
#include "btCollisionCreateFunc.h"
#include "LinearMath/btAlignedObjectArray.h"
class btCollisionObject;
class btCollisionWorld;
class btDispatcher;
class btPersistentManifold;
///SimulationIslandManager creates and handles simulation islands, using btUnionFind
class btSimulationIslandManager
{
btUnionFind m_unionFind;
btAlignedObjectArray<btPersistentManifold*> m_islandmanifold;
btAlignedObjectArray<btCollisionObject* > m_islandBodies;
public:
btSimulationIslandManager();
virtual ~btSimulationIslandManager();
@@ -42,7 +50,7 @@ public:
virtual void storeIslandActivationState(btCollisionWorld* world);
void findUnions(btDispatcher* dispatcher);
void findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld);
@@ -55,6 +63,8 @@ public:
void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback);
void buildIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects);
};
#endif //SIMULATION_ISLAND_MANAGER_H

View File

@@ -68,18 +68,25 @@ void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,b
btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
resultOut->setPersistentManifold(m_manifoldPtr);
if (dist < SIMD_EPSILON)
{
btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize();
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut->setPersistentManifold(m_manifoldPtr);
resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist);
}
if (m_ownManifold)
{
if (m_manifoldPtr->getNumContacts())
{
resultOut->refreshContactPoints();
}
}
}
@@ -102,8 +109,8 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
btVector3 bounds[2];
btBoxShape* boxShape= (btBoxShape*)boxObj->getCollisionShape();
bounds[0] = -boxShape->getHalfExtents();
bounds[1] = boxShape->getHalfExtents();
bounds[0] = -boxShape->getHalfExtentsWithoutMargin();
bounds[1] = boxShape->getHalfExtentsWithoutMargin();
margins = boxShape->getMargin();//also add sphereShape margin?
@@ -209,6 +216,10 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject*
btVector3 p0, tmp, prel, n[6], normal;
btScalar fSep = btScalar(-10000000.0), fSepThis;
// set p0 and normal to a default value to shup up GCC
p0.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
normal.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) );
n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) );
n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) );

View File

@@ -16,11 +16,13 @@ subject to the following restrictions:
#ifndef SPHERE_BOX_COLLISION_ALGORITHM_H
#define SPHERE_BOX_COLLISION_ALGORITHM_H
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../CollisionDispatch/btCollisionCreateFunc.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
#include "../../LinearMath/btVector3.h"
#include "btCollisionDispatcher.h"
#include "LinearMath/btVector3.h"
/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
@@ -40,6 +42,14 @@ public:
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
{
if (m_manifoldPtr && m_ownManifold)
{
manifoldArray.push_back(m_manifoldPtr);
}
}
btScalar getSphereDistance( btCollisionObject* boxObj,btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius );
btScalar getSpherePenetration( btCollisionObject* boxObj, btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax);
@@ -48,12 +58,13 @@ public:
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereBoxCollisionAlgorithm));
if (!m_swapped)
{
return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false);
return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false);
} else
{
return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true);
return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true);
}
}
};

View File

@@ -46,6 +46,8 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
if (!m_manifoldPtr)
return;
resultOut->setPersistentManifold(m_manifoldPtr);
btSphereShape* sphere0 = (btSphereShape*)col0->getCollisionShape();
btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape();
@@ -54,23 +56,41 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
btScalar radius0 = sphere0->getRadius();
btScalar radius1 = sphere1->getRadius();
#ifdef CLEAR_MANIFOLD
m_manifoldPtr->clearManifold(); //don't do this, it disables warmstarting
#endif
///iff distance positive, don't generate a new contact
if ( len > (radius0+radius1))
{
#ifndef CLEAR_MANIFOLD
resultOut->refreshContactPoints();
#endif //CLEAR_MANIFOLD
return;
}
///distance (negative means penetration)
btScalar dist = len - (radius0+radius1);
btVector3 normalOnSurfaceB = diff / len;
btVector3 normalOnSurfaceB(1,0,0);
if (len > SIMD_EPSILON)
{
normalOnSurfaceB = diff / len;
}
///point on A (worldspace)
btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB;
///point on B (worldspace)
btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB;
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut->setPersistentManifold(m_manifoldPtr);
resultOut->addContactPoint(normalOnSurfaceB,pos1,dist);
#ifndef CLEAR_MANIFOLD
resultOut->refreshContactPoints();
#endif //CLEAR_MANIFOLD
}
btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)

View File

@@ -16,9 +16,11 @@ subject to the following restrictions:
#ifndef SPHERE_SPHERE_COLLISION_ALGORITHM_H
#define SPHERE_SPHERE_COLLISION_ALGORITHM_H
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../CollisionDispatch/btCollisionCreateFunc.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
#include "btCollisionDispatcher.h"
class btPersistentManifold;
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
@@ -39,6 +41,13 @@ public:
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
{
if (m_manifoldPtr && m_ownManifold)
{
manifoldArray.push_back(m_manifoldPtr);
}
}
virtual ~btSphereSphereCollisionAlgorithm();
@@ -46,7 +55,8 @@ public:
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
return new btSphereSphereCollisionAlgorithm(0,ci,body0,body1);
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereSphereCollisionAlgorithm));
return new(mem) btSphereSphereCollisionAlgorithm(0,ci,body0,body1);
}
};

View File

@@ -48,8 +48,11 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
if (!m_manifoldPtr)
return;
btSphereShape* sphere = (btSphereShape*)col0->getCollisionShape();
btTriangleShape* triangle = (btTriangleShape*)col1->getCollisionShape();
btCollisionObject* sphereObj = m_swapped? col1 : col0;
btCollisionObject* triObj = m_swapped? col0 : col1;
btSphereShape* sphere = (btSphereShape*)sphereObj->getCollisionShape();
btTriangleShape* triangle = (btTriangleShape*)triObj->getCollisionShape();
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut->setPersistentManifold(m_manifoldPtr);
@@ -57,11 +60,16 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
input.m_maximumDistanceSquared = btScalar(1e30);//todo: tighter bounds
input.m_transformA = col0->getWorldTransform();
input.m_transformB = col1->getWorldTransform();
input.m_transformA = sphereObj->getWorldTransform();
input.m_transformB = triObj->getWorldTransform();
detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
bool swapResults = m_swapped;
detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw,swapResults);
if (m_ownManifold)
resultOut->refreshContactPoints();
}
btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)

View File

@@ -16,10 +16,11 @@ subject to the following restrictions:
#ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../CollisionDispatch/btCollisionCreateFunc.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
#include "btCollisionDispatcher.h"
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
@@ -40,6 +41,13 @@ public:
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
{
if (m_manifoldPtr && m_ownManifold)
{
manifoldArray.push_back(m_manifoldPtr);
}
}
virtual ~btSphereTriangleCollisionAlgorithm();
@@ -49,7 +57,9 @@ public:
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
return new btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped);
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm));
return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped);
}
};

View File

@@ -18,6 +18,7 @@ subject to the following restrictions:
btUnionFind::~btUnionFind()
{
Free();
@@ -76,8 +77,7 @@ void btUnionFind::sortIslands()
// Sort the vector using predicate and std::sort
//std::sort(m_elements.begin(), m_elements.end(), btUnionFindElementSortPredicate);
//perhaps use radix sort?
m_elements.heapSort(btUnionFindElementSortPredicate());
m_elements.quickSort(btUnionFindElementSortPredicate());
}

View File

@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef UNION_FIND_H
#define UNION_FIND_H
#include "../../LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
#define USE_PATH_COMPRESSION 1
@@ -46,11 +46,11 @@ class btUnionFind
void reset(int N);
inline int getNumElements() const
SIMD_FORCE_INLINE int getNumElements() const
{
return int(m_elements.size());
}
inline bool isRoot(int x) const
SIMD_FORCE_INLINE bool isRoot(int x) const
{
return (x == m_elements[x].m_id);
}

View File

@@ -15,35 +15,20 @@ subject to the following restrictions:
#include "btBoxShape.h"
btVector3 btBoxShape::getHalfExtents() const
{
return m_implicitShapeDimensions * m_localScaling;
}
//{
void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
btVector3 halfExtents = getHalfExtents();
btMatrix3x3 abs_b = t.getBasis().absolute();
btPoint3 center = t.getOrigin();
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
abs_b[1].dot(halfExtents),
abs_b[2].dot(halfExtents));
extent += btVector3(getMargin(),getMargin(),getMargin());
aabbMin = center - extent;
aabbMax = center + extent;
btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax);
}
void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
{
//btScalar margin = btScalar(0.);
btVector3 halfExtents = getHalfExtents();
btVector3 halfExtents = getHalfExtentsWithMargin();
btScalar lx=btScalar(2.)*(halfExtents.x());
btScalar ly=btScalar(2.)*(halfExtents.y());

View File

@@ -18,11 +18,11 @@ subject to the following restrictions:
#include "btPolyhedralConvexShape.h"
#include "btCollisionMargin.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../../LinearMath/btPoint3.h"
#include "../../LinearMath/btSimdMinMax.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "LinearMath/btPoint3.h"
#include "LinearMath/btMinMax.h"
///btBoxShape implements both a feature based (vertex/edge/plane) and implicit (getSupportingVertex) Box
///The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
class btBoxShape: public btPolyhedralConvexShape
{
@@ -31,47 +31,52 @@ class btBoxShape: public btPolyhedralConvexShape
public:
btVector3 getHalfExtents() const;
btVector3 getHalfExtentsWithMargin() const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
btVector3 margin(getMargin(),getMargin(),getMargin());
halfExtents += margin;
return halfExtents;
}
const btVector3& getHalfExtentsWithoutMargin() const
{
return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
}
virtual int getShapeType() const { return BOX_SHAPE_PROXYTYPE;}
virtual btVector3 localGetSupportingVertex(const btVector3& vec) const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
btVector3 margin(getMargin(),getMargin(),getMargin());
halfExtents += margin;
btVector3 halfExtents = getHalfExtents();
btVector3 supVertex;
supVertex = btPoint3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
return supVertex;
return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
}
virtual inline btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const
SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
btVector3 halfExtents = getHalfExtents();
btVector3 margin(getMargin(),getMargin(),getMargin());
halfExtents -= margin;
return btVector3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
const btVector3& halfExtents = getHalfExtentsWithoutMargin();
return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
}
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
{
btVector3 halfExtents = getHalfExtents();
btVector3 margin(getMargin(),getMargin(),getMargin());
halfExtents -= margin;
const btVector3& halfExtents = getHalfExtentsWithoutMargin();
for (int i=0;i<numVectors;i++)
{
const btVector3& vec = vectors[i];
supportVerticesOut[i].setValue(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
}
}
@@ -79,14 +84,38 @@ public:
btBoxShape( const btVector3& boxHalfExtents)
{
m_implicitShapeDimensions = boxHalfExtents;
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
};
virtual void setMargin(btScalar collisionMargin)
{
//correct the m_implicitShapeDimensions for the margin
btVector3 oldMargin(getMargin(),getMargin(),getMargin());
btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
btConvexInternalShape::setMargin(collisionMargin);
btVector3 newMargin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
}
virtual void setLocalScaling(const btVector3& scaling)
{
btVector3 oldMargin(getMargin(),getMargin(),getMargin());
btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
btConvexInternalShape::setLocalScaling(scaling);
m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
}
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const
{
@@ -116,7 +145,7 @@ public:
virtual void getVertex(int i,btVector3& vtx) const
{
btVector3 halfExtents = getHalfExtents();
btVector3 halfExtents = getHalfExtentsWithoutMargin();
vtx = btVector3(
halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
@@ -127,7 +156,7 @@ public:
virtual void getPlaneEquation(btVector4& plane,int i) const
{
btVector3 halfExtents = getHalfExtents();
btVector3 halfExtents = getHalfExtentsWithoutMargin();
switch (i)
{
@@ -234,7 +263,7 @@ public:
virtual bool isInside(const btPoint3& pt,btScalar tolerance) const
{
btVector3 halfExtents = getHalfExtents();
btVector3 halfExtents = getHalfExtentsWithoutMargin();
//btScalar minDist = 2*tolerance;
@@ -250,7 +279,7 @@ public:
//debugging
virtual char* getName()const
virtual const char* getName()const
{
return "Box";
}
@@ -291,3 +320,4 @@ public:
#endif //OBB_BOX_MINKOWSKI_H

View File

@@ -18,32 +18,56 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression)
:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh)
:btTriangleMeshShape(meshInterface),
m_bvh(0),
m_useQuantizedAabbCompression(useQuantizedAabbCompression),
m_ownsBvh(false)
{
//construct bvh from meshInterface
#ifndef DISABLE_BVH
m_bvh = new btOptimizedBvh();
btVector3 bvhAabbMin,bvhAabbMax;
meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
if(meshInterface->hasPremadeAabb())
{
meshInterface->getPremadeAabb(&bvhAabbMin, &bvhAabbMax);
}
else
{
meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
}
if (buildBvh)
{
void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
m_bvh = new (mem) btOptimizedBvh();
m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
m_ownsBvh = true;
}
#endif //DISABLE_BVH
}
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh)
:btTriangleMeshShape(meshInterface),
m_bvh(0),
m_useQuantizedAabbCompression(useQuantizedAabbCompression),
m_ownsBvh(false)
{
//construct bvh from meshInterface
#ifndef DISABLE_BVH
m_bvh = new btOptimizedBvh();
m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
if (buildBvh)
{
void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
m_bvh = new (mem) btOptimizedBvh();
m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
m_ownsBvh = true;
}
#endif //DISABLE_BVH
@@ -58,16 +82,140 @@ void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btV
}
void btBvhTriangleMeshShape::refitTree()
void btBvhTriangleMeshShape::refitTree(const btVector3& aabbMin,const btVector3& aabbMax)
{
m_bvh->refit( m_meshInterface );
m_bvh->refit( m_meshInterface, aabbMin,aabbMax );
recalcLocalAabb();
}
btBvhTriangleMeshShape::~btBvhTriangleMeshShape()
{
delete m_bvh;
if (m_ownsBvh)
{
m_bvh->~btOptimizedBvh();
btAlignedFree(m_bvh);
}
}
void btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget)
{
struct MyNodeOverlapCallback : public btNodeOverlapCallback
{
btStridingMeshInterface* m_meshInterface;
btTriangleCallback* m_callback;
MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
:m_meshInterface(meshInterface),
m_callback(callback)
{
}
virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
{
btVector3 m_triangle[3];
const unsigned char *vertexbase;
int numverts;
PHY_ScalarType type;
int stride;
const unsigned char *indexbase;
int indexstride;
int numfaces;
PHY_ScalarType indicestype;
m_meshInterface->getLockedReadOnlyVertexIndexBase(
&vertexbase,
numverts,
type,
stride,
&indexbase,
indexstride,
numfaces,
indicestype,
nodeSubPart);
unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
const btVector3& meshScaling = m_meshInterface->getScaling();
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
}
/* Perform ray vs. triangle collision here */
m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
}
};
MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface);
m_bvh->reportRayOverlappingNodex(&myNodeCallback,raySource,rayTarget);
}
void btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax)
{
struct MyNodeOverlapCallback : public btNodeOverlapCallback
{
btStridingMeshInterface* m_meshInterface;
btTriangleCallback* m_callback;
MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
:m_meshInterface(meshInterface),
m_callback(callback)
{
}
virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
{
btVector3 m_triangle[3];
const unsigned char *vertexbase;
int numverts;
PHY_ScalarType type;
int stride;
const unsigned char *indexbase;
int indexstride;
int numfaces;
PHY_ScalarType indicestype;
m_meshInterface->getLockedReadOnlyVertexIndexBase(
&vertexbase,
numverts,
type,
stride,
&indexbase,
indexstride,
numfaces,
indicestype,
nodeSubPart);
unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
const btVector3& meshScaling = m_meshInterface->getScaling();
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
}
/* Perform ray vs. triangle collision here */
m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
}
};
MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface);
m_bvh->reportBoxCastOverlappingNodex (&myNodeCallback, raySource, rayTarget, aabbMin, aabbMax);
}
//perform bvh tree traversal and report overlapping triangles to 'callback'
@@ -118,13 +266,14 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
indicestype,
nodeSubPart);
int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride);
unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
const btVector3& meshScaling = m_meshInterface->getScaling();
for (int j=2;j>=0;j--)
{
int graphicsindex = gfxbase[j];
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
#ifdef DEBUG_TRIANGLE_MESH
@@ -157,17 +306,37 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
}
void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
{
if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
{
btTriangleMeshShape::setLocalScaling(scaling);
delete m_bvh;
///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
m_bvh = new btOptimizedBvh();
//rebuild the bvh...
m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
}
if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
{
btTriangleMeshShape::setLocalScaling(scaling);
if (m_ownsBvh)
{
m_bvh->~btOptimizedBvh();
btAlignedFree(m_bvh);
}
///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
m_bvh = new(mem) btOptimizedBvh();
//rebuild the bvh...
m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
m_ownsBvh = true;
}
}
void btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling)
{
btAssert(!m_bvh);
btAssert(!m_ownsBvh);
m_bvh = bvh;
m_ownsBvh = false;
// update the scaling without rebuilding the bvh
if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
{
btTriangleMeshShape::setLocalScaling(scaling);
}
}

View File

@@ -18,45 +18,55 @@ subject to the following restrictions:
#include "btTriangleMeshShape.h"
#include "btOptimizedBvh.h"
#include "LinearMath/btAlignedAllocator.h"
///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
///The btBvhTriangleMeshShape is a static-triangle mesh shape with several optimizations, such as bounding volume hierarchy and cache friendly traversal for PlayStation 3 Cell SPU. It is recommended to enable useQuantizedAabbCompression for better memory usage.
///It takes a triangle mesh as input, for example a btTriangleMesh or btTriangleIndexVertexArray. The btBvhTriangleMeshShape class allows for triangle mesh deformations by a refit or partialRefit method.
///Instead of building the bounding volume hierarchy acceleration structure, it is also possible to serialize (save) and deserialize (load) the structure from disk.
///See Demos\ConcaveDemo\ConcavePhysicsDemo.cpp for an example.
ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape
{
btOptimizedBvh* m_bvh;
bool m_useQuantizedAabbCompression;
bool m_pad[12];////need padding due to alignment
bool m_ownsBvh;
bool m_pad[11];////need padding due to alignment
public:
btBvhTriangleMeshShape() :btTriangleMeshShape(0) {};
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression);
BT_DECLARE_ALIGNED_ALLOCATOR();
btBvhTriangleMeshShape() :btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {};
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true);
///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true);
virtual ~btBvhTriangleMeshShape();
/*
bool getOwnsBvh () const
{
return m_ownsBvh;
}
virtual int getShapeType() const
{
return TRIANGLE_MESH_SHAPE_PROXYTYPE;
}
*/
void performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget);
void performConvexcast (btTriangleCallback* callback, const btVector3& boxSource, const btVector3& boxTarget, const btVector3& boxMin, const btVector3& boxMax);
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
void refitTree();
void refitTree(const btVector3& aabbMin,const btVector3& aabbMax);
///for a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks
void partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax);
//debugging
virtual char* getName()const {return "BVHTRIANGLEMESH";}
virtual const char* getName()const {return "BVHTRIANGLEMESH";}
virtual void setLocalScaling(const btVector3& scaling);
@@ -65,6 +75,10 @@ public:
{
return m_bvh;
}
void setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& localScaling=btVector3(1,1,1));
bool usesQuantizedAabbCompression() const
{
return m_useQuantizedAabbCompression;

View File

@@ -21,6 +21,7 @@ subject to the following restrictions:
btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
{
m_upAxis = 1;
m_implicitShapeDimensions.setValue(radius,0.5f*height,radius);
}
@@ -50,7 +51,9 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
{
btVector3 pos(0,getHalfHeight(),0);
btVector3 pos(0,0,0);
pos[getUpAxis()] = getHalfHeight();
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
@@ -60,7 +63,9 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
}
}
{
btVector3 pos(0,-getHalfHeight(),0);
btVector3 pos(0,0,0);
pos[getUpAxis()] = -getHalfHeight();
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
@@ -88,7 +93,8 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
btVector3 vtx;
btScalar newDot;
{
btVector3 pos(0,getHalfHeight(),0);
btVector3 pos(0,0,0);
pos[getUpAxis()] = getHalfHeight();
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
@@ -98,7 +104,8 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
}
}
{
btVector3 pos(0,-getHalfHeight(),0);
btVector3 pos(0,0,0);
pos[getUpAxis()] = -getHalfHeight();
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
@@ -112,7 +119,7 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
}
void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
{
//as an approximation, take the inertia of the box that bounds the spheres
@@ -122,7 +129,8 @@ void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
btScalar radius = getRadius();
btVector3 halfExtents(radius,radius+getHalfHeight(),radius);
btVector3 halfExtents(radius,radius,radius);
halfExtents[getUpAxis()]+=getHalfHeight();
btScalar margin = CONVEX_DISTANCE_MARGIN;
@@ -140,6 +148,22 @@ void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
}
btCapsuleShapeX::btCapsuleShapeX(btScalar radius,btScalar height)
{
m_upAxis = 0;
m_implicitShapeDimensions.setValue(0.5f*height, radius,radius);
}
btCapsuleShapeZ::btCapsuleShapeZ(btScalar radius,btScalar height)
{
m_upAxis = 2;
m_implicitShapeDimensions.setValue(radius,radius,0.5f*height);
}

View File

@@ -16,20 +16,27 @@ subject to the following restrictions:
#ifndef BT_CAPSULE_SHAPE_H
#define BT_CAPSULE_SHAPE_H
#include "btConvexShape.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "btConvexInternalShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
///btCapsuleShape represents a capsule around the Y axis
///A more general solution that can represent capsules is the btMultiSphereShape
class btCapsuleShape : public btConvexShape
///The btCapsuleShape represents a capsule around the Y axis, there is also the btCapsuleShapeX aligned around the X axis and btCapsuleShapeZ around the Z axis.
///The total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
///The btCapsuleShape is a convex hull of two spheres. The btMultiSphereShape is a more general collision shape that takes the convex hull of multiple sphere, so it can also represent a capsule when just using two spheres.
class btCapsuleShape : public btConvexInternalShape
{
protected:
int m_upAxis;
protected:
///only used for btCapsuleShapeZ and btCapsuleShapeX subclasses.
btCapsuleShape() {};
public:
btCapsuleShape(btScalar radius,btScalar height);
///CollisionShape Interface
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
/// btConvexShape Interface
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
@@ -38,23 +45,76 @@ public:
virtual int getShapeType() const { return CAPSULE_SHAPE_PROXYTYPE; }
virtual char* getName()const
virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
{
btVector3 halfExtents(getRadius(),getRadius(),getRadius());
halfExtents[m_upAxis] = getRadius() + getHalfHeight();
halfExtents += btVector3(getMargin(),getMargin(),getMargin());
btMatrix3x3 abs_b = t.getBasis().absolute();
btPoint3 center = t.getOrigin();
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
aabbMin = center - extent;
aabbMax = center + extent;
}
virtual const char* getName()const
{
return "CapsuleShape";
}
int getUpAxis() const
{
return m_upAxis;
}
btScalar getRadius() const
{
return m_implicitShapeDimensions.getX();
int radiusAxis = (m_upAxis+2)%3;
return m_implicitShapeDimensions[radiusAxis];
}
btScalar getHalfHeight() const
{
return m_implicitShapeDimensions.getY();
return m_implicitShapeDimensions[m_upAxis];
}
};
///btCapsuleShapeX represents a capsule around the Z axis
///the total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
class btCapsuleShapeX : public btCapsuleShape
{
public:
btCapsuleShapeX(btScalar radius,btScalar height);
//debugging
virtual const char* getName()const
{
return "CapsuleX";
}
};
///btCapsuleShapeZ represents a capsule around the Z axis
///the total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
class btCapsuleShapeZ : public btCapsuleShape
{
public:
btCapsuleShapeZ(btScalar radius,btScalar height);
//debugging
virtual const char* getName()const
{
return "CapsuleZ";
}
};
#endif //BT_CAPSULE_SHAPE_H

View File

@@ -21,7 +21,12 @@ subject to the following restrictions:
can be used by probes that are checking whether the
library is actually installed.
*/
extern "C" void btBulletCollisionProbe () {}
extern "C"
{
void btBulletCollisionProbe ();
void btBulletCollisionProbe () {}
}
@@ -46,7 +51,7 @@ btScalar btCollisionShape::getAngularMotionDisc() const
return disc;
}
void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax)
void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const
{
//start with static aabb
getAabb(curTrans,temporalAabbMin,temporalAabbMax);

View File

@@ -16,18 +16,21 @@ subject to the following restrictions:
#ifndef COLLISION_SHAPE_H
#define COLLISION_SHAPE_H
#include "../../LinearMath/btTransform.h"
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btMatrix3x3.h"
#include "../../LinearMath/btPoint3.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
#include "LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btMatrix3x3.h"
#include "LinearMath/btPoint3.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
///btCollisionShape provides interface for collision shapes that can be shared among btCollisionObjects.
///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects.
class btCollisionShape
{
void* m_userPointer;
public:
btCollisionShape()
btCollisionShape() : m_userPointer(0)
{
}
virtual ~btCollisionShape()
@@ -45,30 +48,30 @@ public:
///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep)
///result is conservative
void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax);
void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const;
#ifndef __SPU__
inline bool isPolyhedral() const
SIMD_FORCE_INLINE bool isPolyhedral() const
{
return btBroadphaseProxy::isPolyhedral(getShapeType());
}
inline bool isConvex() const
SIMD_FORCE_INLINE bool isConvex() const
{
return btBroadphaseProxy::isConvex(getShapeType());
}
inline bool isConcave() const
SIMD_FORCE_INLINE bool isConcave() const
{
return btBroadphaseProxy::isConcave(getShapeType());
}
inline bool isCompound() const
SIMD_FORCE_INLINE bool isCompound() const
{
return btBroadphaseProxy::isCompound(getShapeType());
}
///isInfinite is used to catch simulation error (aabb check)
inline bool isInfinite() const
SIMD_FORCE_INLINE bool isInfinite() const
{
return btBroadphaseProxy::isInfinite(getShapeType());
}
@@ -76,11 +79,11 @@ public:
virtual int getShapeType() const=0;
virtual void setLocalScaling(const btVector3& scaling) =0;
virtual const btVector3& getLocalScaling() const =0;
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) = 0;
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const = 0;
//debugging support
virtual char* getName()const =0 ;
virtual const char* getName()const =0 ;
#endif //__SPU__
@@ -88,6 +91,18 @@ public:
virtual void setMargin(btScalar margin) = 0;
virtual btScalar getMargin() const = 0;
///optional user data pointer
void setUserPointer(void* userPtr)
{
m_userPointer = userPtr;
}
void* getUserPointer() const
{
return m_userPointer;
}
};
#endif //COLLISION_SHAPE_H

View File

@@ -14,29 +14,42 @@ subject to the following restrictions:
*/
#include "btCompoundShape.h"
#include "btCollisionShape.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
btCompoundShape::btCompoundShape()
:m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
m_aabbTree(0),
m_collisionMargin(btScalar(0.)),
m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
m_dynamicAabbTree(0)
{
void* mem = btAlignedAlloc(sizeof(btDbvt),16);
m_dynamicAabbTree = new(mem) btDbvt();
btAssert(mem==m_dynamicAabbTree);
}
btCompoundShape::~btCompoundShape()
{
if (m_dynamicAabbTree)
{
m_dynamicAabbTree->~btDbvt();
btAlignedFree(m_dynamicAabbTree);
}
}
void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape)
{
m_childTransforms.push_back(localTransform);
m_childShapes.push_back(shape);
//m_childTransforms.push_back(localTransform);
//m_childShapes.push_back(shape);
btCompoundShapeChild child;
child.m_transform = localTransform;
child.m_childShape = shape;
child.m_childShapeType = shape->getShapeType();
child.m_childMargin = shape->getMargin();
m_children.push_back(child);
//extend the local aabbMin/aabbMax
btVector3 localAabbMin,localAabbMax;
@@ -53,39 +66,100 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
}
}
if (m_dynamicAabbTree)
{
const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
int index = m_children.size()-1;
child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index);
}
}
void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
{
btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size());
if (m_dynamicAabbTree)
{
m_dynamicAabbTree->remove(m_children[childShapeIndex].m_node);
}
m_children.swap(childShapeIndex,m_children.size()-1);
m_children.pop_back();
}
void btCompoundShape::removeChildShape(btCollisionShape* shape)
{
// Find the children containing the shape specified, and remove those children.
//note: there might be multiple children using the same shape!
for(int i = m_children.size()-1; i >= 0 ; i--)
{
if(m_children[i].m_childShape == shape)
{
m_children.swap(i,m_children.size()-1);
m_children.pop_back();
//remove it from the m_dynamicAabbTree too
//m_dynamicAabbTree->remove(m_aabbProxies[i]);
//m_aabbProxies.swap(i,m_children.size()-1);
//m_aabbProxies.pop_back();
}
}
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
recalculateLocalAabb();
}
void btCompoundShape::recalculateLocalAabb()
{
// Recalculate the local aabb
// Brute force, it iterates over all the shapes left.
m_localAabbMin = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30));
m_localAabbMax = btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
//extend the local aabbMin/aabbMax
for (int j = 0; j < m_children.size(); j++)
{
btVector3 localAabbMin,localAabbMax;
m_children[j].m_childShape->getAabb(m_children[j].m_transform, localAabbMin, localAabbMax);
for (int i=0;i<3;i++)
{
if (m_localAabbMin[i] > localAabbMin[i])
m_localAabbMin[i] = localAabbMin[i];
if (m_localAabbMax[i] < localAabbMax[i])
m_localAabbMax[i] = localAabbMax[i];
}
}
}
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
{
btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
btPoint3 center = trans(localCenter);
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
abs_b[1].dot(localHalfExtents),
abs_b[2].dot(localHalfExtents));
extent += btVector3(getMargin(),getMargin(),getMargin());
abs_b[1].dot(localHalfExtents),
abs_b[2].dot(localHalfExtents));
aabbMin = center-extent;
aabbMax = center+extent;
aabbMin = center - extent;
aabbMax = center + extent;
}
void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
{
//approximation: take the inertia from the aabb for now
btTransform ident;
ident.setIdentity();
btVector3 aabbMin,aabbMax;
getAabb(ident,aabbMin,aabbMax);
btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
btScalar lx=btScalar(2.)*(halfExtents.x());
btScalar ly=btScalar(2.)*(halfExtents.y());
btScalar lz=btScalar(2.)*(halfExtents.z());
@@ -96,5 +170,62 @@ void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
}
void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const
{
int n = m_children.size();
btScalar totalMass = 0;
btVector3 center(0, 0, 0);
for (int k = 0; k < n; k++)
{
center += m_children[k].m_transform.getOrigin() * masses[k];
totalMass += masses[k];
}
center /= totalMass;
principal.setOrigin(center);
btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0);
for (int k = 0; k < n; k++)
{
btVector3 i;
m_children[k].m_childShape->calculateLocalInertia(masses[k], i);
const btTransform& t = m_children[k].m_transform;
btVector3 o = t.getOrigin() - center;
//compute inertia tensor in coordinate system of compound shape
btMatrix3x3 j = t.getBasis().transpose();
j[0] *= i[0];
j[1] *= i[1];
j[2] *= i[2];
j = t.getBasis() * j;
//add inertia tensor
tensor[0] += j[0];
tensor[1] += j[1];
tensor[2] += j[2];
//compute inertia tensor of pointmass at o
btScalar o2 = o.length2();
j[0].setValue(o2, 0, 0);
j[1].setValue(0, o2, 0);
j[2].setValue(0, 0, o2);
j[0] += o * -o.x();
j[1] += o * -o.y();
j[2] += o * -o.z();
//add inertia tensor of pointmass
tensor[0] += masses[k] * j[0];
tensor[1] += masses[k] * j[1];
tensor[2] += masses[k] * j[2];
}
tensor.diagonalize(principal.getBasis(), btScalar(0.00001), 20);
inertia.setValue(tensor[0][0], tensor[1][1], tensor[2][2]);
}

View File

@@ -18,58 +18,97 @@ subject to the following restrictions:
#include "btCollisionShape.h"
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btTransform.h"
#include "../../LinearMath/btMatrix3x3.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include "btCollisionMargin.h"
#include "../../LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btAlignedObjectArray.h"
class btOptimizedBvh;
//class btOptimizedBvh;
struct btDbvt;
ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild
{
BT_DECLARE_ALIGNED_ALLOCATOR();
btTransform m_transform;
btCollisionShape* m_childShape;
int m_childShapeType;
btScalar m_childMargin;
struct btDbvtNode* m_node;
};
SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompoundShapeChild& c2)
{
return ( c1.m_transform == c2.m_transform &&
c1.m_childShape == c2.m_childShape &&
c1.m_childShapeType == c2.m_childShapeType &&
c1.m_childMargin == c2.m_childMargin );
}
/// btCompoundShape allows to store multiple other btCollisionShapes
/// This allows for concave collision objects. This is more general then the Static Concave btTriangleMeshShape.
class btCompoundShape : public btCollisionShape
/// This allows for moving concave collision objects. This is more general then the static concave btBvhTriangleMeshShape.
ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape
{
btAlignedObjectArray<btTransform> m_childTransforms;
btAlignedObjectArray<btCollisionShape*> m_childShapes;
//btAlignedObjectArray<btTransform> m_childTransforms;
//btAlignedObjectArray<btCollisionShape*> m_childShapes;
btAlignedObjectArray<btCompoundShapeChild> m_children;
btVector3 m_localAabbMin;
btVector3 m_localAabbMax;
btOptimizedBvh* m_aabbTree;
//btOptimizedBvh* m_aabbTree;
btDbvt* m_dynamicAabbTree;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btCompoundShape();
virtual ~btCompoundShape();
void addChildShape(const btTransform& localTransform,btCollisionShape* shape);
/// Remove all children shapes that contain the specified shape
virtual void removeChildShape(btCollisionShape* shape);
void removeChildShapeByIndex(int childShapeindex);
int getNumChildShapes() const
{
return int (m_childShapes.size());
return int (m_children.size());
}
btCollisionShape* getChildShape(int index)
{
return m_childShapes[index];
return m_children[index].m_childShape;
}
const btCollisionShape* getChildShape(int index) const
{
return m_childShapes[index];
return m_children[index].m_childShape;
}
btTransform& getChildTransform(int index)
btTransform getChildTransform(int index)
{
return m_childTransforms[index];
return m_children[index].m_transform;
}
const btTransform& getChildTransform(int index) const
const btTransform getChildTransform(int index) const
{
return m_childTransforms[index];
return m_children[index].m_transform;
}
btCompoundShapeChild* getChildList()
{
return &m_children[0];
}
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
/** Re-calculate the local Aabb. Is called at the end of removeChildShapes.
Use this yourself if you modify the children or their transforms. */
virtual void recalculateLocalAabb();
virtual void setLocalScaling(const btVector3& scaling)
{
@@ -80,8 +119,8 @@ public:
return m_localScaling;
}
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
virtual int getShapeType() const { return COMPOUND_SHAPE_PROXYTYPE;}
virtual void setMargin(btScalar margin)
@@ -92,7 +131,7 @@ public:
{
return m_collisionMargin;
}
virtual char* getName()const
virtual const char* getName()const
{
return "Compound";
}
@@ -100,11 +139,19 @@ public:
//this is optional, but should make collision queries faster, by culling non-overlapping nodes
void createAabbTreeFromChildren();
const btOptimizedBvh* getAabbTree() const
btDbvt* getDynamicAabbTree()
{
return m_aabbTree;
return m_dynamicAabbTree;
}
///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia
///and the center of mass to the current coordinate system. "masses" points to an array of masses of the children. The resulting transform
///"principal" has to be applied inversely to all children transforms in order for the local coordinate system of the compound
///shape to be centered at the center of mass and to coincide with the principal axes. This also necessitates a correction of the world transform
///of the collision object by the principal transform.
void calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const;
private:
btScalar m_collisionMargin;
protected:

View File

@@ -17,12 +17,12 @@ subject to the following restrictions:
#define CONCAVE_SHAPE_H
#include "btCollisionShape.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "btTriangleCallback.h"
///Concave shape proves an interface concave shapes that can produce triangles that overlapping a given AABB.
///Static triangle mesh, infinite plane, height field/landscapes are example that implement this interface.
///The btConcaveShape class provides an interface for non-moving (static) concave shapes.
///It has been implemented by the btStaticPlaneShape, btBvhTriangleMeshShape and btHeightfieldTerrainShape.
class btConcaveShape : public btCollisionShape
{
protected:

View File

@@ -16,11 +16,11 @@ subject to the following restrictions:
#ifndef CONE_MINKOWSKI_H
#define CONE_MINKOWSKI_H
#include "btConvexShape.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "btConvexInternalShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
///btConeShape implements a Cone shape, around the Y axis
class btConeShape : public btConvexShape
///The btConeShape implements a cone shape primitive, centered around the origin and aligned with the Y axis. The btConeShapeX is aligned around the X axis and btConeShapeZ around the Z axis.
class btConeShape : public btConvexInternalShape
{
@@ -42,7 +42,7 @@ public:
btScalar getHeight() const { return m_height;}
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia)
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const
{
btTransform identity;
identity.setIdentity();
@@ -72,7 +72,7 @@ public:
virtual int getShapeType() const { return CONE_SHAPE_PROXYTYPE; }
virtual char* getName()const
virtual const char* getName()const
{
return "Cone";
}

View File

@@ -36,6 +36,13 @@ btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int
}
void btConvexHullShape::setLocalScaling(const btVector3& scaling)
{
m_localScaling = scaling;
recalcLocalAabb();
}
void btConvexHullShape::addPoint(const btPoint3& point)
{
m_points.push_back(point);

View File

@@ -17,18 +17,17 @@ subject to the following restrictions:
#define CONVEX_HULL_SHAPE_H
#include "btPolyhedralConvexShape.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "../../LinearMath/btAlignedObjectArray.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "LinearMath/btAlignedObjectArray.h"
///ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices)
///No connectivity is needed. localGetSupportingVertex iterates linearly though all vertices.
///on modern hardware, due to cache coherency this isn't that bad. Complex algorithms tend to trash the cash.
///(memory is much slower then the cpu)
///The btConvexHullShape implements an implicit convex hull of an array of vertices.
///Bullet provides a general and fast collision detector for convex shapes based on GJK and EPA using localGetSupportingVertex.
ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape
{
btAlignedObjectArray<btPoint3> m_points;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory.
@@ -43,7 +42,12 @@ public:
return &m_points[0];
}
int getNumPoints()
const btPoint3* getPoints() const
{
return &m_points[0];
}
int getNumPoints() const
{
return m_points.size();
}
@@ -56,7 +60,7 @@ public:
virtual int getShapeType()const { return CONVEX_HULL_SHAPE_PROXYTYPE; }
//debugging
virtual char* getName()const {return "Convex";}
virtual const char* getName()const {return "Convex";}
virtual int getNumVertices() const;
@@ -67,7 +71,8 @@ public:
virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const;
virtual bool isInside(const btPoint3& pt,btScalar tolerance) const;
///in case we receive negative scaling
virtual void setLocalScaling(const btVector3& scaling);
};

View File

@@ -0,0 +1,78 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "btConvexInternalShape.h"
btConvexInternalShape::btConvexInternalShape()
: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
m_collisionMargin(CONVEX_DISTANCE_MARGIN)
{
}
void btConvexInternalShape::setLocalScaling(const btVector3& scaling)
{
m_localScaling = scaling.absolute();
}
void btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const
{
btScalar margin = getMargin();
for (int i=0;i<3;i++)
{
btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
vec[i] = btScalar(1.);
btVector3 sv = localGetSupportingVertex(vec*trans.getBasis());
btVector3 tmp = trans(sv);
maxAabb[i] = tmp[i]+margin;
vec[i] = btScalar(-1.);
tmp = trans(localGetSupportingVertex(vec*trans.getBasis()));
minAabb[i] = tmp[i]-margin;
}
};
btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)const
{
#ifndef __SPU__
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
}
return supVertex;
#else
return btVector3(0,0,0);
#endif //__SPU__
}

View File

@@ -0,0 +1,98 @@
#ifndef BT_CONVEX_INTERNAL_SHAPE_H
#define BT_CONVEX_INTERNAL_SHAPE_H
#include "btConvexShape.h"
///The btConvexInternalShape is an internal base class, shared by most convex shape implementations.
class btConvexInternalShape : public btConvexShape
{
protected:
//local scaling. collisionMargin is not scaled !
btVector3 m_localScaling;
btVector3 m_implicitShapeDimensions;
btScalar m_collisionMargin;
btScalar m_padding;
public:
btConvexInternalShape();
virtual ~btConvexInternalShape()
{
}
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
#ifndef __SPU__
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
//notice that the vectors should be unit length
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
#endif //#ifndef __SPU__
const btVector3& getImplicitShapeDimensions() const
{
return m_implicitShapeDimensions;
}
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
getAabbSlow(t,aabbMin,aabbMax);
}
virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual void setLocalScaling(const btVector3& scaling);
virtual const btVector3& getLocalScaling() const
{
return m_localScaling;
}
const btVector3& getLocalScalingNV() const
{
return m_localScaling;
}
virtual void setMargin(btScalar margin)
{
m_collisionMargin = margin;
}
virtual btScalar getMargin() const
{
return m_collisionMargin;
}
btScalar getMarginNV() const
{
return m_collisionMargin;
}
virtual int getNumPreferredPenetrationDirections() const
{
return 0;
}
virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
{
(void)penetrationVector;
(void)index;
btAssert(0);
}
};
#endif //BT_CONVEX_INTERNAL_SHAPE_H

View File

@@ -16,62 +16,3 @@ subject to the following restrictions:
#include "btConvexShape.h"
btConvexShape::btConvexShape()
: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
m_collisionMargin(CONVEX_DISTANCE_MARGIN)
{
}
void btConvexShape::setLocalScaling(const btVector3& scaling)
{
m_localScaling = scaling;
}
void btConvexShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const
{
btScalar margin = getMargin();
for (int i=0;i<3;i++)
{
btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
vec[i] = btScalar(1.);
btVector3 sv = localGetSupportingVertex(vec*trans.getBasis());
btVector3 tmp = trans(sv);
maxAabb[i] = tmp[i]+margin;
vec[i] = btScalar(-1.);
tmp = trans(localGetSupportingVertex(vec*trans.getBasis()));
minAabb[i] = tmp[i]-margin;
}
};
btVector3 btConvexShape::localGetSupportingVertex(const btVector3& vec)const
{
#ifndef __SPU__
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
}
return supVertex;
#else
return btVector3(0,0,0);
#endif //__SPU__
}

View File

@@ -18,37 +18,25 @@ subject to the following restrictions:
#include "btCollisionShape.h"
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btTransform.h"
#include "../../LinearMath/btMatrix3x3.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include "btCollisionMargin.h"
#include "LinearMath/btAlignedAllocator.h"
//todo: get rid of this btConvexCastResult thing!
struct btConvexCastResult;
#define MAX_PREFERRED_PENETRATION_DIRECTIONS 10
/// btConvexShape is an abstract shape interface.
/// The explicit part provides plane-equations, the implicit part provides GetClosestPoint interface.
/// used in combination with GJK or btConvexCast
/// The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape, btConvexHullShape etc.
/// It describes general convex shapes using the localGetSupportingVertex interface, used by collision detectors such as btGjkPairDetector.
ATTRIBUTE_ALIGNED16(class) btConvexShape : public btCollisionShape
{
protected:
//local scaling. collisionMargin is not scaled !
btVector3 m_localScaling;
btVector3 m_implicitShapeDimensions;
btScalar m_collisionMargin;
btScalar m_padding[2];
public:
btConvexShape();
BT_DECLARE_ALIGNED_ALLOCATOR();
virtual ~btConvexShape()
{
@@ -56,7 +44,7 @@ public:
}
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const =0;
#ifndef __SPU__
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
@@ -64,63 +52,24 @@ public:
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
#endif //#ifndef __SPU__
const btVector3& getImplicitShapeDimensions() const
{
return m_implicitShapeDimensions;
}
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
getAabbSlow(t,aabbMin,aabbMax);
}
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0;
virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0;
virtual void setLocalScaling(const btVector3& scaling) =0;
virtual const btVector3& getLocalScaling() const =0;
virtual void setMargin(btScalar margin)=0;
virtual btScalar getMargin() const=0;
virtual int getNumPreferredPenetrationDirections() const=0;
virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0;
virtual void setLocalScaling(const btVector3& scaling);
virtual const btVector3& getLocalScaling() const
{
return m_localScaling;
}
const btVector3& getLocalScalingNV() const
{
return m_localScaling;
}
virtual void setMargin(btScalar margin)
{
m_collisionMargin = margin;
}
virtual btScalar getMargin() const
{
return m_collisionMargin;
}
btScalar getMarginNV() const
{
return m_collisionMargin;
}
virtual int getNumPreferredPenetrationDirections() const
{
return 0;
}
virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
{
(void)penetrationVector;
(void)index;
btAssert(0);
}
}
;
};

View File

@@ -19,10 +19,11 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface)
btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface, bool calcAabb)
:m_stridingMesh(meshInterface)
{
recalcLocalAabb();
if ( calcAabb )
recalcLocalAabb();
}
@@ -203,3 +204,113 @@ const btVector3& btConvexTriangleMeshShape::getLocalScaling() const
{
return m_stridingMesh->getScaling();
}
void btConvexTriangleMeshShape::calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const
{
class CenterCallback: public btInternalTriangleIndexCallback
{
bool first;
btVector3 ref;
btVector3 sum;
btScalar volume;
public:
CenterCallback() : first(true), ref(0, 0, 0), sum(0, 0, 0), volume(0)
{
}
virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
{
(void) triangleIndex;
(void) partId;
if (first)
{
ref = triangle[0];
first = false;
}
else
{
btScalar vol = btFabs((triangle[0] - ref).triple(triangle[1] - ref, triangle[2] - ref));
sum += (btScalar(0.25) * vol) * ((triangle[0] + triangle[1] + triangle[2] + ref));
volume += vol;
}
}
btVector3 getCenter()
{
return (volume > 0) ? sum / volume : ref;
}
btScalar getVolume()
{
return volume * btScalar(1. / 6);
}
};
class InertiaCallback: public btInternalTriangleIndexCallback
{
btMatrix3x3 sum;
btVector3 center;
public:
InertiaCallback(btVector3& center) : sum(0, 0, 0, 0, 0, 0, 0, 0, 0), center(center)
{
}
virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
{
(void) triangleIndex;
(void) partId;
btMatrix3x3 i;
btVector3 a = triangle[0] - center;
btVector3 b = triangle[1] - center;
btVector3 c = triangle[2] - center;
btVector3 abc = a + b + c;
btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6);
for (int j = 0; j < 3; j++)
{
for (int k = 0; k <= j; k++)
{
i[j][k] = i[k][j] = volNeg * (center[j] * center[k]
+ btScalar(0.25) * (center[j] * abc[k] + center[k] * abc[j])
+ btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
+ btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j]));
}
}
btScalar i00 = -i[0][0];
btScalar i11 = -i[1][1];
btScalar i22 = -i[2][2];
i[0][0] = i11 + i22;
i[1][1] = i22 + i00;
i[2][2] = i00 + i11;
sum[0] += i[0];
sum[1] += i[1];
sum[2] += i[2];
}
btMatrix3x3& getInertia()
{
return sum;
}
};
CenterCallback centerCallback;
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
m_stridingMesh->InternalProcessAllTriangles(&centerCallback, -aabbMax, aabbMax);
btVector3 center = centerCallback.getCenter();
principal.setOrigin(center);
volume = centerCallback.getVolume();
InertiaCallback inertiaCallback(center);
m_stridingMesh->InternalProcessAllTriangles(&inertiaCallback, -aabbMax, aabbMax);
btMatrix3x3& i = inertiaCallback.getInertia();
i.diagonalize(principal.getBasis(), btScalar(0.00001), 20);
inertia.setValue(i[0][0], i[1][1], i[2][2]);
inertia /= volume;
}

View File

@@ -3,20 +3,24 @@
#include "btPolyhedralConvexShape.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
/// btConvexTriangleMeshShape is a convex hull of a triangle mesh. If you just have a point cloud, you can use btConvexHullShape instead.
/// It uses the btStridingMeshInterface instead of a point cloud. This can avoid the duplication of the triangle mesh data.
/// The btConvexTriangleMeshShape is a convex hull of a triangle mesh, but the performance is not as good as btConvexHullShape.
/// A small benefit of this class is that it uses the btStridingMeshInterface, so you can avoid the duplication of the triangle mesh data. Nevertheless, most users should use the much better performing btConvexHullShape instead.
class btConvexTriangleMeshShape : public btPolyhedralConvexShape
{
class btStridingMeshInterface* m_stridingMesh;
public:
btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface);
btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface, bool calcAabb = true);
class btStridingMeshInterface* getStridingMesh()
class btStridingMeshInterface* getMeshInterface()
{
return m_stridingMesh;
}
const class btStridingMeshInterface* getMeshInterface() const
{
return m_stridingMesh;
}
@@ -28,7 +32,7 @@ public:
virtual int getShapeType()const { return CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE; }
//debugging
virtual char* getName()const {return "ConvexTrimesh";}
virtual const char* getName()const {return "ConvexTrimesh";}
virtual int getNumVertices() const;
virtual int getNumEdges() const;
@@ -42,6 +46,13 @@ public:
virtual void setLocalScaling(const btVector3& scaling);
virtual const btVector3& getLocalScaling() const;
///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia
///and the center of mass to the current coordinate system. A mass of 1 is assumed, for other masses just multiply the computed "inertia"
///by the mass. The resulting transform "principal" has to be applied inversely to the mesh in order for the local coordinate system of the
///shape to be centered at the center of mass and to coincide with the principal axes. This also necessitates a correction of the world transform
///of the collision object by the principal transform. This method also computes the volume of the convex mesh.
void calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const;
};
@@ -49,3 +60,4 @@ public:
#endif //CONVEX_TRIANGLEMESH_SHAPE_H

View File

@@ -45,7 +45,7 @@ void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3&
}
inline btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v)
SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v)
{
const int cylinderUpAxis = 0;
const int XX = 1;
@@ -163,24 +163,24 @@ const int ZZ = 1;
btVector3 btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
return CylinderLocalSupportX(getHalfExtents(),vec);
return CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vec);
}
btVector3 btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
return CylinderLocalSupportZ(getHalfExtents(),vec);
return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vec);
}
btVector3 btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
return CylinderLocalSupportY(getHalfExtents(),vec);
return CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vec);
}
void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
{
for (int i=0;i<numVectors;i++)
{
supportVerticesOut[i] = CylinderLocalSupportY(getHalfExtents(),vectors[i]);
supportVerticesOut[i] = CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vectors[i]);
}
}
@@ -188,7 +188,7 @@ void btCylinderShapeZ::batchedUnitVectorGetSupportingVertexWithoutMargin(const b
{
for (int i=0;i<numVectors;i++)
{
supportVerticesOut[i] = CylinderLocalSupportZ(getHalfExtents(),vectors[i]);
supportVerticesOut[i] = CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vectors[i]);
}
}
@@ -199,7 +199,7 @@ void btCylinderShapeX::batchedUnitVectorGetSupportingVertexWithoutMargin(const b
{
for (int i=0;i<numVectors;i++)
{
supportVerticesOut[i] = CylinderLocalSupportX(getHalfExtents(),vectors[i]);
supportVerticesOut[i] = CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vectors[i]);
}
}

View File

@@ -17,10 +17,10 @@ subject to the following restrictions:
#define CYLINDER_MINKOWSKI_H
#include "btBoxShape.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "../../LinearMath/btVector3.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "LinearMath/btVector3.h"
/// implements cylinder shape interface
/// The btCylinderShape class implements a cylinder shape primitive, centered around the origin. Its central axis aligned with the Y axis. btCylinderShapeX is aligned with the X axis and btCylinderShapeZ around the Z axis.
class btCylinderShape : public btBoxShape
{
@@ -60,7 +60,7 @@ public:
//use box inertia
// virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
// virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
virtual int getShapeType() const
{
@@ -74,11 +74,11 @@ public:
virtual btScalar getRadius() const
{
return getHalfExtents().getX();
return getHalfExtentsWithMargin().getX();
}
//debugging
virtual char* getName()const
virtual const char* getName()const
{
return "CylinderY";
}
@@ -96,14 +96,14 @@ public:
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
//debugging
virtual char* getName()const
virtual const char* getName()const
{
return "CylinderX";
}
virtual btScalar getRadius() const
{
return getHalfExtents().getY();
return getHalfExtentsWithMargin().getY();
}
};
@@ -121,14 +121,14 @@ public:
return 2;
}
//debugging
virtual char* getName()const
virtual const char* getName()const
{
return "CylinderZ";
}
virtual btScalar getRadius() const
{
return getHalfExtents().getX();
return getHalfExtentsWithMargin().getX();
}
};

View File

@@ -40,7 +40,7 @@ void btEmptyShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aa
}
void btEmptyShape::calculateLocalInertia(btScalar ,btVector3& )
void btEmptyShape::calculateLocalInertia(btScalar ,btVector3& ) const
{
btAssert(0);
}

View File

@@ -18,16 +18,16 @@ subject to the following restrictions:
#include "btConcaveShape.h"
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btTransform.h"
#include "../../LinearMath/btMatrix3x3.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include "btCollisionMargin.h"
/// btEmptyShape is a collision shape without actual collision detection.
///It can be replaced by another shape during runtime
/// The btEmptyShape is a collision shape without actual collision detection shape, so most users should ignore this class.
/// It can be replaced by another shape during runtime, but the inertia tensor should be recomputed.
class btEmptyShape : public btConcaveShape
{
public:
@@ -49,12 +49,12 @@ public:
return m_localScaling;
}
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
virtual int getShapeType() const { return EMPTY_SHAPE_PROXYTYPE;}
virtual char* getName()const
virtual const char* getName()const
{
return "Empty";
}

Some files were not shown because too many files have changed in this diff Show More