coverPoint.cpp
Engine/source/navigation/coverPoint.cpp
Public Variables
bool
For frame signal.
Public Functions
ConsoleDocClass(CoverPoint , "@brief A type of marker that designates <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> location AI characters can take <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">cover.\n\n</a>" )
DefineEngineMethod(CoverPoint , isOccupied , bool , () , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> someone is already using this cover point." )
ImplementEnumType(CoverPointSize , "The <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1ab7d671599a7b25ca99a487fa341bc33a">size</a> of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> cover <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">point.\n</a>" )
Detailed Description
Public Variables
EndImplementEnumType
bool gEditingMission
For frame signal.
Public Functions
ConsoleDocClass(CoverPoint , "@brief A type of marker that designates <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> location AI characters can take <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">cover.\n\n</a>" )
DefineEngineMethod(CoverPoint , isOccupied , bool , () , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> someone is already using this cover point." )
IMPLEMENT_CO_NETOBJECT_V1(CoverPoint )
ImplementEnumType(CoverPointSize , "The <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1ab7d671599a7b25ca99a487fa341bc33a">size</a> of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> cover <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">point.\n</a>" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2014 Daniel Buckmaster 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "coverPoint.h" 25 26#include "math/mathIO.h" 27#include "scene/sceneRenderState.h" 28#include "core/stream/bitStream.h" 29#include "materials/sceneData.h" 30#include "gfx/gfxDebugEvent.h" 31#include "gfx/gfxTransformSaver.h" 32#include "gfx/gfxDrawUtil.h" 33#include "renderInstance/renderPassManager.h" 34#include "console/engineAPI.h" 35 36extern bool gEditingMission; 37 38IMPLEMENT_CO_NETOBJECT_V1(CoverPoint); 39 40ConsoleDocClass(CoverPoint, 41 "@brief A type of marker that designates a location AI characters can take cover.\n\n" 42); 43 44ImplementEnumType(CoverPointSize, 45 "The size of a cover point.\n") 46 { CoverPoint::Prone, "Prone", "Only provides cover when prone.\n" }, 47 { CoverPoint::Crouch, "Crouch", "Only provides cover when crouching.\n" }, 48 { CoverPoint::Stand, "Stand", "Provides cover when standing.\n" }, 49EndImplementEnumType; 50 51//----------------------------------------------------------------------------- 52// Object setup and teardown 53//----------------------------------------------------------------------------- 54CoverPoint::CoverPoint() 55{ 56 mNetFlags.clear(Ghostable); 57 mTypeMask |= MarkerObjectType; 58 mSize = Stand; 59 mQuality = 1.0f; 60 mOccupied = false; 61 mPeekLeft = false; 62 mPeekRight = false; 63 mPeekOver = false; 64} 65 66CoverPoint::~CoverPoint() 67{ 68} 69 70//----------------------------------------------------------------------------- 71// Object Editing 72//----------------------------------------------------------------------------- 73void CoverPoint::initPersistFields() 74{ 75 addGroup("CoverPoint"); 76 77 addField("size", TYPEID<CoverPointSize>(), Offset(mSize, CoverPoint), 78 "The size of this cover point."); 79 80 addField("quality", TypeF32, Offset(mQuality, CoverPoint), 81 "Reliability of this point as solid cover. (0...1)"); 82 83 addField("peekLeft", TypeBool, Offset(mPeekLeft, CoverPoint), 84 "Can characters look left around this cover point?"); 85 addField("peekRight", TypeBool, Offset(mPeekRight, CoverPoint), 86 "Can characters look right around this cover point?"); 87 addField("peekOver", TypeBool, Offset(mPeekOver, CoverPoint), 88 "Can characters look over the top of this cover point?"); 89 90 endGroup("CoverPoint"); 91 92 Parent::initPersistFields(); 93} 94 95bool CoverPoint::onAdd() 96{ 97 if(!Parent::onAdd()) 98 return false; 99 100 // Set up a 1x1x1 bounding box 101 mObjBox.set(Point3F(-0.5f, -0.5f, -0.5f), 102 Point3F( 0.5f, 0.5f, 0.5f)); 103 resetWorldBox(); 104 105 if(gEditingMission) 106 onEditorEnable(); 107 108 addToScene(); 109 110 return true; 111} 112 113void CoverPoint::onRemove() 114{ 115 if(gEditingMission) 116 onEditorDisable(); 117 118 removeFromScene(); 119 120 Parent::onRemove(); 121 122 for(U32 i = 0; i < NumSizes; i++) 123 smVertexBuffer[i] = NULL; 124} 125 126void CoverPoint::setTransform(const MatrixF & mat) 127{ 128 Parent::setTransform(mat); 129 setMaskBits(TransformMask); 130} 131 132void CoverPoint::onEditorEnable() 133{ 134 mNetFlags.set(Ghostable); 135} 136 137void CoverPoint::onEditorDisable() 138{ 139 mNetFlags.clear(Ghostable); 140} 141 142void CoverPoint::inspectPostApply() 143{ 144 setMaskBits(TransformMask); 145} 146 147U32 CoverPoint::packUpdate(NetConnection *conn, U32 mask, BitStream *stream) 148{ 149 U32 retMask = Parent::packUpdate(conn, mask, stream); 150 151 stream->writeInt(mSize, 4); 152 153 stream->writeFlag(mOccupied); 154 155 stream->writeFlag(peekLeft()); 156 stream->writeFlag(peekRight()); 157 stream->writeFlag(peekOver()); 158 159 // Write our transform information 160 if(stream->writeFlag(mask & TransformMask)) 161 { 162 mathWrite(*stream, getTransform()); 163 mathWrite(*stream, getScale()); 164 } 165 166 return retMask; 167} 168 169void CoverPoint::unpackUpdate(NetConnection *conn, BitStream *stream) 170{ 171 Parent::unpackUpdate(conn, stream); 172 173 mSize = (Size)stream->readInt(4); 174 175 setOccupied(stream->readFlag()); 176 177 mPeekLeft = stream->readFlag(); 178 mPeekRight = stream->readFlag(); 179 mPeekOver = stream->readFlag(); 180 181 if(stream->readFlag()) // TransformMask 182 { 183 mathRead(*stream, &mObjToWorld); 184 mathRead(*stream, &mObjScale); 185 186 setTransform(mObjToWorld); 187 } 188} 189 190//----------------------------------------------------------------------------- 191// Functionality 192//----------------------------------------------------------------------------- 193 194Point3F CoverPoint::getNormal() const 195{ 196 return getTransform().getForwardVector(); 197} 198 199DefineEngineMethod(CoverPoint, isOccupied, bool, (),, 200 "@brief Returns true if someone is already using this cover point.") 201{ 202 return object->isOccupied(); 203} 204 205//----------------------------------------------------------------------------- 206// Object Rendering 207//----------------------------------------------------------------------------- 208 209GFXStateBlockRef CoverPoint::smNormalSB; 210GFXVertexBufferHandle<CoverPoint::VertexType> CoverPoint::smVertexBuffer[CoverPoint::NumSizes]; 211 212void CoverPoint::initGFXResources() 213{ 214 if(smVertexBuffer[0] != NULL) 215 return; 216 217 static const Point3F planePoints[4] = 218 { 219 Point3F(-1.0f, 0.0f, 0.0f), Point3F(-1.0f, 0.0f, 2.0f), 220 Point3F( 1.0f, 0.0f, 0.0f), Point3F( 1.0f, 0.0f, 2.0f), 221 }; 222 223 static const U32 planeFaces[6] = 224 { 225 0, 1, 2, 226 1, 2, 3 227 }; 228 229 static const Point3F scales[NumSizes] = 230 { 231 Point3F(1.0f, 1.0f, 0.5f), // Prone 232 Point3F(1.0f, 1.0f, 1.0f), // Crouch 233 Point3F(1.0f, 1.0f, 2.0f) // Stand 234 }; 235 236 static const ColorI colours[NumSizes] = 237 { 238 ColorI(180, 0, 0, 128), // Prone 239 ColorI(250, 200, 90, 128), // Crouch 240 ColorI( 80, 190, 20, 128) // Stand 241 }; 242 243 for(U32 i = 0; i < NumSizes; i++) 244 { 245 // Fill the vertex buffer 246 VertexType *pVert = NULL; 247 smVertexBuffer[i].set(GFX, 6, GFXBufferTypeStatic); 248 249 pVert = smVertexBuffer[i].lock(); 250 for(U32 j = 0; j < 6; j++) 251 { 252 pVert[j].point = planePoints[planeFaces[j]] * scales[i] * 0.5f; 253 pVert[j].normal = Point3F(0.0f, -1.0f, 0.0f); 254 pVert[j].color = colours[i]; 255 } 256 smVertexBuffer[i].unlock(); 257 } 258 259 // Set up our StateBlock 260 GFXStateBlockDesc desc; 261 desc.cullDefined = true; 262 desc.cullMode = GFXCullNone; 263 desc.setBlend(true); 264 smNormalSB = GFX->createStateBlock(desc); 265} 266 267void CoverPoint::prepRenderImage(SceneRenderState *state) 268{ 269 // Allocate an ObjectRenderInst so that we can submit it to the RenderPassManager 270 ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); 271 272 // Now bind our rendering function so that it will get called 273 ri->renderDelegate.bind(this, &CoverPoint::render); 274 275 // Set our RenderInst as a standard object render 276 ri->type = RenderPassManager::RIT_Editor; 277 278 // Set our sorting keys to a default value 279 ri->defaultKey = 0; 280 ri->defaultKey2 = 0; 281 282 // Submit our RenderInst to the RenderPassManager 283 state->getRenderPass()->addInst(ri); 284} 285 286void CoverPoint::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat) 287{ 288 initGFXResources(); 289 290 if(overrideMat) 291 return; 292 293 if(smVertexBuffer[mSize].isNull()) 294 return; 295 296 PROFILE_SCOPE(CoverPoint_Render); 297 298 // Set up a GFX debug event (this helps with debugging rendering events in external tools) 299 GFXDEBUGEVENT_SCOPE(CoverPoint_Render, ColorI::RED); 300 301 // GFXTransformSaver is a handy helper class that restores 302 // the current GFX matrices to their original values when 303 // it goes out of scope at the end of the function 304 GFXTransformSaver saver; 305 306 // Calculate our object to world transform matrix 307 MatrixF objectToWorld = getRenderTransform(); 308 objectToWorld.scale(getScale()); 309 310 // Apply our object transform 311 GFX->multWorld(objectToWorld); 312 313 // Set the state block 314 GFX->setStateBlock(smNormalSB); 315 316 // Set up the "generic" shaders 317 // These handle rendering on GFX layers that don't support 318 // fixed function. Otherwise they disable shaders. 319 GFX->setupGenericShaders(GFXDevice::GSModColorTexture); 320 321 // Set the vertex buffer 322 GFX->setVertexBuffer(smVertexBuffer[mSize]); 323 324 // Draw our triangles 325 GFX->drawPrimitive(GFXTriangleList, 0, 2); 326 327 // Data for decorations. 328 GFXStateBlockDesc desc; 329 F32 height = (float)(mSize + 1) / NumSizes * 2.0f; 330 331 // Draw an X if we're occupied. 332 if(isOccupied()) 333 { 334 GFX->getDrawUtil()->drawArrow(desc, Point3F(-0.5, 0, 0), Point3F(0.5, 0, height), ColorI::RED); 335 GFX->getDrawUtil()->drawArrow(desc, Point3F(0.5, 0, 0), Point3F(-0.5, 0, height), ColorI::RED); 336 } 337 338 // Draw arrows to represent peek directions. 339 if(peekLeft()) 340 GFX->getDrawUtil()->drawArrow(desc, Point3F(0, 0, height * 0.5), Point3F(-0.5, 0, height * 0.5), ColorI::GREEN); 341 if(peekRight()) 342 GFX->getDrawUtil()->drawArrow(desc, Point3F(0, 0, height * 0.5), Point3F(0.5, 0, height * 0.5), ColorI::GREEN); 343 if(peekOver()) 344 GFX->getDrawUtil()->drawArrow(desc, Point3F(0, 0, height * 0.5), Point3F(0, 0, height), ColorI::GREEN); 345} 346