May 22, 2012, 05:06:03 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Please report any bugs or issues that you might be encountering with the Beta in the Support System so that we can better keep track of any oustanding issues that may come up.

GameCore Support System
 
   Home   Help Search Login Register  
Pages: [1] 2 3
  Print  
Author Topic: Controlling Sub Meshes  (Read 2410 times)
Squat
Hero Member
*****
Posts: 592


View Profile
« on: September 08, 2008, 09:10:14 PM »

I need help getting control over submeshes within an object. I have a door that's built of several components, including a frame and all the hinges and stuff. I want to have this one neat package I can put in all my doorjams. I can't gain any control, I really don't know what to do.

Door1.OPR
Quote
OPRP

LoadObject Door1.FBX


ControllerType Scripted
ControllerSetting ScriptFile Door.gsl

ControllerInputCenter -10.5 2.5 -5
ControllerInputBoxSize 5 5 5

EditObject Frame
ObjectName Frame
//~ ObjectMaxDepth 200

EditObject WallHinge
ObjectName WallHinge
ObjectParent Frame
//~ ObjectMaxDepth 20

EditObject Hinge
ObjectName Hinge
ObjectParent WallHinge
//~ ObjectMaxDepth 20

EditObject Door
ObjectName Door
ObjectParent Hinge
//~ ObjectMaxDepth 200

EditObject Fittings
ObjectName Fittings
ObjectParent Door
//~ ObjectMaxDepth 20

EditObject Latch
ObjectName Latch
ObjectParent Fittings
//~ ObjectMaxDepth 20

EditObject Knobs
ObjectName Knobs
ObjectParent Fittings
//~ ObjectMaxDepth 20

EditObject Catch
ObjectName Catch
ObjectParent Frame
//~ ObjectMaxDepth 20

Door.gsl
Quote
ObjectMesh@ Door;

void DynamicsAdvance( Object@ object, float seconds)
{
   Vector rotation;
   ObjectMesh@ doorj;

   @doorj = Door;

   rotation = doorj.GetRotationEuler();
   rotation.x += clamp( 1,0,0);
   doorj.SetRotationEuler( rotation);

}

I've tried a few other radical approaches that all ended in worse. This gets me null pointer access. My goal right now is to merely enter the world and see just the door mesh by itself spinning around constantly without inputs. Any help would get me moving. Thanks guys.
Logged
hikmayan
Full Member
***
Posts: 231



View Profile
« Reply #1 on: September 08, 2008, 10:29:55 PM »

Yes!...the door situation at times can be a pain.
I am hoping Mike is planning all door types template where user get to pick the styling doors needed for a specific project.I am talking about standard door functions (rotate,swing 90deg,elevator type;y= dist. from origin to elev.pt1,2,3,4....).This template one day,will be nice when implemented and will eleminate all door issues.
Logged

You have to be in it.....to win it!
gekido
Guest
« Reply #2 on: September 09, 2008, 12:16:57 AM »

basically you need to get a handle to the sub-mesh itself, like so:

Code:
ObjectMesh@ mesh = object.GetMesh( "MeshName");

then you can call whatever functions that you want on it:

http://www2.gamecore.ca/docs/scripting-reference/classes/ObjectMesh

The default door script that we are implementing is purely for the door itself - it doesn't include things like sub-meshes or anything advanced like that - basically the door model is centered around the 'hinge'.  This makes it very easy to replace / customize the mesh and keep the basic door behavior the same.

By adding the sub-meshes etc it makes it too complicated to serve as a default / example script and won't likely be something that we implement ourselves.  There's nothing stopping you from adding this kind of thing as a custom script if that's what you want to do though ;}
Logged
Ransom
Full Member
***
Posts: 132



View Profile
« Reply #3 on: September 09, 2008, 01:29:05 AM »

Yep.  You need to point from the object to the mesh.

This will grab it and spin it (assuming 'Door' is a proper name of one of the object's meshes)

Quote
float spin = 0;

void DynamicsAdvance( Object@ object, float seconds)
{

object.GetMesh("Door").SetRotationEuler( Vector(0, spin, 0));

spin += 10;

}
Logged
Ransom
Full Member
***
Posts: 132



View Profile
« Reply #4 on: September 09, 2008, 01:40:01 AM »

And this would also work, if you wanted a handle that could be used later...

Quote
   
ObjectMesh@ MyMesh = object.GetMesh("Door");
MyMesh.SetRotationEuler( Vector(0, spin, 0));
Logged
Squat
Hero Member
*****
Posts: 592


View Profile
« Reply #5 on: September 09, 2008, 02:21:43 AM »

Thank you gentlemen, I'll try those things.

My plans for this script will actually be a little specific to my own game so the full thing won't exactly work for all, but I'll post my progress and anything useful I learn.

I'm extremely grateful that a lot of you guys are really helpful.
Logged
pixel_legolas
Hero Member
*****
Posts: 786


View Profile
« Reply #6 on: September 09, 2008, 03:56:54 AM »

Have you looked at the old script for opening door like in PREY? 3 door parts that go each direction when opening?
Logged
Squat
Hero Member
*****
Posts: 592


View Profile
« Reply #7 on: September 09, 2008, 11:05:32 AM »

I might end up with a few more questions, but I now have the basic control over the submesh. Thank you guys a lot for the very prompt replies. It get's me moving right when I get up, which is nice. Ransom, your code worked right out of the box.
Logged
Ransom
Full Member
***
Posts: 132



View Profile
« Reply #8 on: September 09, 2008, 12:28:43 PM »

Hey, glad to help.  I learn a lot from others as well.  The more we share the more apt others are to share and the that's all the more we grow Smiley
Logged
hikmayan
Full Member
***
Posts: 231



View Profile
« Reply #9 on: September 09, 2008, 01:01:34 PM »

Yup!...sharing is love from the heart....not just love.This is the type of love that opens the door so everyone learn something.
Logged

You have to be in it.....to win it!
Squat
Hero Member
*****
Posts: 592


View Profile
« Reply #10 on: September 09, 2008, 05:17:25 PM »

Ok, so I'm back with my next question, sorry lol.

I can't get any luck with a collision object on the door. I can't seem to use the renderobject as it's always closed and doesn't get updated with the visible mesh. I've added the line you guys gave me for adding objects to update it. I think...

I tried adding a box and making the parent object be "Door" and the door actually disappears. Then if I check "follow animation", the door comes back and opens/closes, but the collision isn't there at all.

I'm a bit lost, I figure I need to get a direct handle on the actual collision object? Can a collision object be messed with independantly? Could I merely add calls to rotate it aswell as the door mesh?

Would it work for me to add a separate box with its own bounding-box collision to follow my door mesh and use script instead to update that?

I'm actually unsure even of how to get more control over .FBX aswell. How would I export one .FBX file and distinguis collision and occlusion objects? I know how to do LOD's because that's just hiding meshes at depth, but I need that other access too please.

Here's my funky script right now. Btw, it's set to only open the door if you're the king of all the cheese pieces in the room, which I set to 1 because I'm a lazy gamer.

Door.gsl
Quote
float spin = 0;
float maxopen = -85;
Vector vspin;
bool open = false;

String VictoryController = "cheesebit_global";

//
void Initialize( Object@ object)
{
   vspin.x = 0;
   vspin.y = 0;
   Vector rotation = object.GetMesh("Hinge").GetRotationEuler();
   object.UpdateCollisionObjectPositions();
   print(rotation);
}

//
bool HandleEvent( Object@ object, const String& in event, GameEventParams@ params)
{
   Object@ victoryobject = GetGameManager().GetWorld().GetObject("cheesebit_global"); //get handle to victory state
   bool victory = victoryobject.GetControllerSettingBool("WON");
   
   if(victory == true)
   {
      if(event == "EnterProximity")
         {
            print("IN");
            //~ if(victory == false)
             //tip message
         }
         
      if(event == "Input")
         {
            open = true;
            
         }
         else
         {
            open = false;
            
         }
         
      
         return true;
   }
   else
   {
   GetGameManager().ShowTextPlain("YOU HAVEN'T CLEARED THE ROOM!", 2);
   return false;
   }
}

//
void DynamicsAdvance( Object@ object, float seconds)
{
   object.GetMesh("Hinge").SetRotationEuler( vspin);
   object.UpdateCollisionObjectPositions();
      if(open == true)
      {
         if(vspin.z<=maxopen)
         {
            vspin.z = maxopen;
         }
         else
         {
            vspin.z -= 1;
         }
      }
      else
      {
         if(vspin.z>= 0)
         {
            vspin.z=0;
         }
         else
         {   
         vspin.z += 0.1;
         }
      }
}

Logged
Ransom
Full Member
***
Posts: 132



View Profile
« Reply #11 on: September 10, 2008, 12:39:48 AM »

How to set up multiple collisions in the same object (and a joint between)...

Its all done in the OPR.  Here is an example.
Quote
OPRP

LoadObject Object.fbx


AddCollision Body     # This is your base collision, center it around the main body of the object like on a biped it would most likely be the torso. DO NOT use CollisionAttachObject on this - will cause issues

CollisionType Box
CollisionBox -0.25 1.05 -0.25 0.25 1.55 0.25 # position of collision box
CollisionMass 100

AddCollision RBicep #Name this anything you want
CollisionAttachObject RUpperArm  #This is the actual name of the submesh as exported from your modeling program
CollisionType Box
CollisionBox -0.77 1.38 -0.08 -0.25 1.54 0.07
CollisionMass 100
CollisionBouncyness 0
CollisionFriction 1

AddJoint RShoulder    #you can name this whatever you want
JointType Hinge2
JointCollisionObjects RBicep Body
JointAttachObject RShoulder    #This is the actual name of the joint (or submesh) as exported from your modeling program
JointAttachAxis X
JointAttachAxis2 Z
JointRotationLimits -60 60
JointRotationLimits2 -60 60
JointSoftness 0.0001
JointSoftness2 0.0001
JointDrag 100
JointDrag2 100
JointBouncyness 0
JointBouncyness2 0
JointErrorParameter 0.8
JointErrorParameter2 0.8
JointSuspensionErrorParameter 0.8
JointSuspensionSoftness 0.00001

Now.  To access collision objects from a script, you need to do this...
Quote
//assuming you've named the collision object 'Body' in your OPR...

// creates a pointer to the collision object
ObjectCollide@ BodyCollsion = object.GetCollideObject("Body");

Logged
Ransom
Full Member
***
Posts: 132



View Profile
« Reply #12 on: September 10, 2008, 12:58:55 AM »

Note:  Use the object viewer to set up your collision boxes.  If you check "Collision Geom" it will show you the box and as you edit/save the OPR, the box will update its position.  Makes set up much easier.

Also, the position for the collision box is set up like [min x] [min y] [min z] [max x] [max y] [max z]
If min is ever greater than max, you will get errors.
Logged
pixel_legolas
Hero Member
*****
Posts: 786


View Profile
« Reply #13 on: September 10, 2008, 10:11:41 AM »

I take no credits for this script. It's from old BV forum. Don't remember who made it Smiley

Quote
New day - new sample  Here is sample of self working door entity. Opennig phase is depend on distance between player and entity position, like in game PREY

door_entity.opr
Code:
Code:
OPRP

LoadObject door_outline.lwo
ObjectName AutomaticDoor

LoadObject door_left.lwo
ObjectPosition -1.5 3 0
ObjectName DoorLeftPart

LoadObject door_middle.lwo
ObjectPosition 0 3 0
ObjectName DoorMiddlePart

LoadObject door_right.lwo
ObjectPosition 1.5 3 0
ObjectName DoorRightPart

ControllerInputRadius 5

ControllerType Scripted
ControllerSetting ScriptFile door_entity.gsl

ControllerSetting EntityClass door_entity

# Door on startup set Close or Open
ControllerSetting DoorStatus Close

door_entity.gsl
Code:


Code:
String DoorStatus;
Vector DoorL_pos;
Vector DoorM_pos;
Vector DoorR_pos;
Vector DoorL_rot;
Vector DoorR_rot;
Vector PlayerPos;
bool DoorInactive;

void Initialize( Object@ object)
{

DoorStatus = object.GetControllerSettingString("DoorStatus");

DoorM_pos = object.GetMesh("DoorMiddlePart").GetPosition();

DoorL_rot = object.GetMesh("DoorLeftPart").GetRotationEuler();
DoorR_rot = object.GetMesh("DoorRightPart").GetRotationEuler();

if (DoorStatus=="Open")
{

object.GetMesh("DoorLeftPart").SetRotationEuler(Vector(0,0,-45));
object.GetMesh("DoorMiddlePart").SetPosition(Vector(DoorM_pos.x,DoorM_pos.y+3,DoorM_pos.z));
object.GetMesh("DoorRightPart").SetRotationEuler(Vector(0,0,45));
DoorInactive = true;
}

if (DoorStatus=="Close")
{
DoorInactive = false;

}

}

float CheckPlayerDistance(Object@ object)
{

Object@ obj = GetGameManager().GetWorld().GetObject("Player");
Vector PlayerPos = obj.GetPosition();
Vector Direction =?  object.GetPosition() - PlayerPos;
float Length = Direction.GetLength();


return Length;
}

void DynamicsAdvance( Object@ object, float seconds)
{

if (!DoorInactive)
{
float Length = CheckPlayerDistance(object);
if (Length<6)
{

float angle_step = 25/6;

object.GetMesh("DoorLeftPart").SetRotationEuler(Vector(0,0,-(25-angle_step*Length)));
object.GetMesh("DoorMiddlePart").SetPosition(Vector(DoorM_pos.x,DoorM_pos.y+(3 - (abs(Length)/2)),DoorM_pos.z));
object.GetMesh("DoorRightPart").SetRotationEuler(Vector(0,0,25-angle_step*Length));

}
else
{
object.GetMesh("DoorLeftPart").SetRotationEuler(Vector(0,0,0));
object.GetMesh("DoorMiddlePart").SetPosition(DoorM_pos);
object.GetMesh("DoorRightPart").SetRotationEuler(Vector(0,0,0));

}
}

}
Logged
Squat
Hero Member
*****
Posts: 592


View Profile
« Reply #14 on: September 10, 2008, 12:52:48 PM »

Thanks again gentlemen, this should keep me moving ahead.
Logged
Pages: [1] 2 3
  Print  
 
Jump to:  

 
Powered by MySQL Powered by PHP bluBlur Skin © 2006, hbSkins
Powered by SMF 1.1.14 | SMF © 2006-2011, Simple Machines LLC
Valid XHTML 1.0! Valid CSS!