void Decals::PaintDecal() { Vector3 hitPos; Drawable* hitDrawable; if (Raycast(250.0f, hitPos, hitDrawable)) { // Check if target scene node already has a DecalSet component. If not, create now Node* targetNode = hitDrawable->GetNode(); DecalSet* decal = targetNode->GetComponent<DecalSet>(); if (!decal) { ResourceCache* cache = GetSubsystem<ResourceCache>(); decal = targetNode->CreateComponent<DecalSet>(); decal->SetMaterial(cache->GetResource<Material>("Materials/UrhoDecal.xml")); } // Add a square decal to the decal set using the geometry of the drawable that was hit, orient it to face the camera, // use full texture UV's (0,0) to (1,1). Note that if we create several decals to a large object (such as the ground // plane) over a large area using just one DecalSet component, the decals will all be culled as one unit. If that is // undesirable, it may be necessary to create more than one DecalSet based on the distance decal->AddDecal(hitDrawable, hitPos, cameraNode_->GetRotation(), 0.5f, 1.0f, 1.0f, Vector2::ZERO, Vector2::ONE); } }
void Decals::PaintDecal() { UI* ui = GetSubsystem<UI>(); Graphics* graphics = GetSubsystem<Graphics>(); IntVector2 pos = ui->GetCursorPosition(); // Make sure no UI element in front of the cursor if (ui->GetElementAt(pos, true)) return; Camera* camera = cameraNode_->GetComponent<Camera>(); Ray cameraRay = camera->GetScreenRay((float)pos.x_ / graphics->GetWidth(), (float)pos.y_ / graphics->GetHeight()); // Raycast up to 250 world units distance, pick only geometry objects, not eg. zones or lights, only get the first // (closest) hit PODVector<RayQueryResult> results; RayOctreeQuery query(results, cameraRay, RAY_TRIANGLE, 250.0f, DRAWABLE_GEOMETRY); scene_->GetComponent<Octree>()->RaycastSingle(query); if (results.Size()) { RayQueryResult& result = results[0]; // Calculate hit position in world space Vector3 rayHitPos = cameraRay.origin_ + cameraRay.direction_ * result.distance_; // Check if target scene node already has a DecalSet component. If not, create now Node* targetNode = result.drawable_->GetNode(); DecalSet* decal = targetNode->GetComponent<DecalSet>(); if (!decal) { ResourceCache* cache = GetSubsystem<ResourceCache>(); decal = targetNode->CreateComponent<DecalSet>(); decal->SetMaterial(cache->GetResource<Material>("Materials/UrhoDecal.xml")); } // Add a square decal to the decal set using the geometry of the drawable that was hit, orient it to face the camera, // use full texture UV's (0,0) to (1,1). Note that if we create several decals to a large object (such as the ground // plane) over a large area using just one DecalSet component, the decals will all be culled as one unit. If that is // undesirable, it may be necessary to create more than one DecalSet based on the distance decal->AddDecal(result.drawable_, rayHitPos, cameraNode_->GetWorldRotation(), 0.5f, 1.0f, 1.0f, Vector2::ZERO, Vector2::ONE); } }