Horde3D http://www.horde3d.org/forums/ |
|
Extending Horde3D::castRay and Horde3DUtil::pick http://www.horde3d.org/forums/viewtopic.php?f=8&t=337 |
Page 1 of 2 |
Author: | Codepoet [ 17.05.2008, 14:19 ] |
Post subject: | Extending Horde3D::castRay and Horde3DUtil::pick |
Horde3D::castRay and Horde3DUtil::pick use internally checkIntersection to determine the point of intersection with a node - if any. I need this intersection point in my app, so it would be great if we could extend the API to provide this information. At the moment I'm directly accessing checkIntersection by using an extended wrapper. Another problem is, if several objects intersect with the ray: Then only the nearest object is returned without a way to determine the other objects. Edit: I read the code a bit more carefully: It's not possible to use minDist to select the nearest object which is further away then a certain value. So the intersected nodes must be stored internally somehow. |
Author: | DarkAngel [ 18.05.2008, 10:22 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
Good idea. Codepoet wrote: A better approach would be to store a list of all intersected nodes [if the user has requested more than one result] and add functions to retrieve and clear the list. ^^A lot of the time the user will still only require the closest object, so there should be extra parameters that you can pass to configure how the picking will happen. Gamebryo 2.x acheives this by having the user declare and fill in a configuration structure (e.g. closest object or all objects? return intersection position? return normal, texcoords, etc at point of intersection?), and then the results of the picking operation are stored in this same structure. e.g. something like: Code: struct pickResult { vec3 pos, normal; vec2 tex; float distance; }; struct pickInfo { pickInfo( int f ) : flags(f) {} std::vector<pickResult> results; int flags; const static int F_GET_POS = 0x01; const static int F_GET_NORM = 0x02; const static int F_GET_DISTANCE = 0x04; const static int F_GET_ALL_OBJECTS = 0x08; }; pickInfo bullet( F_GET_DISTANCE ); doPick( node, bullet, rayStart, rayDirection ); if( !bullet.results.empty() ) damage = std::max(0, 100 - bullet.results.front().distance); [edit] I forgot that we can't use std::vectors in Horde's interface ![]() |
Author: | Codepoet [ 18.05.2008, 12:51 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
Edit: Updated design to avoid memory allocations inside user app. The current API does not use structures. So I'll not introduce them ![]() My suggestion will achieve the same thing: Code: int castRay(NodeHandle node, float ox, float oy, float oz, float dx, float dy, float dz, int flags, int numNearest); flags: UNSORTED - do not sort result list (may be faster, default is sorted) (more? depending on getCastRayResults implementation here can be determined which information should be calculated) numNearest: if == 0 return all intersecting nodes; if != 0 and UNSORTED was specified, it is undefined which n nodes are included in the result return value: number of intersections found Code: bool getCastRayResults(int index, NodeHandle *node, float *distance, float *intersection); index: result index in range [0, result of castRay) node: NodeHandle or NULL distance: float or NULL intersection: float[3] or NULL return value: true on success, otherwise false (really needed? as long as the index is valid, this call should succeed always) Code: void clearCastRayResults(); releases internal memory. Automatically called by castRay. Sample use case for all intersections: Code: int num = castRay(startNode, ox, oy, oz, dx, dy, dz, 0, 0) for(int i; i < num; ++i) { NodeHandle node; float distance; float intersection[3]; getCastRayResults(i, &node, &distance, intersection); // do something with the result // .. } clearCastRayResult(); Sample use case for only nearest intersection: Code: if(castRay(startNode, ox, oy, oz, dx, dy, dz, 0, 1)) { NodeHandle node; float distance; float intersection[3]; getCastRayResult(0, &node, &distance, intersection); // do something with result // ... } clearCastRayResult(); In order to avoid duplicating code with picking replace Horde3DUtils::pick with a function that returns the ray origin and direction. Then the user can do the ray cast as usual. |
Author: | roarflolo [ 18.05.2008, 19:36 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
How about: Code: enum { RAYCAST_FLAG_SORT = (1<<0), RAYCAST_FLAG_NEAREST_RESULT_ONLY = (1<<1), }; class RaycastResult { public: RaycastResult(NodeHandle* node, float k) : m_node(node), m_k(k) {} NodeHandle* Node() const { return m_node; } float Distance() const { return m_k } private: NodeHandle* m_node; float m_k; // normalized distance along the ray [0-1] (could be real distance as well) }; void myFunc() { std::vector<RaycastResult> results; // cast the ray and fill in the vector with results rayCast(from_x, from_y, from_z, to_x, to_y, to_z, RAYCAST_FLAG_SORT, results); for( size_t i_intersection=0; i_intersection<results.size(); ++i_intersection ) { const RaycastResult& result = results[i_intersection]; // do whatever } } I just saw someone saying no std::vector. Why? |
Author: | Codepoet [ 18.05.2008, 20:25 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
roarflolo wrote: I just saw someone saying no std::vector. Why? The public API is a C-style procedural interface. That means no structs, classes or anything like that. This makes it really easy to write language bindings for Horde3D. |
Author: | Codepoet [ 20.05.2008, 19:48 ] | ||
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick | ||
I've attached the code to replace pickNode with a function which only returns the ray parameters for use with castRay.
|
Author: | marciano [ 20.05.2008, 20:01 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
Codepoet, I like your idea much! I appreciate especially that you try to keep the interface consistent. Just one suggestion: currently one would require memory allocations for the result list which can kill performance and introduce memory fragmentation. What about having an internal list of results that you can query? I'm thinking of something similar to the way findNodes/getNodeFindResult is working. Another note: the ray casting is not meant for complex applications like physics. It is not very optimized (for heavy meshes), so if you require a plenty of queries you better use a physics engine. |
Author: | Codepoet [ 20.05.2008, 20:08 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
marciano wrote: Just one suggestion: currently one would require memory allocations for the result list which can kill performance and introduce memory fragmentation. What about having an internal list of results that you can query? I'm thinking of something similar to the way findNodes/getNodeFindResult is working. good idea. I've updated my post above. marciano wrote: Another note: the ray casting is not meant for complex applications like physics. It is not very optimized (for heavy meshes), so if you require a plenty of queries you better use a physics engine. It's ideal for debugging at the moment since I don't have any physics, yet. |
Author: | Codepoet [ 30.05.2008, 21:59 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
I'd like to raise again the issue about changing the castRay code - I just tested the terrain intersection algorithm and had to change the engine code to spit out debug messages inside castRay since I can't access the intersection point otherwise... @Volker, marciano: If you want to include my proposal I'll implement it and post the patches here. |
Author: | Volker [ 30.05.2008, 22:29 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
Sure |
Author: | Codepoet [ 31.05.2008, 00:40 ] | ||
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick | ||
Here's the patch. When you've committed it to svn I'll update my D and Python bindings. I've made two small changes to my proposal above: The current implementation does not use flags, so I omitted this parameter and getCastRayResults is now getCastRayResult. Apply with "patch -p1" as usual.
|
Author: | marciano [ 01.06.2008, 15:34 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
Thanks for the patch. Is the function for clearing the results really needed? Actually this could happen implicitely during the next query. I would suggest to integrate the new functionality after Horde 1.0 final was released since it would break the current API. |
Author: | Codepoet [ 01.06.2008, 17:46 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
At the moment it's cleared automatically when one calls castRay. The idea was to allow the user to free "unused" resources ASAP. But you are right, it seems like overkill here. I'll remove it. I don't know your release policy, but if you want that 1.x stays backwards compatible to 1.0 it would mean that this usefull feature would have to wait until 2.0 / stay in the development branch. Obviously I'd like to have it in the 1.0 release instead of having to write an extension and duplicating the code in the engine core. Especially for beginners it would make it easier if there's only one obvious way to do picking instead of having the option of either using the engine or an extension. I understand the problem of breaking the API this late in the release process, so I'll respect your decision either way ![]() |
Author: | Codepoet [ 01.06.2008, 17:55 ] | ||
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick | ||
New patch without clearCastRayResults.
|
Author: | swiftcoder [ 02.06.2008, 12:22 ] |
Post subject: | Re: Extending Horde3D::castRay and Horde3DUtil::pick |
Codepoet wrote: I don't know your release policy, but if you want that 1.x stays backwards compatible to 1.0 it would mean that this usefull feature would have to wait until 2.0 / stay in the development branch. Obviously I'd like to have it in the 1.0 release instead of having to write an extension and duplicating the code in the engine core. You do have a point though - at the 1.0 beta stage we have a license to break a little (before the 1.0.x freeze). This is a good change, which simplifies and clarifies the API, and we do want 1.0 to be a very useful freeze...
|
Page 1 of 2 | All times are UTC + 1 hour |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |