Crystal Space
Welcome, Guest. Please login or register.
April 18, 2014, 07:47:57 pm

Login with username, password and session length
Search:     Advanced search
8990 Posts in 2037 Topics by 7596 Members
Latest Member: Sporny4
* Home Help Search Login Register
+  Crystal Space
|-+  Crystal Space Development
| |-+  Game Content Creation
| | |-+  Loading CEL entities into a non-CEL level.
« previous next »
Pages: [1] Print
Author Topic: Loading CEL entities into a non-CEL level.  (Read 4954 times)
Panch
Jr. Member
**
Posts: 80


View Profile Email
« on: February 02, 2008, 06:33:48 am »

Is this possible? I'd like to be able to load standard CEL entities into a standard CS level; i guess without the use of pcZoneManager. I guess I need to know if I'm going to use CEL entities does the code need to be all CEL, or can it be a mix of say a CS walktest level with CEL entities (monster, treasure chests, doors, etc ...) within it? if so, how can I spawn a CEL entity within a normal CS level?

Thanks Smiley
Logged
Panch
Jr. Member
**
Posts: 80


View Profile Email
« Reply #1 on: February 04, 2008, 03:13:16 pm »

Well it compiles ok now, but it crashes on trying to set the behaviour to the entity.

Create entity:
Code:
...
// Load Muck library
if(!loader->LoadLibraryFile  ("/lib/Muck/library"))
ReportError("Error loading 'Muck' library!");

csRef<iMeshFactoryWrapper> imeshfact_muck = engine->FindMeshFactory  ("spr3dSphere");
if(!imeshfact_muck)
{
csReport(object_reg, CS_REPORTER_SEVERITY_ERROR,
"crystalspace.Phage",
"Error loading mesh object factory!");
ReportError("Error loading mesh factory '%s' !");

return false;
}

csVector3 rot = (0,0,0);
csVector3 mot = (0,0,0);

csRef<iMeshWrapper> muck1 = (engine->CreateMeshWrapper (imeshfact_muck, "Muck A", room, csVector3(1,1,5)));
muck1->GetMovable ()->UpdateMove ();
muck1->SetZBufMode (CS_ZBUF_USE);
muck1->SetRenderPriority (engine->GetObjectRenderPriority ());

collider_muck1.SetCollideSystem (cdsys);
collider_muck1.SetEngine (engine);
csVector3 legs1 (.2f, .3f, .2f);
csVector3 body1 (.2f, 1.2f, .2f);
csVector3 shift1 (0, -2, 0);
collider_muck1.InitializeColliders (muck1,
legs1, body1, shift1);
//collider_muck1.EnableHitMeshes(true);
collider_muck1.SetOnGround(false);

muck_state1 = scfQueryInterface<iSprite3DState> (
muck1->GetMeshObject());

muck_state1->SetAction("Idle", true, 1.0f);
csVector3 muck1_rotate;
muck1_rotate = muck1->GetMovable()->GetFullPosition();
csXRotMatrix3 x_muck1_rot (4.7f);
muck1->GetMovable ()->Transform(x_muck1_rot);

collider_muck1.Move (((unsigned)time(0) / 1000.0f), 1.0f,
    (CS_VEC_FORWARD * 1.0f), rot);

// Attempt to create an entity from a mesh, per CEL manual:
iCelEntity* entity = pl->FindAttachedEntity (muck1->QueryObject ());
..

Which runs ok but when this runs to set the behaviour:
Code:
...
bl->CreateBehaviour(entity, "box_behave");
...

behave.cpp crashes on

Code:
iCelBehaviour* BehaviourLayer::CreateBehaviour (iCelEntity* entity,
const char* name)
{
  iCelBehaviour* behave = 0;

...
  if (behave)
  {
// Crashes on this line below
    entity->SetBehaviour (behave);
    // There is now a reference in the entity. We destroy
    // our own reference here.
    behave->DecRef ();
 

and the entity has a memory address of 0, so while it is initialized it seems like it isn't properly created, or fully created? Not sure how else to get a CEL entity from a standard CS mesh as the way above is how its described in the manual.

Thanks!
Logged
Panch
Jr. Member
**
Posts: 80


View Profile Email
« Reply #2 on: February 05, 2008, 12:00:01 am »

OK, well this works:
Code:
muck1_entity = pl->CreateEntity("Muck_ent", bl, "box_behave",
"pcobject.mesh",
//"pcmove.linear",
//"pcmove.actor.standard",
CEL_PROPCLASS_END);


pl->AttachEntity(muck1->QueryObject(), muck1_entity);
bl->CreateBehaviour(muck1_entity, "box_behave");
return true;

But for some reason, the entities don't seem to be sending messages. I'm trying to interact with a mesh but when I click on it, nothing happens like it does in the walktut tutorial. When are entity messages sent?

Thanks!
Logged
rvhaasen
Jr. Member
**
Posts: 62


View Profile
« Reply #3 on: February 11, 2008, 04:04:50 pm »

I think that in order to receive the mesh selection event you also have to register the "meshselect" property class:
 
Code:
muck1_entity = pl->CreateEntity("Muck_ent", bl, "box_behave",
"pcobject.mesh",
                         "pcobject.mesh.select"
//"pcmove.linear",
//"pcmove.actor.standard",
CEL_PROPCLASS_END);
the entity should now receive the selection event
Code:
bool BehaviourBox::SendMessage (csStringID msg_id,
iCelPropertyClass* pc,
  celData& ret, iCelParameterBlock* params, va_list arg)
{
  if (msg_id == id_pcmeshsel_down)
  {
    // do something...
    return true;
  }

  return BehaviourCommon::SendMessage (msg_id, pc, ret, params, arg);
}

Using CEL in combination with "straight CS" works great, in this way you can have "best of both worlds", using CEL if you can find something there that does what you want, and using CS if you cannot do it with CEL. You can also consider defining a new property-class for the "feature". Even in that case it is not a bad idea to first code it in CS, and define a property-class for it later only if it is "general enough" so you (and others) can use the feature in a convenient way...
 At the moment i only use CEL for the actor, in this way i get the nice camera modes, animation control and collistion detection for "free".
Logged
Panch
Jr. Member
**
Posts: 80


View Profile Email
« Reply #4 on: February 12, 2008, 12:52:36 am »

Wow this sounds great! Thanks Smiley I was able to get the monster to load properly but because my hero isn't a CEL entity it didn't receive any messages.

How are you creating the actor entity without a pre-existing level entity?

Thanks so much!
Logged
rvhaasen
Jr. Member
**
Posts: 62


View Profile
« Reply #5 on: February 12, 2008, 02:21:44 pm »

How are you creating the actor entity without a pre-existing level entity?
i do create the level entity first:
Code:
  pl = csQueryRegistry<iCelPlLayer> (object_reg);
  bl.AttachNew (new BehaviourLayer(pl));

  // We also need to register it to the object registry.
  if (!GetObjectRegistry()->Register (bl, "iCelBlLayer"))
    return ReportError ("Can't register our behaviour layer!");

  pl->RegisterBehaviourLayer (bl);

  // etc

  // Load all used propertyclass factorries
  if (!pl->LoadPropertyClassFactory ("cel.pcfactory.zonemanager"))
    return ReportError ("Error loading pczonemanager factory!");
  // etc.
  level_entity = pl->CreateEntity ("level", bl, "level_behave",
    "pczonemanager",
    CEL_PROPCLASS_END);
  if (!level_entity)
    return ReportError ("Error creating level entity!");

  // Now get the iPcZoneManager interface so we can setup the level.
 
  csRef<iPcZoneManager> zonemgr = CEL_QUERY_PROPCLASS_ENT (level_entity,
  iPcZoneManager);
  iCelZone* zone = zonemgr->CreateZone ("main");
  iCelRegion* region = zonemgr->CreateRegion ("main");
  zone->LinkRegion (region);

  iCelMapFile* mapfile = region->CreateMapFile ();
  mapfile->SetPath ("/this/level");
  mapfile->SetFile ("world");   
Logged
Panch
Jr. Member
**
Posts: 80


View Profile Email
« Reply #6 on: February 12, 2008, 05:02:32 pm »

Quote
i do create the level entity first:

Oh, well thank you for all the help so far Smiley I was able to get the monster entity to load but it wasn't sending any messages. I don't know if I didn't read the CEL doc's well enough or if it isn't explained in them. I'm trying to get around having to load a level entity or I need to figure out how to switch between levels using level entities. I don't know if the level entity causes entities to send messages or a player entity or the combination of both. Both when I load up a CEL entity into a CS level it doesn't send any messages.

Basically, in CS I load my player to a csColliderActor and initialize it to a camera, in this way when I use iLoader to load another map file, I just get the camera position in that level and set the camera at that point and I'm in the new level.

In CEL, I don't know how to unload the level entity, unload the monster entites, reload the level entity and set the CEL camera to the new map that is loaded.

Have any ideas on either lol ?

And thanks again Smiley
Logged
rvhaasen
Jr. Member
**
Posts: 62


View Profile
« Reply #7 on: February 13, 2008, 10:49:54 am »

i used the cel-example "walktut" as reference for my integration with CS.
As far as i understand, it (and the event distribution) works as follows:
There must be 1 object with the iCelBlLayer interface that is responsible for creating the behaviours of the entities that you want to create (also with the iCelBLLayer interface). Therefore, this class only implements the "CreateBehaviour" and the "GetName" methods. This object is registered at the physical layer:
Code:
  pl->RegisterBehaviourLayer (bl);

From now on, when a entity creation is requested, the creation of the "corresponding" behaviour is defered to the iCelBlLayer object that was registered above.
If one of the specified property-classes generates events of any kind, these will effectively be send to the behaviour associated to this entity. For example, if a pccommand property class is specified, keybord events will be send to the behaviours SendMessage method. The behaviour object has to do something with it, for example updating the position of the mesh.

So i don't think that the level-entity has some special purpose in relation to the event mechanism.
The physical layer should be able to send any "subscribed" events to the behaviours.
I would suggest to set a breakpoint at the "CreateBehaviour" method, to be sure that the correct behaviour will be created when you request a new entity.
Another breakpoint at the SendMessage method of the behaviour-object to check if events arrive. 

Until now i haven't switched levels at runtime, so i don't know if this works when using level entities, it is interesting to try. As far as i remember, switching levels still is problematic even in plain cs (things with unreleased renderloops of the previous levels or something like that). I don't know what the status is of these issues...
Logged
Panch
Jr. Member
**
Posts: 80


View Profile Email
« Reply #8 on: February 13, 2008, 02:01:03 pm »

Hmm OK, that makes more sense. I'll look through it later a bit and try to break into it. I think I'm actually pretty close to switching levels in CEL and I have it down pat for CS, I would be happy to post the code if you'd like.

Thanks for the help Smiley

EDIT - most of the code is actually here: http://www.crystalspace3d.org/forum/index.php/topic,1577.0.html

The only addition is to add

Code:
  view->GetCamera ()->SetSector (room);
  view->GetCamera ()->GetTransform ().SetOrigin (pos);

In the function that loads the second map so the camera is updated.
« Last Edit: February 13, 2008, 02:08:15 pm by Panch » Logged
Pages: [1] Print 
« previous next »
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 9.297 seconds with 16 queries.