| /* Copyright (C) 2001 by Jorrit Tyberghein This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cssysdef.h" #include "isotest.h" #include "cstool/csview.h" #include "cstool/initapp.h" #include "csutil/cmdhelp.h" #include "csutil/cscolor.h" #include "csutil/event.h" #include "csutil/sysfunc.h" #include "iengine/camera.h" #include "iengine/campos.h" #include "iengine/engine.h" #include "iengine/light.h" #include "iengine/material.h" #include "iengine/mesh.h" #include "iengine/movable.h" #include "iengine/sector.h" #include "iengine/texture.h" #include "igraphic/imageio.h" #include "imap/loader.h" #include "imesh/object.h" #include "imesh/sprite3d.h" #include "iutil/csinput.h" #include "iutil/event.h" #include "iutil/eventq.h" #include "iutil/objreg.h" #include "iutil/vfs.h" #include "iutil/virtclk.h" #include "ivaria/reporter.h" #include "ivaria/stdrep.h" #include "ivideo/fontserv.h" #include "ivideo/graph2d.h" #include "ivideo/graph3d.h" #include "ivideo/material.h" #include "ivideo/texture.h" #include "ivideo/txtmgr.h" #include "imesh/genmesh.h" #include "imesh/gmeshskel.h" CS_IMPLEMENT_APPLICATION //------------------------------------------------------------------------ // The global pointer to isotest IsoTest *isotest; IsoTest::IsoTest (iObjectRegistry* object_reg) { IsoTest::object_reg = object_reg; current_view = 0; views[0].SetOrigOffset (csVector3 (-4, 4, -4)); // true isometric perspective. views[1].SetOrigOffset (csVector3 (-9, 9, -9)); // zoomed out. views[2].SetOrigOffset (csVector3 (4, 3, -4)); // diablo style perspective. views[3].SetOrigOffset (csVector3 (0, 4, -4)); // zelda style perspective. actor_is_walking = false; } IsoTest::~IsoTest () { } void IsoTest::SetupFrame () { // First get elapsed time from the virtual clock. csTicks elapsed_time = vc->GetElapsedTicks (); // Now rotate the camera according to keyboard state float speed = (elapsed_time / 1000.0) * (0.03 * 90); if (kbd->GetModifierState (CSKEY_SHIFT_LEFT) || kbd->GetModifierState (CSKEY_SHIFT_RIGHT)) { if (kbd->GetKeyState (CSKEY_RIGHT)) views[current_view].angle += speed*15.f; if (kbd->GetKeyState (CSKEY_LEFT)) views[current_view].angle -= speed*15.f; if (kbd->GetKeyState (CSKEY_UP)) views[current_view].distance -= 0.25f*speed; if (kbd->GetKeyState (CSKEY_DOWN)) views[current_view].distance += 0.25f*speed; SetupIsoView(views[current_view]); } else { float facing = 0.f; // in degrees bool moved = false; if (kbd->GetKeyState (CSKEY_RIGHT)) { moved = true; actor->GetMovable ()->MovePosition (csVector3 (speed, 0, 0)); facing = 270.f; } if (kbd->GetKeyState (CSKEY_LEFT)) { moved = true; actor->GetMovable ()->MovePosition (csVector3 (-speed, 0, 0)); facing = 90.f; } if (kbd->GetKeyState (CSKEY_UP)) { moved = true; actor->GetMovable ()->MovePosition (csVector3 (0, 0, speed)); facing = 0.f; } if (kbd->GetKeyState (CSKEY_DOWN)) { moved = true; actor->GetMovable ()->MovePosition (csVector3 (0, 0, -speed)); facing = 180.f; } if(kbd->GetKeyState (CSKEY_DOWN) && kbd->GetKeyState (CSKEY_LEFT)) facing = 135; if(kbd->GetKeyState (CSKEY_DOWN) && kbd->GetKeyState (CSKEY_RIGHT)) facing = 225; if(kbd->GetKeyState (CSKEY_UP) && kbd->GetKeyState (CSKEY_LEFT)) facing = 45; if(kbd->GetKeyState (CSKEY_UP) && kbd->GetKeyState (CSKEY_RIGHT)) facing = 315; if(moved) { csYRotMatrix3 r(facing*PI/180.0); actor->GetMovable ()->SetTransform(r); } // update animation state csRef<iGeneralMeshState> spstate ( SCF_QUERY_INTERFACE (actor->GetMeshObject (), iGeneralMeshState)); csRef<iGenMeshSkeletonControlState> animcontrol ( SCF_QUERY_INTERFACE (spstate->GetAnimationControl (), iGenMeshSkeletonControlState)); if(actor_is_walking && !moved) { animcontrol->StopAll(); animcontrol->Execute("idle"); } if(!actor_is_walking && moved) { animcontrol->StopAll(); animcontrol->Execute("walk"); } actor_is_walking = moved; } // Make sure actor is constant distance above plane. csVector3 actor_pos = actor->GetMovable ()->GetPosition (); actor_pos.y += 10.0; // Make sure we start beam high enough. csVector3 end_pos, isect; end_pos = actor_pos; end_pos.y -= 100.0; float r; plane->HitBeamObject (actor_pos, end_pos, isect, &r); actor_pos.y = isect.y + .8; actor->GetMovable ()->SetPosition (actor_pos); actor->GetMovable ()->UpdateMove (); // Move the light. actor_light->SetCenter (actor_pos+csVector3 (0, 2, -1)); CameraIsoLookat(view->GetCamera(), views[current_view], actor_pos); // Tell 3D driver we're going to display 3D things. if (!g3d->BeginDraw (engine->GetBeginDrawFlags () | CSDRAW_3DGRAPHICS)) return; // Tell the camera to render into the frame buffer. view->Draw (); if (!g3d->BeginDraw (CSDRAW_2DGRAPHICS)) return; csVector2 lpos(0,0); view->GetCamera()->Perspective( view->GetCamera()->GetTransform ().Other2This(csVector3 (-4.7f, 1.0f, 5.5f)), lpos); // display a helpful little text. int txtw=0, txth=0; font->GetMaxSize(txtw, txth); if(txth == -1) txth = 20; int white = g3d->GetDriver2D ()->FindRGB (255, 255, 255); g3d->GetDriver2D ()->DrawBox((int)lpos.x-2, g3d->GetDriver2D ()->GetHeight()-(int)lpos.y-2,4,4,white); int ypos = g3d->GetDriver2D ()->GetHeight () - txth*4 - 1; g3d->GetDriver2D ()->Write (font, 1, ypos, white, -1, "Isometric demo keys (esc to exit):"); ypos += txth; g3d->GetDriver2D ()->Write (font, 1, ypos, white, -1, " arrow keys: move around"); ypos += txth; g3d->GetDriver2D ()->Write (font, 1, ypos, white, -1, " shift+arrow keys: rotate/zoom camera"); ypos += txth; g3d->GetDriver2D ()->Write (font, 1, ypos, white, -1, " tab key: cycle through camera presets"); } void IsoTest::FinishFrame () { g3d->FinishDraw (); g3d->Print (0); } bool IsoTest::HandleEvent (iEvent& ev) { if (ev.Type == csevBroadcast && csCommandEventHelper::GetCode(&ev) == cscmdProcess) { isotest->SetupFrame (); return true; } else if (ev.Type == csevBroadcast && csCommandEventHelper::GetCode(&ev) == cscmdFinalProcess) { isotest->FinishFrame (); return true; } else if ((ev.Type == csevKeyboard) && (csKeyEventHelper::GetEventType (&ev) == csKeyEventTypeDown)) { utf32_char c = csKeyEventHelper::GetCookedCode (&ev); if (c == CSKEY_ESC) { csRef<iEventQueue> q (CS_QUERY_REGISTRY (object_reg, iEventQueue)); if (q) q->GetEventOutlet()->Broadcast (cscmdQuit); return true; } else if (c == CSKEY_TAB) { current_view++; if (current_view >= 4) current_view = 0; } } return false; } void IsoTest::CameraIsoLookat(csRef<iCamera> cam, const IsoView& isoview, const csVector3& lookat) { // Let the camera look at the actor. // so the camera is set to look at 'actor_pos' //int isofactor = 50; // 98.3% isometric (=GetFovAngle()/180.0) //int isofactor = 100; // 99.2% isometric (=GetFovAngle()/180.0) int isofactor = 200; // 99.6% isometric (=GetFovAngle()/180.0) // set center and lookat csOrthoTransform& cam_trans = cam->GetTransform (); cam_trans.SetOrigin (lookat + float(isofactor)*isoview.camera_offset); cam_trans.LookAt (lookat-cam_trans.GetOrigin (), csVector3 (0, 1, 0)); // set fov more isometric, could be done in initialisation once. cam->SetFOV (g3d->GetHeight()*isofactor, g3d->GetWidth()); // due to moving the camera so far away, depth buffer accuracy is // impaired, repair that by using smaller coordinate system csOrthoTransform repair_trans = cam->GetTransform(); repair_trans.SetT2O (repair_trans.GetT2O()/repair_trans.GetOrigin().Norm()); cam->SetTransform (repair_trans); } void IsoTest::SetupIsoView(IsoView& isoview) { // clamp if(isoview.angle < 0.f) isoview.angle += 360.f; if(isoview.angle > 360.f) isoview.angle -= 360.f; if(isoview.distance < 0.05f) isoview.distance = 0.05f; if(views[current_view].distance > 10.f) isoview.distance = 10.f; // setup csYRotMatrix3 r(isoview.angle * PI / 180.0); isoview.camera_offset = (r*isoview.original_offset)*isoview.distance; } bool IsoTest::IsoTestEventHandler (iEvent& ev) { return isotest->HandleEvent (ev); } bool IsoTest::LoadMap () { // First disable the lighting cache. Our map uses stencil // lighting. engine->SetLightingCacheMode (0); // Set VFS current directory to the level we want to load. csRef<iVFS> VFS (CS_QUERY_REGISTRY (object_reg, iVFS)); VFS->ChDir ("/lev/isomap"); // Load the level file which is called 'world'. if (!loader->LoadMapFile ("world")) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Couldn't load level!"); return false; } // Find the starting position in this level. csVector3 pos (0, 0, 0); if (engine->GetCameraPositions ()->GetCount () > 0) { // There is a valid starting position defined in the level file. iCameraPosition* campos = engine->GetCameraPositions ()->Get (0); room = engine->GetSectors ()->FindByName (campos->GetSector ()); pos = campos->GetPosition (); } else { // We didn't find a valid starting position. So we default // to going to room called 'room' at position (0,0,0). room = engine->GetSectors ()->FindByName ("room"); } if (!room) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Can't find a valid starting position!"); return false; } view->GetCamera ()->SetSector (room); view->GetCamera ()->GetTransform ().SetOrigin (pos); iLightList* ll = room->GetLights (); actor_light = engine->CreateLight (0, csVector3 (-3, 5, 0), 5, csColor (1, 1, 1)); ll->Add (actor_light); csRef<iLight> statuelight = engine->CreateLight ("statuelight", csVector3 (-4.7f, 1.0f, 5.5f), 4, csColor(1.2f,0.2f,0.2f)); statuelight->CreateNovaHalo (1278, 15, 0.3f); ll->Add (statuelight); plane = engine->FindMeshObject ("Plane"); return true; } bool IsoTest::CreateActor () { // Load a texture for our sprite. iTextureManager* txtmgr = g3d->GetTextureManager (); iTextureWrapper* txt = loader->LoadTexture ("vedette_fashion", "/lib/std/ugly_woman.jpg", CS_TEXTURE_3D, txtmgr, false, false); if (txt == 0) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Error loading texture!"); return false; } csRef<iStringSet> strings = CS_QUERY_REGISTRY_TAG_INTERFACE ( object_reg, "crystalspace.shared.stringset", iStringSet); csRef<iShaderManager> shader_mgr = CS_QUERY_REGISTRY (object_reg, iShaderManager); if (shader_mgr == 0) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Couldn't find shader manager! This application requires new renderer!" ); return false; } iShader* ambient_shader = shader_mgr->GetShader ("ambient"); iShader* light_shader = shader_mgr->GetShader ("light"); if (ambient_shader == 0 || light_shader == 0) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Couldn't find shaders!"); return false; } csRef<iMaterial> fash_material = engine->CreateBaseMaterial (txt); fash_material->SetShader (strings->Request ("ambient"), ambient_shader); fash_material->SetShader (strings->Request ("diffuse"), light_shader); engine->GetMaterialList ()->NewMaterial (fash_material, "vedette_fashion"); // Load a sprite template from disk. csRef<iMeshFactoryWrapper> imeshfact ( loader->LoadMeshObjectFactory ("/lev/isomap/vedette.spr")); if (imeshfact == 0) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Error loading mesh object factory!"); return false; } csMatrix3 m; m.Identity (); m *= 1.10f; // scaling factor imeshfact->HardTransform (csReversibleTransform (m, csVector3 (0))); // Create the sprite and add it to the engine. actor = engine->CreateMeshWrapper ( imeshfact, "MySprite", room, csVector3 (-3, 2, 3)); actor->GetMovable ()->UpdateMove (); csRef<iGeneralMeshState> spstate ( SCF_QUERY_INTERFACE (actor->GetMeshObject (), iGeneralMeshState)); csRef<iGenMeshSkeletonControlState> animcontrol ( SCF_QUERY_INTERFACE (spstate->GetAnimationControl (), iGenMeshSkeletonControlState)); animcontrol->StopAll(); animcontrol->Execute("idle"); // The following two calls are not needed since CS_ZBUF_USE and // Object render priority are the default but they show how you // can do this. actor->SetZBufMode (CS_ZBUF_USE); actor->SetRenderPriority (engine->GetObjectRenderPriority ()); return true; } bool IsoTest::Initialize () { if (!csInitializer::RequestPlugins (object_reg, CS_REQUEST_VFS, CS_REQUEST_OPENGL3D, CS_REQUEST_ENGINE, CS_REQUEST_PLUGIN("crystalspace.font.server.multiplexer", iFontServer), "crystalspace.font.server.freetype2", "iFontServer.1", scfInterfaceTraits<iFontServer>::GetID(), scfInterfaceTraits<iFontServer>::GetVersion(), "crystalspace.font.server.default", "iFontServer.2", scfInterfaceTraits<iFontServer>::GetID(), scfInterfaceTraits<iFontServer>::GetVersion(), CS_REQUEST_FONTSERVER, CS_REQUEST_IMAGELOADER, CS_REQUEST_LEVELLOADER, CS_REQUEST_REPORTER, CS_REQUEST_REPORTERLISTENER, CS_REQUEST_END)) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Can't initialize plugins!"); return false; } if (!csInitializer::SetupEventHandler (object_reg, IsoTestEventHandler)) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Can't initialize event handler!"); return false; } // Check for commandline help. if (csCommandLineHelper::CheckHelp (object_reg)) { csCommandLineHelper::Help (object_reg); return false; } // The virtual clock. vc = CS_QUERY_REGISTRY (object_reg, iVirtualClock); if (!vc) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Can't find the virtual clock!"); return false; } // Find the pointer to engine plugin engine = CS_QUERY_REGISTRY (object_reg, iEngine); if (!engine) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "No iEngine plugin!"); return false; } loader = CS_QUERY_REGISTRY (object_reg, iLoader); if (!loader) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "No iLoader plugin!"); return false; } g3d = CS_QUERY_REGISTRY (object_reg, iGraphics3D); if (!g3d) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "No iGraphics3D plugin!"); return false; } kbd = CS_QUERY_REGISTRY (object_reg, iKeyboardDriver); if (!kbd) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "No iKeyboardDriver plugin!"); return false; } // Open the main system. This will open all the previously loaded plug-ins. if (!csInitializer::OpenApplication (object_reg)) { csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Error opening system!"); return false; } view = csPtr<iView> (new csView (engine, g3d)); iGraphics2D* g2d = g3d->GetDriver2D (); view->SetRectangle (0, 0, g2d->GetWidth (), g2d->GetHeight ()); font = g3d->GetDriver2D ()->GetFontServer()->LoadFont ("/fonts/ttf/Vera.ttf", 10); if(!font) // fallback font = g3d->GetDriver2D ()->GetFontServer()->LoadFont(CSFONT_LARGE); if (!LoadMap ()) return false; if (!CreateActor ()) return false; engine->Prepare (); return true; } void IsoTest::Start () { csDefaultRunLoop (object_reg); } /*---------------------------------------------------------------------* * Main function *---------------------------------------------------------------------*/ int main (int argc, char* argv[]) { iObjectRegistry* object_reg = csInitializer::CreateEnvironment (argc, argv); if (!object_reg) return -1; isotest = new IsoTest (object_reg); if (isotest->Initialize ()) isotest->Start (); delete isotest; csInitializer::DestroyApplication (object_reg); return 0; } |
""" isotest.py The intent of this script is to remake isotest.cpp line-for-line in Python. The purpose is to improve and expand the use of Python in Crystal Space projects. My hope is that others will do the same with some of the other tutorial scripts, eventually forming a PyCrystal (CrystalPy?) community. Scott Holliday """ ############################## Module Imports # import Python modules import types, string, re, sys, math, traceback # import CrystalSpace module try: from cspace import * except: print "WARNING: Failed to import module cspace" sys.exit(1) ############################## rewriting isotest.h class IsoView: def __init__(self,v): # initialize with original offset of camera from the spot you look at. self.camera_offset = v # offset to apply to the camera. self.original_offset = v # original camera offset. self.angle = 0.0 # angle of rotation, in degrees, 0.0 is original. self.distance = 1.0 # distance from the lookat spot. 1.0 is original distance. ############################## Event Handler is Global Instead def IsoTestEventHandler(ev): try: if ev.Type == csevBroadcast and csCommandEventHelper.GetCode(ev) == cscmdProcess: isotest.SetupFrame() return 1 elif ev.Type == csevBroadcast and csCommandEventHelper.GetCode(ev) == cscmdFinalProcess: try: isotest.FinishFrame() except: msg=traceback.format_exc() csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,"crystalspace.application.isotest", msg) return 1 elif ev.Type == csevKeyboard and csKeyEventHelper.GetEventType(ev) == csKeyEventTypeDown: c = csKeyEventHelper.GetCookedCode (ev) if c == CSKEY_ESC: q = CS_QUERY_REGISTRY (object_reg, iEventQueue) if q: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Done! "+str(framecount)) q.GetEventOutlet().Broadcast(cscmdQuit) except: traceback.print_exc() # prints the usual error messages sys.exit(1) # stop dead return 1 ############################## Rewriting isotest.cpp # The global pointer to isotest isotest=IsoTest() class IsoTest: ########## Variables are instead initialized in the Initialize Method below def SetupFrame (self): global framecount # First get elapsed time from the virtual clock. elapsed_time = self.vc.GetElapsedTicks () # Now rotate the camera according to keyboard state speed = elapsed_time / 1000.0 * 0.03 * 90 ################# WARNING: SHIFT CSKEYS ARE UNDEFINED! # if self.kbd.GetModifierState(CSKEY_SHIFT): if 1: angle=self.views[self.current_view].angle distance=self.views[self.current_view].distance if self.kbd.GetKeyState (CSKEY_DEL): self.views[self.current_view].angle -= speed*15.0 if self.kbd.GetKeyState (CSKEY_END): self.views[self.current_view].angle += speed*15.0 if self.kbd.GetKeyState (CSKEY_PGUP): self.views[self.current_view].distance -= speed/2 if self.kbd.GetKeyState (CSKEY_PGDN): self.views[self.current_view].distance += speed/2 if angle!=self.views[self.current_view].angle or distance!=self.views[self.current_view].distance: self.SetupIsoView(self.views[self.current_view]) moved = 0 if self.kbd.GetKeyState (CSKEY_RIGHT): moved = 1 self.actor.GetMovable ().MovePosition (csVector3 (speed, 0, 0)) facing = 270.0 if self.kbd.GetKeyState (CSKEY_LEFT): moved = 1 self.actor.GetMovable ().MovePosition (csVector3 (-speed, 0, 0)) facing = 90.0 if self.kbd.GetKeyState (CSKEY_UP): moved = 1 self.actor.GetMovable ().MovePosition (csVector3 (0, 0, speed)) facing = 0.0 if self.kbd.GetKeyState (CSKEY_DOWN): moved = 1 self.actor.GetMovable ().MovePosition (csVector3 (0, 0, -speed)) facing = 180.0 if self.kbd.GetKeyState (CSKEY_DOWN) and self.kbd.GetKeyState (CSKEY_LEFT): facing = 135.0 if self.kbd.GetKeyState (CSKEY_DOWN) and self.kbd.GetKeyState (CSKEY_RIGHT): facing = 225.0 if self.kbd.GetKeyState (CSKEY_UP) and self.kbd.GetKeyState (CSKEY_LEFT): facing = 45.0 if self.kbd.GetKeyState (CSKEY_UP) and self.kbd.GetKeyState (CSKEY_RIGHT): facing = 315.0 if self.kbd.GetKeyState (CSKEY_TAB): self.current_view=(self.current_view+1)%4 if moved: r = csYRotMatrix3(facing*math.pi/180.0) self.actor.GetMovable ().SetTransform(r) # update animation state self.spstate = SCF_QUERY_INTERFACE (self.actor.GetMeshObject (), iGeneralMeshState) ################# WARNING: iGenMeshSkeletonControlState is not defined! #self.animcontrol (SCF_QUERY_INTERFACE (spstate.GetAnimationControl (),iGenMeshSkeletonControlState)) # if self.actor_is_walking and moved==0: # self.animcontrol->StopAll() # self.animcontrol->Execute("idle") # if self.actor_is_walking==0 and moved: # self.animcontrol->StopAll() # self.animcontrol->Execute("walk") self.actor_is_walking = moved # Make sure actor is constant distance above plane. self.actor_pos = self.actor.GetMovable ().GetPosition () startpos=self.actor_pos+csVector3(0,10,0) # Make sure we start beam high enough. endpos=self.actor_pos-csVector3(0,100,0) hbo=self.plane.HitBeamObject(startpos,endpos) ## HitBeamObject returns csHitBeamResult self.actor_pos.y = hbo.isect.y + 0.85 self.actor.GetMovable ().SetPosition (self.actor_pos) self.actor.GetMovable ().UpdateMove () # Move the light. self.actor_light.SetCenter (self.actor_pos+csVector3 (0, 2, -1)) self.CameraIsoLookat(self.view.GetCamera(), self.views[self.current_view], self.actor_pos) # Tell 3D driver we're going to display 3D things. if not self.g3d.BeginDraw(self.engine.GetBeginDrawFlags() | CSDRAW_3DGRAPHICS): return # Tell the camera to render into the frame buffer. self.view.Draw () if not self.g3d.BeginDraw (CSDRAW_2DGRAPHICS): return lpos = self.view.GetCamera().Perspective(self.view.GetCamera(). GetTransform().Other2This(csVector3(-4.7, 1.0, 5.5))) # display a helpful little text. txtw,txth = self.font.GetMaxSize() if txth == -1: txth = 20 white = self.g3d.GetDriver2D ().FindRGB (255, 255, 255) self.g3d.GetDriver2D().DrawBox(int(lpos.x-2),int(self.g3d.GetDriver2D(). GetHeight()-lpos.y-2),4,4,white) ypos = self.g3d.GetDriver2D ().GetHeight () - txth*8 - 1 self.g3d.GetDriver2D ().Write (self.font, 1, ypos, white, -1,str(hbo.hit)+" : "+str(self.current_view)+" : "+str(speed)) ypos += txth self.g3d.GetDriver2D ().Write (self.font, 1, ypos, white, -1,str(int(hbo.isect.x))+" : "+str(int(self.actor_pos.x))) ypos += txth self.g3d.GetDriver2D ().Write (self.font, 1, ypos, white, -1,str(int(hbo.isect.y))+" : "+str(int(self.actor_pos.y))) ypos += txth self.g3d.GetDriver2D ().Write (self.font, 1, ypos, white, -1,str(int(hbo.isect.z))+" : "+str(int(self.actor_pos.z))) ypos += txth self.g3d.GetDriver2D ().Write (self.font, 1, ypos, white, -1,"Isometric demo keys (esc to exit):") ypos += txth self.g3d.GetDriver2D ().Write (self.font, 1, ypos, white, -1," arrow keys: move around") ypos += txth self.g3d.GetDriver2D ().Write (self.font, 1, ypos, white, -1," DEL/END and PGUP/PGDN: rotate/zoom camera") ypos += txth self.g3d.GetDriver2D ().Write (self.font, 1, ypos, white, -1," tab key: cycle through camera presets") def FinishFrame (self): global framecount self.g3d.FinishDraw () self.g3d.Print(None) ########## This method is handled above globally def CameraIsoLookat(self, cam, isoview, lookat): # Let the camera look at the actor. So the camera is set to look at 'actor_pos' # isofactor = 50 # 98.3% isometric (=GetFovAngle()/180.0) # isofactor = 100 # 99.2% isometric (=GetFovAngle()/180.0) isofactor = 200 # 99.6% isometric (=GetFovAngle()/180.0) # set center and lookat cam_trans = cam.GetTransform (); cam_trans.SetOrigin (lookat + isofactor*isoview.camera_offset) cam_trans.LookAt (lookat - cam_trans.GetOrigin (), csVector3 (0, 1, 0)) # set fov more isometric, could be done in initialisation once. cam.SetFOV (self.g3d.GetHeight()*isofactor, self.g3d.GetWidth()) # due to moving the camera so far away, depth buffer accuracy is impaired, repair that by using smaller coordinate system repair_trans = cam.GetTransform() repair_trans.SetT2O(repair_trans.GetT2O()/repair_trans.GetOrigin().Norm()) cam.SetTransform (repair_trans) def SetupIsoView(self,isoview): # clamp if isoview.angle < 0: isoview.angle += 360.0 if isoview.angle > 360: isoview.angle -= 360.0 if isoview.distance < 0.05: isoview.distance = 0.05 if self.views[self.current_view].distance > 5.0: isoview.distance = 5.0 # setup r= csYRotMatrix3(isoview.angle * math.pi / 180.0) isoview.camera_offset = r * isoview.original_offset * isoview.distance ######## This method is handled above globally def LoadMap (self): # First disable the lighting cache. Our map uses stencil lighting. self.engine.SetLightingCacheMode(0) # Set VFS current directory to the level we want to load. VFS=CS_QUERY_REGISTRY (object_reg, iVFS) VFS.ChDir ("/lev/isomap") # Load the level file which is called 'world'. if not self.loader.LoadMapFile ("world"): csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Couldn't load level!") return # Find the starting position in this level. pos=(0, 0, 0) if (self.engine.GetCameraPositions().GetCount() > 0): # There is a valid starting position defined in the level file. self.campos = self.engine.GetCameraPositions().Get (0) self.room = self.engine.GetSectors().FindByName(self.campos.GetSector ()) self.pos = self.campos.GetPosition () else: # We didn't find a valid starting position? So we default to room called 'room' at position (0,0,0). self.room = self.engine.GetSectors().FindByName("room") if not self.room: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Can't find a valid starting position!") return self.view.GetCamera().SetSector (self.room) self.view.GetCamera().GetTransform ().SetOrigin (self.pos) self.ll=self.room.GetLights () self.actor_light=self.engine.CreateLight("actor_light", csVector3(-3,5,0), 5, csColor(1,1,1)) self.ll.Add (self.actor_light) statuelight = self.engine.CreateLight ("statuelight", csVector3 (-4.7, 1.0, 5.5), 4, csColor(2.2,0.5,0.5)) statuelight.CreateNovaHalo (1278, 15, 0.3) self.ll.Add (statuelight) self.plane = self.engine.FindMeshObject ("Plane") return 1 def CreateActor(self): # Load a texture for our sprite. self.txtmgr = self.g3d.GetTextureManager () self.txt = self.loader.LoadTexture ("vedette_fashion","/lib/std/ugly_woman.jpg", CS_TEXTURE_3D, self.txtmgr, 0, 0) if self.txt==0: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,"crystalspace.application.isotest","Error loading texture!") return self.strings = CS_QUERY_REGISTRY_TAG_INTERFACE (object_reg, "crystalspace.shared.stringset", iStringSet) self.shader_mgr = CS_QUERY_REGISTRY (object_reg,iShaderManager) if self.shader_mgr == 0: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,"crystalspace.application.isotest","Couldn't find shader manager! This application requires new renderer!") return self.ambient_shader = self.shader_mgr.GetShader ("ambient") self.light_shader = self.shader_mgr.GetShader ("light") if self.ambient_shader == 0 or self.light_shader == 0: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,"crystalspace.application.isotest","Couldn't find shaders!") return false self.fash_material = self.engine.CreateBaseMaterial (self.txt) self.fash_material.SetShader (self.strings.Request ("ambient"), self.ambient_shader) self.fash_material.SetShader (self.strings.Request ("diffuse"), self.light_shader) self.engine.GetMaterialList ().NewMaterial (self.fash_material, "vedette_fashion") # Load a sprite template from disk. self.imeshfact=self.loader.LoadMeshObjectFactory ("/lev/isomap/vedette.spr") if self.imeshfact == 0: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,"crystalspace.application.isotest","Error loading mesh object factory!") return self.m=csMatrix3(0,0,0,0) self.m.Identity() self.m *= 1.10 # scaling factor self.imeshfact.HardTransform (csReversibleTransform (self.m, csVector3 (0))) # Create the sprite and add it to the engine. self.actor = self.engine.CreateMeshWrapper (self.imeshfact, "MySprite", self.room, csVector3 (-3, 2, 3)) self.actor.GetMovable ().UpdateMove () self.spstate = SCF_QUERY_INTERFACE (self.actor.GetMeshObject (), iGeneralMeshState) ############################### WARNING! iGenMeshSkeletonControlState is undefined! try: self.animcontrol = SCF_QUERY_INTERFACE (self.spstate.GetAnimationControl (), iGenMeshSkeletonControlState) self.animcontrol.StopAll() self.animcontrol.Execute("idle") except: msg=traceback.format_exc() csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", msg) # The following two calls are not needed since CS_ZBUF_USE and Object render priority are the default but they show how you can do this. self.actor.SetZBufMode (CS_ZBUF_USE) self.actor.SetRenderPriority (self.engine.GetObjectRenderPriority ()) return 1 def Initialize(self): self.r=0 self.views=[0,0,0,0] self.object_reg = object_reg; self.current_view=0 self.views[0]=IsoView(csVector3 (-4, 4, -4)) # true isometric perspective. self.views[1]=IsoView(csVector3 (-9, 9, -9)) # zoomed out. self.views[2]=IsoView(csVector3 (4, 3, -4)) # diablo style perspective. self.views[3]=IsoView(csVector3 (0, 4, -4)) # zelda style perspective. self.actor_is_walking = 0; if not csInitializer.RequestPlugins(object_reg,[CS_REQUEST_VFS, CS_REQUEST_OPENGL3D, CS_REQUEST_ENGINE, CS_REQUEST_FONTSERVER, CS_REQUEST_IMAGELOADER, CS_REQUEST_LEVELLOADER, CS_REQUEST_REPORTER, CS_REQUEST_REPORTERLISTENER]): csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Can't initialize plugins!") return if not csInitializer.SetupEventHandler(object_reg, IsoTestEventHandler): csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Can't initialize event handler!") return # Check for commandline help. if csCommandLineHelper.CheckHelp(object_reg): csCommandLineHelper.Help(object_reg) csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Command line help!") return # The virtual clock. self.vc = CS_QUERY_REGISTRY (object_reg, iVirtualClock) if not self.vc: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Can't find the virtual clock!") return # Find the pointer to engine plugin self.engine = CS_QUERY_REGISTRY (object_reg, iEngine) if not self.engine: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "No iEngine plugin!") return self.loader = CS_QUERY_REGISTRY (object_reg, iLoader) if not self.loader: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "No iLoader plugin!") return self.g3d = CS_QUERY_REGISTRY (object_reg, iGraphics3D) if not self.g3d: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "No iGraphics3D plugin!") return self.kbd = CS_QUERY_REGISTRY (object_reg, iKeyboardDriver) if not self.kbd: csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "No iKeyboardDriver plugin!") return # Open the main system. This will open all the previously loaded plug-ins. if not csInitializer.OpenApplication (object_reg): csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.isotest", "Error opening system!") return self.view = csView (self.engine, self.g3d) self.g2d = self.g3d.GetDriver2D () self.view.SetRectangle (0, 0, self.g2d.GetWidth (), self.g2d.GetHeight ()) self.font = self.g3d.GetDriver2D().GetFontServer().LoadFont("/fonts/ttf/Vera.ttf", 10) if not self.font: # fallback self.font = self.g3d.GetDriver2D().GetFontServer().LoadFont(CSFONT_LARGE) if not self.LoadMap(): return if not self.CreateActor(): return self.engine.Prepare() return 1 def Start(self): csDefaultRunLoop (object_reg) ############################## Main framecount=0 object_reg = csInitializer.CreateEnvironment(sys.argv) if object_reg is None: sys.exit() if isotest.Initialize(): isotest.Start () isotest=None csInitializer.DestroyApplication (object_reg) object_reg=None |