Similar to Cafe World. Mesh object to attach to a objectContainer depending on the which plane the mouse is on.

Software: Away3D 4.x

Tayyab, Member
Posted: 20 July 2012 02:46 AM   Total Posts: 72

Hi,

I don’t know how to explain this, but what i want is to select a mesh[object] from a menu and drag it to the shed(objectcontainer or a mesh). and when i move my mouse over that shed the mesh would move with the mouse and if the plane changes where the mouse is, the mesh would stick to that particular plane.

I had done this through drag3D class, but drag3d depends on a plane or object’s plane.

Similar to what happens in cafe world game on facebook, where you can add windows and doors and it gets stuck to the respective wall, where your mouse is.

I have attached an image of the shed i have made, at the moment what i want to do is to click and drag on a window from a menu to the shed and the window would get stuck to the respective wall.

Later on, on this project i will replace the windows mesh with a 3d object.

I got some idea from the the example file: Intermediate_MouseInteraction.as

but in that file it uses a linesegment, how do i replace that with a cube mesh and maybe rotate it, depending on the wall’s plane?

Can any one please help me in this. A quick reply would be really, really, really appreciated.

Thanx,
Tayyab

 

   

Richard Olsson, Administrator
Posted: 20 July 2012 11:48 AM   Total Posts: 1192   [ # 1 ]

What you see in Intermediate_MouseInteraction is more or less exactly what you want to do. Set the pickingCollider of your shed mesh to one of the values on PickingColliderType that is not BOUNDS_ONLY. Then when you get MOUSE_MOVE events on the walls of your shed object, the event objects will contain the scene position of the point where the cursor hit the wall. That’s where you want to place your object.

To rotate it correctly, use the sceneNormal property which contains the normal of the triangle that was hit in scene space. Have the object lookAt() it’s own position plus that normal value, e.g.:

target = new Vector3D();
target.myObject.event.sceneNormal.x;
target.myObject.event.sceneNormal.y;
target.myObject.event.sceneNormal.z;
myObject.lookAt(target); 

That should work, assuming that the object resides in scene space (i.e. has been added directly to the scene, or to a container with no transformation.)

   

Tayyab, Member
Posted: 30 July 2012 12:19 AM   Total Posts: 72   [ # 2 ]

I am sorry to get back so late, I was a bit sick…

I used ur code and it worked perfectly! smile

var target:Vector3D = new Vector3D();
target.window.event.sceneNormal.x;
target.window.event.sceneNormal.y;
target.window.event.sceneNormal.z;
window.lookAt(target);
  
window.position event.scenePosition

I just added the window.position line and started to drag on the walls.

Now my next question is, how would i restrict the object within the the wall boundaries. or to check even if it fits on the wall?

and also if i have put one window or object in and i want to put another one, how would i check that it does not collide with the other?

   

Mr Margaret Scratcher, Sr. Member
Posted: 30 July 2012 12:26 AM   Total Posts: 344   [ # 3 ]

A bit of maths to figure out your max and min x,y, and z values (Figure out where the edge of your plane is, then subtract or add half of the width or height of the thing your dragging, porvided the origin of it is in the centre), and then in your (dragging = true) bit which I assume you have in your (onEnterFrame) function simply add

if (objectBeingDragged.x <=maxX)
{objectBeingDragged.x = maxX}

(I might have got the < and = round the wrong way - I always have to double check that…)

   

Tayyab, Member
Posted: 30 July 2012 01:05 AM   Total Posts: 72   [ # 4 ]

Thanx Margaret,

How would i calculate the bounds, if the plane is not a pure rectangle or a square, what if its a triangular shape or a circular shape.

Here is what i am doing:

http://ranbuild.greycanberradev.com/assets/flash/ShedBuilder-FlashApp/V2/

its a 4.6 MB file and i don’t have a preloader, so you might have to wait for a bit to let it load.

and also how would i calculated the bounds for each object i place on the shed??

Thanx

   

Tayyab, Member
Posted: 30 July 2012 01:10 AM   Total Posts: 72   [ # 5 ]

Here is my code for the mouse move on the mesh:

/**
 * mesh listener for mouse move interaction
 */
private function  onMeshMouseMove(event:MouseEvent3D):void
{
 
// Show tracers.
 
pickingPositionTracer.visible pickingNormalTracer.visible true;

 
// Update position tracer.
 
pickingPositionTracer.position event.scenePosition;

 var 
target:Vector3D = new Vector3D();
 
target.window.event.sceneNormal.x;
 
target.window.event.sceneNormal.y;
 
target.window.event.sceneNormal.z;
 
window.lookAt(target);
   
 
window.position event.scenePosition;

 

   

Mr Margaret Scratcher, Sr. Member
Posted: 30 July 2012 01:39 AM   Total Posts: 344   [ # 6 ]

Hmmm interesting, and actuall something I’m going to have to think about with my current project..

How I see it, roughly, is that if you break down the front of the barn/shed into distinct areas, you could use trigonometry to calculate how high the roof is at a point x across the front, and then use this to limit the y position of your plane using the method I posted above. Whether you achieve this by physically splitting up the front face, or setting a number of conditions like (draggingplane.x <= 100 && >=20) or whatever (again, no doubt I’ve got those symbols the wrong way round…) is another thing entirely…

Some sort of class for this would be vey handy - taking the bounds of an object and making sure it fits within the confines of a specified shape..

   

Mr Margaret Scratcher, Sr. Member
Posted: 30 July 2012 01:41 AM   Total Posts: 344   [ # 7 ]

PS I am by no means an expert in away3d, as my numerous reuqests for help will atest, so no doubt Richard will be along to show us both a much more elegant way of acheiveing this.

   

Tayyab, Member
Posted: 30 July 2012 06:56 AM   Total Posts: 72   [ # 8 ]

thanx for the reply Margaret.

Looking forward for richard helping us out.

   

Richard Olsson, Administrator
Posted: 30 July 2012 06:59 AM   Total Posts: 1192   [ # 9 ]

I would say that the best way would be to check all the bounding vertices of the window against every triangle in the wall. If all of them are found to be inside a triangle that belongs to that wall, that means that none of the window’s corners “stick out” from off the side of the wall, and hence that it’s in a legal position.

Depending on how much knowledge you have about your meshes (e.g. do you know which vertex is which?) you could either just use the correct vertices from the window corners and each of the walls. To simplify this, split up the house into separate meshes for each wall, and loop over their triangle buffer.

If you don’t know which vertices are on each of the walls, loop over the entire geometry, check the normals (to figure out if they are pointing the same way that the surface on which the mouse is currently located) and perform the test there.

Use the Face class, which has a method called containsPoint() that allows you to test whether a vector (3D point) is within the triangle.

So, to recap:
1) Figure out the world position of your window’s four corners, e.g. using the Mesh.bounds property, or by inspecting it’s vertices directly.
2) Loop over all the triangles in the relevant wall through the wall geometry’s index data vector.
3) For each triangle, check all four window corners using Face.containsPoint()
4) If containsPoint() returns false for any of the corners, you know that the window is in an illegal position.

Note that this will only be 100% reliable when the walls are convex polygons. With concave polygons, the two points on an edge could both be inside the polygon, without the entire edge being so. Looking at your example though, you should be fine.

   

Tayyab, Member
Posted: 30 July 2012 11:31 PM   Total Posts: 72   [ # 10 ]

Thanx Richard, everything u said does make sense, but being a newbie I need some code examples to get me started, like how to use the Face class, how to get the vertices.

How to loop through all the triangles.

How to check for all four window corners using Face.containsPoint()

Thank you once again for guiding me in the right direction.

Thanx

   

Richard Olsson, Administrator
Posted: 31 July 2012 08:31 AM   Total Posts: 1192   [ # 11 ]

To use the Face class, just instantiate it, and then set it’s three vertex positions using it’s setVertexAt().

All the vertices of your mesh can be retrieved from it’s geometry’s sub-geometries, like so:

myMesh.geometry.subGeometries[0].vertexData

This assumes that the geometry has one and only one sub-geometry, which is probably the case with your very simple models.

Likewise, you can loop through the triangles by looping over the indexData vector instead of the vertexData vector. Every three numbers a new triangle face is described, using indices that point into the vertex vector. So using it along with the Face class, you should be able to do something like this (not optimized):

sub myMesh.geometry.subGeometries[0];
face = new Face();

for (
i=0i<sub.indexData.length+= 3{
  vidx 
sub.indexData[i+0] 3;
  
face.setVertexAt(0sub.vertexData[vidx+0]sub.vertexData[vidx+1]sub.vertexData[vidx+2]);

  
vidx sub.indexData[i+1] 3;
  
face.setVertexAt(1sub.vertexData[vidx+0]sub.vertexData[vidx+1]sub.vertexData[vidx+2]);

  
vidx sub.indexData[i+2] 3;
  
face.setVertexAt(2sub.vertexData[vidx+0]sub.vertexData[vidx+1]sub.vertexData[vidx+2]);

  
// Face now represents a triangle in the mesh. Do whatever with it.

Outside of this loop, make sure you prepare Vector3D instances representing all four corners of your window. Maybe you know that your window is 100x100 units and centered, and in that case you can just hard-code these points to (-50,50,0), (50,50,0), (50,-50,0) and (-50,-50,0) respectively. If you don’t know the size, you can use the min/max properties of Mesh.bounds to calculate it. Call these points topLeft, topRight, bottomLeft and bottomRight, for example.

Then, within the loop above, just use face.containsPoint(topLeft), face.containsPoint(topRight) et c and make sure that it returns true for all three points.

Make sure that the Z value in your window corner vectors (that I hardcoded to zero in my examples above) matches the Z value of your walls.

Also, make sure that if you want to test on a wall that is not in the X/Y plane (e.g. one of the side walls) you have to either adapt your algorithm to that, or transform the face into that plane first. The former will be easier in many cases, but will not work with slanted walls, that are not in any axis-aligned plane.

   

Tayyab, Member
Posted: 01 August 2012 05:45 AM   Total Posts: 72   [ # 12 ]

All this is in onMeshMouseMove function.
this is what i have added on top of the for loop:

var isContained:Array = new Array(falsefalsefalsefalse);
   
topLeft.window.window.minX -1;
   
topLeft.window.window.maxY-1;
   
topLeft.thisMesh.z;
   
topRight.window.window.maxX-1;
   
topRight.window.window.maxY-1;
   
topRight.thisMesh.z;
   
bottomLeft.window.window.minX-1;
   
bottomLeft.window.window.minY-1;
   
bottomLeft.thisMesh.z;
   
bottomRight.window.window.maxX-1;
   
bottomRight.window.window.minY-1;
   
bottomRight.thisMesh.z;
   var 
moveWindow:Boolean false
if (face.containsPoint(topLeft))
     
isContained[0] true;
    if (
face.containsPoint(topRight))
     
isContained[1] true;
    if (
face.containsPoint(bottomLeft))
     
isContained[2] true;
    if (
face.containsPoint(bottomRight))
     
isContained[3] true;
    
FlashConnect.trace(isContained);
    if (
isContained[0] && isContained[1] && isContained[2] && isContained[3])
    
{
     moveWindow 
true;
     
FlashConnect.trace("ALL TRUE!==");
     break; 
    
}
   }
   
if (moveWindow)
    
window.position event.scenePosition

this is what i have added in between the for loop, it worked with a simple xy plane mesh. but i could not seem to find the Z axis of my shed’s mesh. how would i know the z axis.

also on the simple XY plane mesh, window did remain in the plane mesh, but when it touch the corner it stayed there and did not move after that

   

Richard Olsson, Administrator
Posted: 01 August 2012 07:28 AM   Total Posts: 1192   [ # 13 ]

If it already worked, you probably do not need to know the Z position. Also, in that case, it might just work out of the box even for slanted walls. I’m not sure entirely how the Face.containsPoint() works mathematically, so you will have to employ some trial and error there to figure out whether it works on non-XY walls.

The reason why it stays in the corner is probably because once it’s made it there it will constantly return that the position is illegal, and therefor your code prevents it from being moved back in towards the wall. Here’s what I would do, every frame or on mouse move:

1) Store the current position of the window as oldPosition
2) Move the window according to mouse
3) Check if legal position
4) If legal, continue. If not, restore window to oldPosition

   

Tayyab, Member
Posted: 01 August 2012 07:30 AM   Total Posts: 72   [ # 14 ]

Hey Richard, thanx for the reply

it only worked with a simple plane mesh:

mesh = new Mesh( new PlaneGeometry(30030011false) );
mesh.position = new Vector3D(000); 

but for my shed mesh, the window stays in the center and inside the shed..

   

Richard Olsson, Administrator
Posted: 01 August 2012 07:43 AM   Total Posts: 1192   [ # 15 ]

Have you debugged it at all? Please try to figure out what it is that prevents it from working on your shed’s XY walls. It might be the z position, in which case the z position that you test should be that of the vertices which you are testing against (e.g. sub.vertexData[vidx+2]).

   
   

X

Away3D Forum

Member Login

Username

Password

Remember_me



X