Browse Source

Allow creating a decal only on a specified subgeometry.
Cleaned up example script code.

Lasse Öörni 13 years ago
parent
commit
47eb79aa24

+ 35 - 25
Bin/Data/Scripts/TestScene.as

@@ -393,22 +393,45 @@ void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
     if (button == MOUSEB_RIGHT)
     if (button == MOUSEB_RIGHT)
         ui.cursor.visible = false;
         ui.cursor.visible = false;
 
 
-    // Test creating a new physics object
-    if (button == MOUSEB_LEFT && !input.qualifierDown[QUAL_SHIFT] && ui.GetElementAt(ui.cursorPosition, true) is null &&
-        ui.focusElement is null)
+    // Test either creating a new physics object or painting a decal (SHIFT down)
+    if (button == MOUSEB_LEFT && ui.GetElementAt(ui.cursorPosition, true) is null && ui.focusElement is null)
     {
     {
-        VariantMap eventData;
-        eventData["Pos"] = cameraNode.position;
-        eventData["Rot"] = cameraNode.rotation;
-
-        // If we are the client, send the spawn command as a remote event, else send locally
-        if (runClient)
+        if (!input.qualifierDown[QUAL_SHIFT])
         {
         {
-            if (network.serverConnection !is null)
-                network.serverConnection.SendRemoteEvent("SpawnBox", true, eventData);
+            VariantMap eventData;
+            eventData["Pos"] = cameraNode.position;
+            eventData["Rot"] = cameraNode.rotation;
+    
+            // If we are the client, send the spawn command as a remote event, else send locally
+            if (runClient)
+            {
+                if (network.serverConnection !is null)
+                    network.serverConnection.SendRemoteEvent("SpawnBox", true, eventData);
+            }
+            else
+                SendEvent("SpawnBox", eventData);
         }
         }
         else
         else
-            SendEvent("SpawnBox", eventData);
+        {
+            IntVector2 pos = ui.cursorPosition;
+            if (ui.GetElementAt(pos, true) is null && testScene.octree !is null)
+            {
+                Ray cameraRay = camera.GetScreenRay(float(pos.x) / graphics.width, float(pos.y) / graphics.height);
+                RayQueryResult result = testScene.octree.RaycastSingle(cameraRay, RAY_TRIANGLE, 250.0, DRAWABLE_GEOMETRY);
+                if (result.drawable !is null)
+                {
+                    Vector3 rayHitPos = cameraRay.origin + cameraRay.direction * result.distance;
+                    DecalSet@ decal = result.drawable.node.GetComponent("DecalSet");
+                    if (decal is null)
+                    {
+                        decal = result.drawable.node.CreateComponent("DecalSet");
+                        decal.material = cache.GetResource("Material", "Materials/Test.xml");
+                    }
+                    decal.AddDecal(result.drawable, rayHitPos - cameraNode.worldRotation * Vector3(0, 0, 0.1),
+                        cameraNode.worldRotation, 0.1, 1.0, 0.2, Vector2(0, 0), Vector2(1, 1));
+                }
+            }
+        }
     }
     }
 }
 }
 
 
@@ -465,19 +488,6 @@ void HandlePostRenderUpdate()
             Vector3 rayHitPos = cameraRay.origin + cameraRay.direction * result.distance;
             Vector3 rayHitPos = cameraRay.origin + cameraRay.direction * result.distance;
             testScene.debugRenderer.AddBoundingBox(BoundingBox(rayHitPos + Vector3(-0.01, -0.01, -0.01), rayHitPos +
             testScene.debugRenderer.AddBoundingBox(BoundingBox(rayHitPos + Vector3(-0.01, -0.01, -0.01), rayHitPos +
                 Vector3(0.01, 0.01, 0.01)), Color(1.0, 1.0, 1.0), true);
                 Vector3(0.01, 0.01, 0.01)), Color(1.0, 1.0, 1.0), true);
-
-            if (input.mouseButtonPress[MOUSEB_LEFT] && input.qualifierDown[QUAL_SHIFT] && ui.GetElementAt(ui.cursorPosition, true)
-                is null && ui.focusElement is null)
-            {
-                DecalSet@ decal = result.drawable.node.GetComponent("DecalSet");
-                if (decal is null)
-                {
-                    decal = result.drawable.node.CreateComponent("DecalSet");
-                    decal.material = cache.GetResource("Material", "Materials/Test.xml");
-                }
-                decal.AddDecal(result.drawable, rayHitPos - cameraNode.worldRotation * Vector3(0, 0, 0.1),
-                    cameraNode.worldRotation, 0.1, 1.0, 0.2, Vector2(0, 0), Vector2(1, 1));
-            }
         }
         }
     }
     }
 }
 }

+ 44 - 37
Bin/Data/Scripts/TestSceneOld.as

@@ -499,32 +499,52 @@ void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
     if (button == MOUSEB_RIGHT)
     if (button == MOUSEB_RIGHT)
         ui.cursor.visible = false;
         ui.cursor.visible = false;
 
 
-    // Test creating a new physics object
-    if (button == MOUSEB_LEFT && !input.qualifierDown[QUAL_SHIFT] && ui.GetElementAt(ui.cursorPosition, true) is null &&
-        ui.focusElement is null)
+    // Test either creating a new physics object or painting a decal (SHIFT down)
+    if (button == MOUSEB_LEFT && ui.GetElementAt(ui.cursorPosition, true) is null && ui.focusElement is null)
     {
     {
-        Vector3 position = eventData["Pos"].GetVector3();
-        Quaternion rotation = eventData["Rot"].GetQuaternion();
-
-        Node@ newNode = testScene.CreateChild();
-        newNode.position = cameraNode.position;
-        newNode.rotation = cameraNode.rotation;
-        newNode.SetScale(0.2);
+        if (!input.qualifierDown[QUAL_SHIFT])
+        {
+            Node@ newNode = testScene.CreateChild();
+            newNode.position = cameraNode.position;
+            newNode.rotation = cameraNode.rotation;
+            newNode.SetScale(0.2);
+        
+            RigidBody@ body = newNode.CreateComponent("RigidBody");
+            body.mass = 1.0;
+            body.friction = 1.0;
+            body.linearVelocity = cameraNode.rotation * Vector3(0.0, 1.0, 10.0);
     
     
-        RigidBody@ body = newNode.CreateComponent("RigidBody");
-        body.mass = 1.0;
-        body.friction = 1.0;
-        body.linearVelocity = cameraNode.rotation * Vector3(0.0, 1.0, 10.0);
-
-        CollisionShape@ shape = newNode.CreateComponent("CollisionShape");
-        shape.SetBox(Vector3(1, 1, 1));
-
-        StaticModel@ object = newNode.CreateComponent("StaticModel");
-        object.model = cache.GetResource("Model", "Models/Box.mdl");
-        object.material = cache.GetResource("Material", "Materials/Test.xml");
-        object.castShadows = true;
-        object.shadowDistance = 150.0;
-        object.drawDistance = 200.0;
+            CollisionShape@ shape = newNode.CreateComponent("CollisionShape");
+            shape.SetBox(Vector3(1, 1, 1));
+    
+            StaticModel@ object = newNode.CreateComponent("StaticModel");
+            object.model = cache.GetResource("Model", "Models/Box.mdl");
+            object.material = cache.GetResource("Material", "Materials/Test.xml");
+            object.castShadows = true;
+            object.shadowDistance = 150.0;
+            object.drawDistance = 200.0;
+        }
+        else
+        {
+            IntVector2 pos = ui.cursorPosition;
+            if (ui.GetElementAt(pos, true) is null && testScene.octree !is null)
+            {
+                Ray cameraRay = camera.GetScreenRay(float(pos.x) / graphics.width, float(pos.y) / graphics.height);
+                RayQueryResult result = testScene.octree.RaycastSingle(cameraRay, RAY_TRIANGLE, 250.0, DRAWABLE_GEOMETRY);
+                if (result.drawable !is null)
+                {
+                    Vector3 rayHitPos = cameraRay.origin + cameraRay.direction * result.distance;
+                    DecalSet@ decal = result.drawable.node.GetComponent("DecalSet");
+                    if (decal is null)
+                    {
+                        decal = result.drawable.node.CreateComponent("DecalSet");
+                        decal.material = cache.GetResource("Material", "Materials/Test.xml");
+                    }
+                    decal.AddDecal(result.drawable, rayHitPos - cameraNode.worldRotation * Vector3(0, 0, 0.1),
+                        cameraNode.worldRotation, 0.1, 1.0, 0.2, Vector2(0, 0), Vector2(1, 1));
+                }
+            }
+        }
     }
     }
 }
 }
 
 
@@ -555,19 +575,6 @@ void HandlePostRenderUpdate()
             Vector3 rayHitPos = cameraRay.origin + cameraRay.direction * result.distance;
             Vector3 rayHitPos = cameraRay.origin + cameraRay.direction * result.distance;
             testScene.debugRenderer.AddBoundingBox(BoundingBox(rayHitPos + Vector3(-0.01, -0.01, -0.01), rayHitPos +
             testScene.debugRenderer.AddBoundingBox(BoundingBox(rayHitPos + Vector3(-0.01, -0.01, -0.01), rayHitPos +
                 Vector3(0.01, 0.01, 0.01)), Color(1.0, 1.0, 1.0), true);
                 Vector3(0.01, 0.01, 0.01)), Color(1.0, 1.0, 1.0), true);
-
-            if (input.mouseButtonPress[MOUSEB_LEFT] && input.qualifierDown[QUAL_SHIFT] && ui.GetElementAt(ui.cursorPosition, true)
-                is null && ui.focusElement is null)
-            {
-                DecalSet@ decal = result.drawable.node.GetComponent("DecalSet");
-                if (decal is null)
-                {
-                    decal = result.drawable.node.CreateComponent("DecalSet");
-                    decal.material = cache.GetResource("Material", "Materials/Test.xml");
-                }
-                decal.AddDecal(result.drawable, rayHitPos - cameraNode.worldRotation * Vector3(0, 0, 0.1),
-                    cameraNode.worldRotation, 0.1, 1.0, 0.2, Vector2(0, 0), Vector2(1, 1));
-            }
         }
         }
     }
     }
 }
 }

+ 1 - 1
Engine/Engine/GraphicsAPI.cpp

@@ -758,7 +758,7 @@ static void RegisterParticleEmitter(asIScriptEngine* engine)
 static void RegisterDecalSet(asIScriptEngine* engine)
 static void RegisterDecalSet(asIScriptEngine* engine)
 {
 {
     RegisterDrawable<DecalSet>(engine, "DecalSet");
     RegisterDrawable<DecalSet>(engine, "DecalSet");
-    engine->RegisterObjectMethod("DecalSet", "bool AddDecal(Drawable@+, const Vector3&in, const Quaternion&in, float, float, float, const Vector2&in, const Vector2&in, float timeToLive = 0.0, float normalCutoff = 0.25, float depthBias = 0.0005)", asMETHOD(DecalSet, AddDecal), asCALL_THISCALL);
+    engine->RegisterObjectMethod("DecalSet", "bool AddDecal(Drawable@+, const Vector3&in, const Quaternion&in, float, float, float, const Vector2&in, const Vector2&in, float timeToLive = 0.0, float normalCutoff = 0.25, float depthBias = 0.0005, uint subGeometry = 0xffffffff)", asMETHOD(DecalSet, AddDecal), asCALL_THISCALL);
     engine->RegisterObjectMethod("DecalSet", "void RemoveDecals(uint)", asMETHOD(DecalSet, RemoveDecals), asCALL_THISCALL);
     engine->RegisterObjectMethod("DecalSet", "void RemoveDecals(uint)", asMETHOD(DecalSet, RemoveDecals), asCALL_THISCALL);
     engine->RegisterObjectMethod("DecalSet", "void RemoveAllDecals()", asMETHOD(DecalSet, RemoveAllDecals), asCALL_THISCALL);
     engine->RegisterObjectMethod("DecalSet", "void RemoveAllDecals()", asMETHOD(DecalSet, RemoveAllDecals), asCALL_THISCALL);
     engine->RegisterObjectMethod("DecalSet", "void set_material(Material@+)", asMETHOD(DecalSet, SetMaterial), asCALL_THISCALL);
     engine->RegisterObjectMethod("DecalSet", "void set_material(Material@+)", asMETHOD(DecalSet, SetMaterial), asCALL_THISCALL);

+ 10 - 3
Engine/Graphics/DecalSet.cpp

@@ -263,7 +263,7 @@ void DecalSet::SetMaxIndices(unsigned num)
 
 
 bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Quaternion& worldRotation, float size,
 bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Quaternion& worldRotation, float size,
     float aspectRatio, float depth, const Vector2& topLeftUV, const Vector2& bottomRightUV, float timeToLive, float normalCutoff,
     float aspectRatio, float depth, const Vector2& topLeftUV, const Vector2& bottomRightUV, float timeToLive, float normalCutoff,
-    float depthBias)
+    float depthBias, unsigned subGeometry)
 {
 {
     PROFILE(AddDecal);
     PROFILE(AddDecal);
     
     
@@ -349,8 +349,15 @@ bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Qu
     PODVector<DecalVertex> tempFace;
     PODVector<DecalVertex> tempFace;
     
     
     unsigned numBatches = target->GetBatches().Size();
     unsigned numBatches = target->GetBatches().Size();
-    for (unsigned i = 0; i < numBatches; ++i)
-        GetFaces(faces, target, i, decalFrustum, decalNormal, normalCutoff);
+    
+    // Use either a specified subgeometry in the target, or all
+    if (subGeometry < numBatches)
+        GetFaces(faces, target, subGeometry, decalFrustum, decalNormal, normalCutoff);
+    else
+    {
+        for (unsigned i = 0; i < numBatches; ++i)
+            GetFaces(faces, target, i, decalFrustum, decalNormal, normalCutoff);
+    }
     
     
     // Clip the acquired faces against all frustum planes
     // Clip the acquired faces against all frustum planes
     for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
     for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)

+ 1 - 1
Engine/Graphics/DecalSet.h

@@ -126,7 +126,7 @@ class DecalSet : public Drawable
     /// %Set maximum number of decal vertex indices.
     /// %Set maximum number of decal vertex indices.
     void SetMaxIndices(unsigned num);
     void SetMaxIndices(unsigned num);
     /// Add a decal at world coordinates, using an existing drawable's geometry for reference. Return true if successful.
     /// Add a decal at world coordinates, using an existing drawable's geometry for reference. Return true if successful.
-    bool AddDecal(Drawable* target, const Vector3& worldPosition, const Quaternion& worldRotation, float size, float aspectRatio, float depth, const Vector2& topLeftUV, const Vector2& bottomRightUV, float timeToLive = 0.0f, float normalCutoff = 0.25f, float depthBias = 0.0005f);
+    bool AddDecal(Drawable* target, const Vector3& worldPosition, const Quaternion& worldRotation, float size, float aspectRatio, float depth, const Vector2& topLeftUV, const Vector2& bottomRightUV, float timeToLive = 0.0f, float normalCutoff = 0.25f, float depthBias = 0.0005f, unsigned subGeometry = M_MAX_UNSIGNED);
     /// Remove n oldest decals.
     /// Remove n oldest decals.
     void RemoveDecals(unsigned num);
     void RemoveDecals(unsigned num);
     /// Remove all decals.
     /// Remove all decals.