浏览代码

gui offscreen material test

added interaction static guioffscreencanvas to capture mouse events
added test shape
marauder2k7 2 月之前
父节点
当前提交
6f9c4158d8

+ 69 - 6
Engine/source/T3D/fps/guiCrossHairHud.cpp

@@ -30,7 +30,11 @@
 #include "T3D/shapeBase.h"
 #include "gfx/gfxDrawUtil.h"
 #include "console/engineAPI.h"
-
+#include "gui/core/guiOffscreenCanvas.h"
+#include "T3D/tsStatic.h"
+#include "materials/baseMatInstance.h"
+#include "materials/matInstance.h"
+#include "materials/materialDefinition.h"
 
 //-----------------------------------------------------------------------------
 /// Vary basic cross hair hud.
@@ -46,12 +50,14 @@ class GuiCrossHairHud : public GuiBitmapCtrl
    LinearColorF   mDamageFrameColor;
    Point2I  mDamageRectSize;
    Point2I  mDamageOffset;
+   PlatformTimer* mFrameTime;
 
 protected:
    void drawDamage(Point2I offset, F32 damage, F32 opacity);
 
 public:
    GuiCrossHairHud();
+   ~GuiCrossHairHud();
 
    void onRender( Point2I, const RectI &) override;
    static void initPersistFields();
@@ -95,6 +101,12 @@ GuiCrossHairHud::GuiCrossHairHud()
    mDamageFrameColor.set( 1.0f, 0.6f, 0.0f, 1.0f );
    mDamageRectSize.set(50, 4);
    mDamageOffset.set(0,32);
+   mFrameTime = PlatformTimer::create();
+}
+
+GuiCrossHairHud::~GuiCrossHairHud()
+{
+   SAFE_DELETE(mFrameTime);
 }
 
 void GuiCrossHairHud::initPersistFields()
@@ -114,13 +126,14 @@ void GuiCrossHairHud::initPersistFields()
 
 void GuiCrossHairHud::onRender(Point2I offset, const RectI &updateRect)
 {
+   GuiOffscreenCanvas::sActiveOffscreenCanvas = NULL;
    // Must have a connection and player control object
    GameConnection* conn = GameConnection::getConnectionToServer();
    if (!conn)
       return;
-   GameBase* control = dynamic_cast<GameBase*>(conn->getCameraObject());
+   /*GameBase* control = dynamic_cast<GameBase*>(conn->getCameraObject());
    if (!control || !(control->getTypeMask() & ObjectMask) || !conn->isFirstPerson())
-      return;
+      return;*/
 
    // Parent render.
    Parent::onRender(offset,updateRect);
@@ -139,11 +152,61 @@ void GuiCrossHairHud::onRender(Point2I offset, const RectI &updateRect)
 
    // Collision info. We're going to be running LOS tests and we
    // don't want to collide with the control object.
-   static U32 losMask = TerrainObjectType | ShapeBaseObjectType;
-   control->disableCollision();
+   static U32 losMask = TerrainObjectType | ShapeBaseObjectType | StaticShapeObjectType;
+   //control->disableCollision();
 
    RayInfo info;
    if (gClientContainer.castRay(camPos, endPos, losMask, &info)) {
+      // is this a tsstatic? then it could be a offscreen canvas, check the list.
+      if (TSStatic* ts = dynamic_cast<TSStatic*>(info.object))
+      {
+         if (mFrameTime->getElapsedMs() > 32)
+         {
+            mFrameTime->reset();
+
+            Point3F newStart, newEnd;
+            ts->getWorldTransform().mulP(camPos, &newStart);
+            ts->getWorldTransform().mulP(endPos, &newEnd);
+
+            newStart.convolveInverse(ts->getScale());
+            newEnd.convolveInverse(ts->getScale());
+
+            info.generateTexCoord = true;
+            if (ts->getShapeInstance()->castRayOpcode(0, newStart, newEnd, &info))
+            {
+               MatInstance* matInst = dynamic_cast<MatInstance*>(info.material);
+               if (matInst)
+               {
+                  Material* mat = matInst->getMaterial();
+                  if (mat && mat->getDiffuseMapAsset(0).notNull() && mat->getDiffuseMapAsset(0)->isNamedTarget())
+                  {
+                     String canvasName = String(mat->getDiffuseMapAsset(0)->getImageFile()).substr(1, (U32)strlen(mat->getDiffuseMapAsset(0)->getImageFile()) - 1);
+                     for (GuiOffscreenCanvas* canvas : GuiOffscreenCanvas::sList)
+                     {
+                        if (canvas->getTarget()->getName() == canvasName)
+                        {
+                           if (!canvas->canInteract() || canvas->getMaxInteractDistance() < info.distance)
+                           {
+                              break;
+                           }
+
+                           Point2I canvasSize = canvas->getWindowSize();
+                           Point2I newCursorPos(mRound(mClampF((info.texCoord.x * canvasSize.x), 0.0f, (F32)canvasSize.x)),
+                              mRound(mClampF((info.texCoord.y * canvasSize.y), 0.0f, (F32)canvasSize.y)));
+
+                           canvas->setCursorPos(newCursorPos);
+                           canvas->markDirty();
+                           GuiOffscreenCanvas::sActiveOffscreenCanvas = canvas;
+                           break;
+                        }
+                     }
+                  }
+               }
+            }
+         }
+
+      }
+
       // Hit something... but we'll only display health for named
       // ShapeBase objects.  Could mask against the object type here
       // and do a static cast if it's a ShapeBaseObjectType, but this
@@ -157,7 +220,7 @@ void GuiCrossHairHud::onRender(Point2I offset, const RectI &updateRect)
    }
 
    // Restore control object collision
-   control->enableCollision();
+   //control->enableCollision();
 }
 
 

+ 6 - 0
Engine/source/gui/core/guiCanvas.cpp

@@ -690,6 +690,12 @@ bool GuiCanvas::processInputEvent(InputEventInfo &inputEvent)
    mConsumeLastInputEvent = true;
    mLastInputDeviceType = inputEvent.deviceType;
 
+   // If we have an active offscreen canvas, give it the input
+   if (GuiOffscreenCanvas::sActiveOffscreenCanvas &&
+      (GuiOffscreenCanvas::sActiveOffscreenCanvas != this) &&
+      GuiOffscreenCanvas::sActiveOffscreenCanvas->processInputEvent(inputEvent))
+      return mConsumeLastInputEvent;
+
    // First call the general input handler (on the extremely off-chance that it will be handled):
    if (mFirstResponder &&  mFirstResponder->onInputEvent(inputEvent))
    {

+ 3 - 1
Engine/source/gui/core/guiOffscreenCanvas.cpp

@@ -9,6 +9,7 @@
 
 IMPLEMENT_CONOBJECT(GuiOffscreenCanvas);
 
+GuiOffscreenCanvas* GuiOffscreenCanvas::sActiveOffscreenCanvas = NULL;
 Vector<GuiOffscreenCanvas*> GuiOffscreenCanvas::sList;
 
 GuiOffscreenCanvas::GuiOffscreenCanvas()
@@ -33,7 +34,8 @@ void GuiOffscreenCanvas::initPersistFields()
    addField( "targetName", TypeRealString, Offset( mTargetName, GuiOffscreenCanvas ), "");
    addField( "dynamicTarget", TypeBool, Offset( mDynamicTarget, GuiOffscreenCanvas ), "");
    addField( "useDepth", TypeBool, Offset( mUseDepth, GuiOffscreenCanvas ), "");
-
+   addField("canInteract", TypeBool, Offset(mCanInteract, GuiOffscreenCanvas), "");
+   addField("maxInteractDistance", TypeF32, Offset(mMaxInteractDistance, GuiOffscreenCanvas), "");
    Parent::initPersistFields();
 }
 

+ 5 - 0
Engine/source/gui/core/guiOffscreenCanvas.h

@@ -38,6 +38,8 @@ public:
    void _teardownTargets();
 
    NamedTexTargetRef getTarget() { return &mNamedTarget; }
+   bool canInteract() { return mCanInteract; }
+   F32 getMaxInteractDistance() { return mMaxInteractDistance; }
 
    void markDirty() { mTargetDirty = true; }
 
@@ -59,9 +61,12 @@ protected:
    
    bool mUseDepth;
    GFXTexHandle mTargetDepth;
+   bool mCanInteract;
+   F32 mMaxInteractDistance;
 
 public:
    static Vector<GuiOffscreenCanvas*> sList;
+   static GuiOffscreenCanvas* sActiveOffscreenCanvas;
 };
 
 #endif

+ 11 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/ScreenTarget.asset.taml

@@ -0,0 +1,11 @@
+<ImageAsset
+    AssetName="ScreenTarget"
+    imageFile="@assetFile=#screen_Canvas"
+    VersionId="1">
+    <ImageAsset.ImageMetadata>
+        <ImageInfo
+            ImageWidth="-1"
+            ImageHeight="-1"
+            ImageDepth="-1"/>
+    </ImageAsset.ImageMetadata>
+</ImageAsset>

+ 13 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_base_mat.asset.taml

@@ -0,0 +1,13 @@
+<MaterialAsset
+    AssetName="monitor_base_mat"
+    materialDefinitionName="monitor_base_mat">
+    <Material
+        Name="monitor_base_mat"
+        mapTo="monitor_base_mat"
+        originalAssetName="monitor_base_mat">
+        <Material.Stages>
+            <Stages_beginarray
+                DiffuseColor="0 0 0 1"/>
+        </Material.Stages>
+    </Material>
+</MaterialAsset>

+ 16 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_screen_mat.asset.taml

@@ -0,0 +1,16 @@
+<MaterialAsset
+    AssetName="monitor_screen_mat"
+    materialDefinitionName="monitor_screen_mat">
+    <Material
+        Name="monitor_screen_mat"
+        mapTo="monitor_screen_mat"
+        originalAssetName="monitor_base_mat">
+        <Material.Stages>
+            <Stages_beginarray
+                DiffuseMapAsset="@asset=Prototyping:ScreenTarget"
+                IgnoreLighting="true"/>
+            <Stages_beginarray
+                DiffuseColor="White"/>
+        </Material.Stages>
+    </Material>
+</MaterialAsset>

+ 6 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.asset.taml

@@ -0,0 +1,6 @@
+<ShapeAsset
+    AssetName="monitor_shape"
+    fileName="@assetFile=monitor_shape.fbx"
+    constuctorFileName="@assetFile=monitor_shape.tscript"
+    materialSlot0="@asset=Prototyping:monitor_base_mat"
+    materialSlot1="@asset=Prototyping:monitor_screen_mat"/>

二进制
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.fbx


+ 61 - 0
Templates/BaseGame/game/data/Prototyping/gui_offscreen_test/monitor_shape.tscript

@@ -0,0 +1,61 @@
+
+singleton TSShapeConstructor(monitor_shapefbx)
+{
+   baseShapeAsset = "Prototyping:monitor_shape";
+   singleDetailSize = "0";
+   neverImportMat = "DefaultMaterial	ColorEffect*";
+   flipUVCoords = "0";
+   joinIdenticalVerts = "0";
+   reverseWindingOrder = "0";
+   removeRedundantMats = "0";
+   animFPS = "2";
+};
+
+function monitor_shapefbx::onLoad(%this)
+{
+   %this.addNode("Col-1", "", "0 0 0 0 0 1 0", "0", "");
+   %this.addNode("ColBox-1", "Col-1", "0 0 0 1 0 0 0", "0", "Bounds");
+   %this.addCollisionDetail("-1", "Box", "Bounds", "4", "10", "30", "32", "30", "30", "30", "Flood fill");
+   %this.setBounds("-0.8 -0.244957 -0.0409516 0.8 0.244957 1.10231");
+   
+   if (!isObject(screen_Canvas))
+   {
+      new GuiOffscreenCanvas(screen_Canvas) {
+         targetName = "screen_Canvas";
+         targetSize = "1280 720";
+         dynamicTarget = false;
+         canInteract = true;
+         maxInteractDistance = "3";
+      };
+   }
+
+   if(isObject(OptionsMenu))
+   {
+      screen_Canvas.setContent(OptionsMenu);
+   }
+
+   %screen_Canvas_asset = "Prototyping:ScreenTarget";
+   if(!AssetDatabase.isDeclaredAsset(%screen_Canvas_asset))
+   {
+      %screen_asset = new ImageAsset()
+      {
+         assetName = "ScreenTarget";
+         versionId = 1;
+         imageFile = "#screen_Canvas";
+      };
+      TamlWrite(%screen_asset, expandPath("^Prototyping/gui_offscreen_test/" @ %screen_asset.AssetName @ ".asset.taml"));
+      %previewModule = ModuleDatabase.findModule("Prototyping",1);
+      AssetDatabase.addDeclaredAsset(%previewModule, expandPath("^Prototyping/gui_offscreen_test/" @ %screen_asset.AssetName @ ".asset.taml"));
+   }
+
+   %mat_asset = "Prototyping:monitor_screen_mat";
+   if(!AssetDatabase.isDeclaredAsset(%mat_asset))
+   {
+      echo("Material asset not found, this should exist");
+   }
+
+   %assetDef = AssetDatabase.acquireAsset(%mat_asset);
+   %material = %assetDef.materialDefinitionName;  
+   %material.DiffuseMapAsset = %screen_Canvas_asset;
+
+}