Files
SLikeNet/DependentExtensions/SQLite3Plugin/Logger/ClientOnly/Samples/Ogre3D/BspCollision.cpp
2025-11-24 14:19:51 +05:30

320 lines
11 KiB
C++

/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/
Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html
You may use this sample code for anything you like, it is not covered by the
LGPL like the rest of the engine.
-----------------------------------------------------------------------------
*/
/*
* This file was taken from RakNet 4.082.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*
* Modified work: Copyright (c) 2017-2020, SLikeSoft UG (haftungsbeschränkt)
*
* Modifications in this file are free to be used for anything you like.
* Alternatively you are permitted to license the modifications under the MIT license, if you so desire. The
* license can be found in the license.txt file in the root directory of this source tree.
*/
/*
-----------------------------------------------------------------------------
Filename: BspCollision.cpp
Description: Somewhere to play in the sand...
-----------------------------------------------------------------------------
*/
#include "OgreReferenceAppLayer.h"
#include "ExampleRefAppApplication.h"
#include "OgreStringConverter.h"
// Hacky globals
ApplicationObject *ball;
SceneNode* targetNode;
RaySceneQuery* rsq = 0;
static const int num_rows = 3;
// RakNet: Logger includes.
#include "SQLiteClientLoggerPlugin.h"
#include "slikenet/PacketizedTCP.h"
#include "Ogre3D_DX9_BackbufferGrabber.h"
#include "slikenet/time.h"
#include "slikenet/GetTime.h"
// Event handler to add ability to alter curvature
class BspCollisionListener : public ExampleRefAppFrameListener
{
protected:
// RakNet: For logging video
PacketizedTCP packetizedTCP;
SLNet::SQLiteClientLoggerPlugin loggerPlugin;
Ogre3D_DX9_BackbufferGrabber backbufferGrabber;
SLNet::TimeMS lastScreenshotTime;
// Also save the world * so we can log it out
World* mWorld;
public:
BspCollisionListener(RenderWindow* win, CollideCamera* cam, World* world)
: ExampleRefAppFrameListener(win, cam)
{
// RakNet: Connect to server using TCP, for logging video
packetizedTCP.AttachPlugin(&loggerPlugin);
packetizedTCP.Start(0,0);
loggerPlugin.SetServerParameters(packetizedTCP.Connect("127.0.0.1", 38123, true), "ogrevideo.sqlite");
// For testing, I'm using 512x512 with a huge memory constraint at 30 FPS
// For a real game, you probably want to limit this to 256x256, with a 8MB memory constraint, at 15-20 FPS
loggerPlugin.SetMemoryConstraint(128000000);
backbufferGrabber.InitBackbufferGrabber(mWindow, 512, 512);
lastScreenshotTime=0;
mWorld=world;
}
bool frameEnded(const FrameEvent& evt)
{
// local just to stop toggles flipping too fast
static Real timeUntilNextToggle = 0;
// Deal with time delays that are too large
// If we exceed this limit, we ignore
static const Real MAX_TIME_INCREMENT = 0.5f;
if (evt.timeSinceLastEvent > MAX_TIME_INCREMENT)
{
return true;
}
if (timeUntilNextToggle >= 0)
timeUntilNextToggle -= evt.timeSinceLastFrame;
// Call superclass
bool ret = ExampleRefAppFrameListener::frameEnded(evt);
if (mKeyboard->isKeyDown(OIS::KC_SPACE) && timeUntilNextToggle <= 0)
{
timeUntilNextToggle = 2;
ball->setPosition(mCamera->getPosition() +
mCamera->getDirection() * mCamera->getNearClipDistance() * 2);
ball->setLinearVelocity(mCamera->getDirection() * 200);
ball->setAngularVelocity(Vector3::ZERO);
// RakNet: Log events, which in this case is only firing the ball. Give the event a color so we can plot it
rakSqlLog("EventData", "x,y,z,name,color",
(mCamera->getPosition().x, mCamera->getPosition().y, mCamera->getPosition().z, "Fired Ball", "green"));
}
// Move the targeter
rsq->setRay(mCamera->getRealCamera()->getCameraToViewportRay(0.5, 0.5));
RaySceneQueryResult& rsqResult = rsq->execute();
RaySceneQueryResult::iterator ri = rsqResult.begin();
if (ri != rsqResult.end())
{
RaySceneQueryResultEntry& res = *ri;
targetNode->setPosition(rsq->getRay().getPoint(res.distance));
}
// RakNet: Send screenshot and FPS info to server if connected, at most once every 30 milliseconds
// This is constrained so we don't overflow the server with screenshots
// Also only do it if we connected to the server
SLNet::TimeMS timeSinceLastLog= SLNet::GetTimeMS()-lastScreenshotTime;
if (packetizedTCP.GetConnectionCount()>0 && timeSinceLastLog>30)
{
SLNet::RGBImageBlob blob;
backbufferGrabber.LockBackbufferCopy(&blob);
RakAssert(blob.data!=0);
// RakNet: Log frame data, including screenshot and FPS
SLNet::SQLLogResult logResult = rakSqlLog("FrameData", "screenshot,averageFPS,lastFPS,bestFPS,worstFPS,numTris,DebugText",
( &blob,mWindow->getAverageFPS(),mWindow->getLastFPS(),mWindow->getBestFPS(),mWindow->getWorstFPS(),(int) mWindow->getTriangleCount(),mDebugText.c_str() ));
// Release backbuffer as soon as possible, after sending frame data
backbufferGrabber.ReleaseBackbufferCopy();
if ( logResult== SLNet::SQLLR_WOULD_EXCEED_MEMORY_CONSTRAINT )
{
/// Sending too large of screenshots, or can't transfer data fast enough. See loggerPlugin.SetMemoryConstraint
}
// Also log out position of all world objects
Entity *entity;
SceneNode *sceneNode;
entity = mWorld->getSceneManager()->getEntity("ball");
sceneNode = entity->getParentSceneNode();
// RakNet: Log object position data over time
rakSqlLog("ObjectData", "x,y,z,name,color",
(sceneNode->getPosition().x, sceneNode->getPosition().y, sceneNode->getPosition().z, entity->getName().c_str(), "blue"));
for (int row = 0; row < num_rows; ++row)
{
for (int i = 0; i < (num_rows-row); ++i)
{
String name = "box";
name += StringConverter::toString((row*num_rows) + i);
entity = mWorld->getSceneManager()->getEntity(name);
sceneNode = entity->getParentSceneNode();
rakSqlLog("ObjectData", "x,y,z,name,color",
(sceneNode->getPosition().x, sceneNode->getPosition().y, sceneNode->getPosition().z, entity->getName().c_str(), "red"));
}
}
lastScreenshotTime= SLNet::GetTimeMS();
}
return ret;
}
};
class BspCollisionApplication : public ExampleRefAppApplication
{
public:
BspCollisionApplication() {
}
~BspCollisionApplication()
{
delete rsq;
}
protected:
void chooseSceneManager(void)
{
mSceneMgr = mRoot->createSceneManager("BspSceneManager");
}
void createWorld(void)
{
// Create BSP-specific world
mWorld = new World(mSceneMgr, World::WT_REFAPP_BSP);
}
void createScene(void)
{
mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
// Set ambient light
mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));
// Create a point light
Light* l = mSceneMgr->createLight("MainLight");
l->setPosition(-100,50,100);
l->setAttenuation(8000,1,0,0);
// Setup World
mWorld->setGravity(Vector3(0, 0, -60));
mWorld->getSceneManager()->setWorldGeometry("ogretestmap.bsp");
// modify camera for close work
mCamera->setNearClipDistance(10);
mCamera->setFarClipDistance(20000);
// Also change position, and set Quake-type orientation
// Get random player start point
ViewPoint vp = mSceneMgr->getSuggestedViewpoint(true);
mCamera->setPosition(vp.position);
mCamera->pitch(Degree(90)); // Quake uses X/Y horizon, Z up
mCamera->rotate(vp.orientation);
// Don't yaw along variable axis, causes leaning
mCamera->setFixedYawAxis(true, Vector3::UNIT_Z);
// Look at the boxes
mCamera->lookAt(-150,40,30);
ball = mWorld->createBall("ball", 7, vp.position + Vector3(0,0,80));
ball->setDynamicsEnabled(true);
ball->getEntity()->setMaterialName("Ogre/Eyes");
OgreRefApp::Box* box = mWorld->createBox("shelf", 75, 125, 5, Vector3(-150, 40, 30));
box->getEntity()->setMaterialName("Examples/Rocky");
static const Real BOX_SIZE = 15.0f;
for (int row = 0; row < num_rows; ++row)
{
for (int i = 0; i < (num_rows-row); ++i)
{
Real row_size = (num_rows - row) * BOX_SIZE * 1.25;
String name = "box";
name += StringConverter::toString((row*num_rows) + i);
box = mWorld->createBox(name, BOX_SIZE,BOX_SIZE,BOX_SIZE ,
Vector3(-150,
40 - (row_size * 0.5) + (i * BOX_SIZE * 1.25) ,
32.5 + (BOX_SIZE / 2) + (row * BOX_SIZE)));
box->setDynamicsEnabled(false, true);
box->getEntity()->setMaterialName("Examples/10PointBlock");
}
}
mCamera->setCollisionEnabled(false);
mCamera->getRealCamera()->setQueryFlags(0);
// Create the targeting sphere
Entity* targetEnt = mSceneMgr->createEntity("testray", "sphere.mesh");
MaterialPtr mat = MaterialManager::getSingleton().create("targeter",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Pass* pass = mat->getTechnique(0)->getPass(0);
TextureUnitState* tex = pass->createTextureUnitState();
tex->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT,
ColourValue::Red);
pass->setLightingEnabled(false);
pass->setSceneBlending(SBT_ADD);
pass->setDepthWriteEnabled(false);
targetEnt->setMaterialName("targeter");
targetEnt->setCastShadows(false);
targetEnt->setQueryFlags(0);
targetNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
targetNode->scale(0.025, 0.025, 0.025);
targetNode->attachObject(targetEnt);
rsq = mSceneMgr->createRayQuery(Ray());
rsq->setSortByDistance(true, 1);
rsq->setWorldFragmentType(SceneQuery::WFT_SINGLE_INTERSECTION);
}
// Create new frame listener
void createFrameListener(void)
{
mFrameListener= new BspCollisionListener(mWindow, mCamera, mWorld);
mRoot->addFrameListener(mFrameListener);
}
public:
};
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
// Create application object
BspCollisionApplication app;
try {
app.go();
} catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox(nullptr, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
}
return 0;
}