bool GameMain::Raycast(float maxDistance, Vector3& hitPos, Vector3& hitNormal, Drawable*& hitDrawable) { hitDrawable = 0; Graphics* graphics = GetSubsystem<Graphics>(); //Ray cameraRay = camera->GetScreenRay((float)graphics->GetWidth() * 0.5f, (float) graphics->GetHeight() * 0.5f); Ray ray = world.camera.camera_->GetScreenRay((float) 0.5f, (float) 0.5f); //Ray gunRay = Ray(gunNode_->GetWorldPosition(), gunNode_->GetWorldDirection()); // Pick only geometry objects, not eg. zones or lights, only get the first (closest) hit PODVector<RayQueryResult> results; //RayOctreeQuery query(results, cameraRay, RAY_TRIANGLE, maxDistance, DRAWABLE_GEOMETRY); RayOctreeQuery query(results, ray, RAY_TRIANGLE, maxDistance, DRAWABLE_GEOMETRY, 191); Octree* octree = scene_->GetComponent<Octree>(); //octree->RaycastSingle(query); octree->Raycast(query); if (results.Size()) { for (unsigned int i = 0; i < results.Size(); i++) { RayQueryResult& result = results[i]; Variant fx = result.node_->GetVar("fx"); if (fx.GetInt() == 1) continue; hitPos = result.position_; hitNormal = result.normal_; hitDrawable = result.drawable_; return true; } } return false; }
static int Octree_Raycast(duk_context* ctx) { bool single = duk_get_current_magic(ctx) == DUK_MAGIC_RAYCAST_SINGLE; duk_idx_t nargs = duk_get_top(ctx); // require at least the ray if (nargs < 1) { duk_push_undefined(ctx); return 1; } Ray ray; if (!duk_get_ray(ctx, 0, ray)) { duk_push_undefined(ctx); return 1; } RayQueryLevel level = RAY_TRIANGLE; if (nargs > 1) { unsigned _level = (unsigned) duk_to_number(ctx, 1); if (_level > (unsigned) RAY_TRIANGLE_UV) { duk_push_undefined(ctx); return 1; } level = (RayQueryLevel) _level; } float maxDistance = M_INFINITY; if (nargs > 2) { maxDistance = (float) duk_to_number(ctx, 2); } unsigned char drawableFlags = DRAWABLE_ANY; if (nargs > 3) { drawableFlags = (unsigned char) duk_to_number(ctx, 3); } unsigned viewMask = DEFAULT_VIEWMASK; if (nargs > 4) { viewMask = (unsigned) duk_to_number(ctx, 4); } duk_push_this(ctx); Octree* octree = js_to_class_instance<Octree>(ctx, -1, 0); PODVector<RayQueryResult> result; RayOctreeQuery query(result, ray, level, maxDistance, drawableFlags, viewMask); single ? octree->RaycastSingle(query) : octree->Raycast(query); // handle case of nothing hit if (!result.Size()) { if (single) duk_push_null(ctx); else duk_push_array(ctx); return 1; } else { if (single) { duk_push_rayqueryresult(ctx, result[0]); } else { duk_push_array(ctx); for (unsigned i = 0; i < result.Size(); i++) { duk_push_rayqueryresult(ctx, result[i]); duk_put_prop_index(ctx, -2, i); } } } return 1; }