Bullet Physics - btConvexShape to Softbody - bulletphysics

I have a simple question: How do I convert a btConvexShape to a btSoftBody? By using btSoftBodyHelpers::CreateFromConvexHull? If so, I'm not clear on how I pass the convex hull to the softbody helper based on bullets documentation for the helper and convex shape

btConvexShape can be any convex object in bullet, not just a convex hull. You should implement different approaches depending on the concrete subclass. Use btCollisionShape::getShapeType() (return values) to find out the concrete implementation, then cast. Eg:
btSoftBody* convexShapeToSoft(const btConvexShape& shape)
{
if(shape.getShapeType() == BOX_SHAPE_PROXYTYPE)
{
const btBoxShape& boxShape = static_cast<const btBoxShape&>(shape);
// Build btSoftBody using the box vertices
}
else if(shape.getShapeType() == SPHERE_SHAPE_PROXYTYPE)
{
const btSphereShape& shpereShape = static_cast<const btSphereShape&>(shape);
// Build btSoftBody using the box vertices
}
// ....
}

Related

How to remove duplicate vertices and their vertex handles when performing hole filling in OpenFlipper based on OpenMesh

Recently, I am using the plugin "hole filling" of OpenFlipper, and have entirely compiled the OpenFlipper. However, the new mesh has a large number of duplicate vertices, when I tried to add the filling patch to the original mesh. I used the following codes to perform the adding operation:
// filling_patch: newly created filling mesh
// mesh_ori: the original mesh before hole filling
class MeshT::FaceHandle fh;
class MeshT::FaceIter f_it, f_end;
class MeshT::FaceVertexIter fv_it;
for(f_it = filling_patch->faces_begin(), f_end = fill_patch ->faces_end(); f_it != f_end; f_it++)
{
// ith face
fh = *f_it;
// Check whether it is valid
if(!fh.is_valid())
{
return;
}
// Store its three vertices
std::vector<class MeshT::VertexHandle> face_vhandles;
face_vhandles.clear();
// Iterate each vertex of this face
for(fv_it = mesh_ori->fv_iter(fh); fv_it.is_valid(); fv_it++)
{
// Get the 3D point
class MeshT::Point p = filling_patch->point(*fv_it);
// Add this point to original mesh. Note: vh is a new vertevHandle, differ to *fv_it
class MeshT::VertexHandle vh = mesh_ori->add_vertex(p);
face_vhandles.push_back(vh);
}
// Save the face to mesh
mesh_ori->add_face(face_vhandles);
}
So, I am not sure whether there is an existing function that can be used to fix this problem in OpenMesh.
Does someone give me some advice?
Thanks a lot.

Viewer `rayIntersect` doesn't ignore transparents when it should

For some reason when I'm trying to cast a ray using viewer.rayIntersect it still hits transparent objects.
Looking at the rayIntersect implementation it looks like _modelQueue.rayIntersect ignores transparent objects while avp.VBIntersector.intersectObject does not.
// ... rayIntersect implementation
var result = _modelQueue.rayIntersect(ray.origin, ray.direction, ignoreTransparent, dbIds, modelIds, intersections);
if (this.sceneAfter.children.length) {
var raycaster = new THREE.Raycaster(ray.origin, ray.direction, this.camera.near, this.camera.far);
var intersects = [];
avp.VBIntersector.intersectObject(this.sceneAfter, raycaster, intersects, true);
if (intersects.length) {
if (!result || intersects[0].distance < result.distance) {
result = intersects[0];
}
}
}
// ... rayIntersect implementation
Is there another way to cast a ray to get around this issue?
Edit:
Maybe it worth mentioning that the ray hits a Room Geometry (though invisible):
The blue dot is the ray intersection point, you can see it 'floats in the air' instead of being on the floor.
I'm using version 3.1

Liskov Substitution Principle example

LSP is the hardest in SOLID for me to understand correctly.
LSP states that objects in a program should be replaceable with instances of their subtypes without altering the correctness of the program.
So if we have this typical rectangle - square example:
rect = new Rectangle();
rect.width = 10;
rect.height = 20;
and then we try to test it:
assert 10 == rect.width
assert 20 == rect.height
Everything is ok, but when we try to say that square is rectangle as well we use:
rect = new Square();
Square actually has both height and width the same, which will make tests fail.
So how do we resolve this problem? We segragate classes for Square and Rectangle to avoid LSP problem in this case?
In this particular example, the solution is to not let Square derive from Rectangle, because although we usually say inheritance is an 'is a' relationship, you should see it as an 'behaves like' relationship. So although mathematically, a Square is a Rectangle, a Square does certainly not behave like a Rectangle (as you prove in the code above).
Instead, let them both derive from the same base class:
public abstract class Shape { }
public class Square : Shape {
public int Size;
}
public class Rectangle : Scape {
public int Height;
public int Weight;
}

AS3 Change curve to Symbol Hitbox

I have two draggable objects, and when your drag one them it generates a line based off where your mouse is, and the line is anchored to the other object. What Id like this code to do, is generate the line at the rear of the symbol
I got this
but I need this
if ((mouseX-targetPointX<0 && mouseY-targetPointY>0) || (mouseX-targetPointX>=0 && mouseY-targetPointY<=0)) {
line.moveTo(mouseX-offset,mouseY-offset);
line.curveTo(mouseX-offset,targetPointY-offset,targetPointX-offset,targetPointY-offset);
line.lineTo(targetPointX+offset,targetPointY+offset);
line.curveTo(mouseX+offset,targetPointY+offset,mouseX+offset,mouseY+offset);
} else {
line.moveTo(mouseX-offset,mouseY+offset);
line.curveTo(mouseX-offset,targetPointY+offset,targetPointX-offset,targetPointY+offset);
line.lineTo(targetPointX+offset,targetPointY-offset);
line.curveTo(mouseX+offset,targetPointY-offset,mouseX+offset,mouseY-offset);
}
line.endFill();
};
Instead of using the mouse position as reference to draw your curve, you can use a custom Point object with the coordinates from where you want the curve to start from.
moveTo(myPoint.x, myPoint.y);
You can create any Point you want, for example at (50,200) using the relative coordinates from your Sprite, and then find the global coordinates using localToGlobal.
var globalPoint:Point = mySprite.localToGlobal(new Point(50,200));
trace(globalPoint.x,globalPoint.y);

How to determine whether a given object is a mask

Apparently, in Adobe's wisdom, both the object being mask, and the masking object contain a "mask" property. This leads to a cyclical reference that prevents determining which is the actual mask and which is the masked.
For example...
var clip:MovieClip = new MovieClip();
clip.name = "clip";
addChild(clip);
var boundary:Shape = new Shape();
boundary.name = "boundary";
clip.addChild(boundary);
clip.mask = boundary;
trace(clip.mask.name); // outputs "boundary"
trace(clip.mask.mask.name); // outputs "clip"
I've iterated through the properties of both clip and boundary, and there doesn't seem to be anything unique that sets them apart. My first thought was to force a removal of the superfluous "mask" reference in boundary, however, that also sets the mask property in clip to null, thereby removing the mask.
My second thought was to check the parent relationship of a mask. If the parent is the same as the object's mask, then the object in question is itself the mask.
var a:Array = [clip, boundary];
for each (var item in a) {
if (item.mask == item.parent) {
trace(item.name + " is a mask");
}
}
// outputs "boundary is a mask"
Seems to work, and after checking the API reference on masks, it's clear that when caching, a mask will need to be a child of the masked, however... it's also valid to have a mask at the same depth as the masked (I do this from time to time when a mask needs to not travel with the masked content).
For example...
MainTimeline ¬
0: clip ¬
0: boundary
... can also be laid out as ...
MainTimeline ¬
0: clip ¬
1: boundary
So, there's the conundrum. Any ideas on how to resolve this?
The "best" hack I've found so far is to run hitTestPoint on the objects (after making sure they have something to hit under the target). Masks do not appear to ever return true for a full pixel hit test. This seems to work in most basic situations that I've tested:
public function isMask(displayObject:DisplayObject):Boolean {
// Make sure the display object is a Class which has Graphics available,
// and is part of a mask / maskee pair.
if ((displayObject is Shape || displayObject is Sprite) && displayObject.mask) {
// Add a circle at the target object's origin.
displayObject['graphics'].beginFill(0);
displayObject['graphics'].drawCircle(0, 0, 10);
var origin:Point = displayObject.localToGlobal(new Point());
var maskLocal:Point = displayObject.mask.globalToLocal(origin);
// Add a circle at the same relative position on the "mask".
displayObject.mask['graphics'].beginFill(0);
displayObject.mask['graphics'].drawCircle(maskLocal.x, maskLocal.y, 10);
// No matter which is the actual mask, one circle will reveal the other,
// so hit testing the origin point should return true.
// However, it seems to return false if the object is actually a mask.
var hit:Boolean = displayObject.hitTestPoint(origin.x, origin.y, true);
displayObject['graphics'].clear();
displayObject.mask['graphics'].clear();
// Return true if the hit test failed.
return !hit;
} else {
return false;
}
}
Obviously you'd want to cache the graphics in case the objects already have some, and it could do with something more elegant than casting as Sprite so that it can handle Shapes, but it's a start.
Edit: Accessing ['graphics'] lets this accept Shapes, but obviously isn't super efficient. I'm not sure what the best method would be, short of adding an interface.
Great question, haven't run into this before. I wasn't aware of the cyclical reference.
If your masks are exclusively masks, I would suggest just incorporating that into your naming convention. For example calling it clipMask as opposed to boundary.
As noted in the comments, in the situation where the mask is on the same display list, you could use getChildIndex() to compare their position on the display list of the parent.
Typically in that situation I'll have the mask layered over the other display object. This is not enforced obviously, and I don't believe that it has any effect on the result of the mask visually. But it's easier to maintain for a large group than a naming convention.
Still not ideal obviously.