bool psEffectObj::Update(csTicks elapsed)
{
    if (!anchor || !anchor->IsReady() || !anchorMesh->GetMovable()->GetSectors()->GetCount()) // wait for anchor to be ready
        return true;

    const static csMatrix3 UP_FIX(1,0,0,   0,0,1,  0,1,0);
    const static csMatrix3 billboardFix = csXRotMatrix3(-3.14f/2.0f);

    iMovable* anchorMovable = anchorMesh->GetMovable();
    iMovable* meshMovable = mesh->GetMovable();

    csVector3 anchorPosition = anchorMovable->GetFullPosition();

    life += elapsed;
    if (life > animLength && killTime <= 0)
    {
        life %= animLength;
        if (!life)
        {
            life += animLength;
        }
    }

    isAlive |= (life >= birth);

    if (isAlive)
    {
        meshMovable->SetSector(anchorMovable->GetSectors()->Get(0));
        meshMovable->SetPosition(anchorPosition);
        if (dir == DT_NONE)
        {
            matBase = anchorMovable->GetFullTransform().GetT2O();
        }
    }

    csMatrix3 matTransform;
    if (keyFrames->GetSize() == 0)
    {
        if (dir == DT_CAMERA)
        {
            // note that this is *very* expensive
            csVector3 camDir = -view->GetCamera()->GetTransform().GetO2TTranslation() 
                             + anchorPosition;
            csReversibleTransform rt;
            rt.LookAt(camDir, csVector3(0.f,1.f,0.f));
            matBase = rt.GetT2O() * UP_FIX;
        }
        else if (dir == DT_BILLBOARD)
        {
            matBase = view->GetCamera()->GetTransform().GetT2O() * billboardFix;
        }

        baseScale = scale;
        matTransform = matBase / baseScale;
    }
    else
    {
        currKeyFrame = FindKeyFrameByTime(life);
        nextKeyFrame = (currKeyFrame + 1) % keyFrames->GetSize();

        // grab and lerp values - expensive
        float lerpfactor = LERP_FACTOR;
        csVector3 lerpRot = LERP_VEC_KEY(KA_ROT,lerpfactor);
        csVector3 lerpSpin = LERP_VEC_KEY(KA_SPIN,lerpfactor);
        csVector3 objOffset = LERP_VEC_KEY(KA_POS,lerpfactor);

        // calculate rotation from lerped values - expensive
        csMatrix3 matRot = csZRotMatrix3(lerpRot.z) * csYRotMatrix3(lerpRot.y) * csXRotMatrix3(lerpRot.x);
        if (dir != DT_CAMERA && dir != DT_BILLBOARD)
        {
            matRot *= matBase;
        }

        // calculate new position
        csVector3 newPos = matRot * csVector3(-objOffset.x, objOffset.y, -objOffset.z);

        if (dir == DT_CAMERA)
        {
            // note that this is *very* expensive - again
            csVector3 camDir = -view->GetCamera()->GetTransform().GetO2TTranslation() 
                             + anchorPosition + newPos;
            csReversibleTransform rt;
            rt.LookAt(camDir, csVector3(sinf(lerpSpin.y),cosf(lerpSpin.y),0.f));
            matBase = rt.GetT2O() * UP_FIX;
            newPos = rt.GetT2O() * newPos;

            // rotate and spin should have no effect on the transform when we want it to face the camera
            matTransform = matBase;
        }
        else if (dir == DT_BILLBOARD)
        {
            matBase = view->GetCamera()->GetTransform().GetT2O() * billboardFix;
            matTransform = matBase;
        }
        else
        {
            matTransform = matRot;
            matTransform *= csZRotMatrix3(lerpSpin.z) * csYRotMatrix3(lerpSpin.y) * csXRotMatrix3(lerpSpin.x);
        }

        // SCALE
        baseScale = LERP_KEY(KA_SCALE,lerpfactor) * scale;
        matTransform /= baseScale;
    
        // adjust position
        meshMovable->SetPosition(anchorPosition+newPos);
    }

    // set new transform
    meshMovable->SetTransform(matTransform);
    meshMovable->UpdateMove();

    if (killTime > 0)
    {
        killTime -= elapsed;
        if (killTime <= 0)
            return false;
    }

    return true;
}
csMatrix3 psEffectObj::BuildRotMatrix(const csVector3 &up) const
{
    csVector3 forward = csVector3(0, 0, 1);
    csVector3 right = up % forward;
    return csMatrix3(right.x, right.y, right.z, up.x, up.y, up.z, forward.x, forward.y, forward.z);
}
bool csShaderProgram::ProgramParamParser::ParseProgramParam (
  iDocumentNode* node, ProgramParam& param, uint types)
{
  const char* type = node->GetAttributeValue ("type");
  if (type == 0)
  {
    synsrv->Report ("crystalspace.graphics3d.shader.common",
      CS_REPORTER_SEVERITY_WARNING,
      node,
      "No %s attribute",
      CS::Quote::Single ("type"));
    return false;
  }

  // Var for static data
  csRef<csShaderVariable> var;
  var.AttachNew (new csShaderVariable (CS::InvalidShaderVarStringID));

  ProgramParamType paramType = ParamInvalid;
  if (strcmp (type, "shadervar") == 0)
  {
    const char* value = node->GetContentsValue();
    if (!value)
    {
      synsrv->Report ("crystalspace.graphics3d.shader.common",
	CS_REPORTER_SEVERITY_WARNING,
	node,
	"Node has no contents");
      return false;
    }
    
    CS::Graphics::ShaderVarNameParser nameParse (value);
    param.name = stringsSvName->Request (nameParse.GetShaderVarName());
    for (size_t n = 0; n < nameParse.GetIndexNum(); n++)
    {
      param.indices.Push (nameParse.GetIndexValue (n));
    }
    param.valid = true;
    return true;
  }
  else if (strcmp (type, "int") == 0)
  {
    paramType = ParamInt;
  }
  else if (strcmp (type, "float") == 0)
  {
    paramType = ParamFloat;
  }
  else if (strcmp (type, "vector2") == 0)
  {
    paramType = ParamVector2;
  }
  else if (strcmp (type, "vector3") == 0)
  {
    paramType = ParamVector3;
  }
  else if (strcmp (type, "vector4") == 0)
  {
    paramType = ParamVector4;
  }
  else if (strcmp (type, "matrix") == 0)
  {
    paramType = ParamMatrix;
  }
  else if (strcmp (type, "transform") == 0)
  {
    paramType = ParamTransform;
  }
  else if ((strcmp (type, "expression") == 0) || (strcmp (type, "expr") == 0))
  {
    // Parse exp and save it
    csRef<iShaderVariableAccessor> acc = synsrv->ParseShaderVarExpr (node);
    var->SetAccessor (acc);
    param.var = var;
    param.valid = true;
    return true;
  }
  else if (strcmp (type, "array") == 0)
  {
    csArray<ProgramParam> allParams;
    ProgramParam tmpParam;
    csRef<iDocumentNodeIterator> it = node->GetNodes ();
    while (it->HasNext ())
    {
      csRef<iDocumentNode> child = it->Next ();
      ParseProgramParam (child, tmpParam, types & 0x3F);
      allParams.Push (tmpParam);
    }

    //Save the params
    var->SetType (csShaderVariable::ARRAY);
    var->SetArraySize (allParams.GetSize ());

    for (uint i = 0; i < allParams.GetSize (); i++)
    {
      var->SetArrayElement (i, allParams[i].var);
    }
    paramType = ParamArray;
  }
  else 
  {
    synsrv->Report ("crystalspace.graphics3d.shader.common",
      CS_REPORTER_SEVERITY_WARNING,
      node,
      "Unknown type %s", CS::Quote::Single (type));
    return false;
  }

  if (!(types & paramType))
  {
    synsrv->Report ("crystalspace.graphics3d.shader.common",
      CS_REPORTER_SEVERITY_WARNING,
      node,
      "Type %s not supported by this parameter", CS::Quote::Single (type));
    return false;
  }

  const uint directValueTypes = ParamInt | ParamFloat | ParamVector2
    | ParamVector3 | ParamVector4 | ParamMatrix | ParamTransform;
  switch (paramType & directValueTypes)
  {
    case ParamInvalid:
      return false;
      break;
    case ParamInt:
      {
	int x = node->GetContentsValueAsInt ();
	var->SetValue (x);
      }
      break;
    case ParamFloat:
      {
	float x = node->GetContentsValueAsFloat ();
	var->SetValue (x);
      }
      break;
    case ParamVector2:
      {
	float x, y;
	const char* value = node->GetContentsValue();
	if (!value)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Node has no contents");
	  return false;
	}
	if (csScanStr (value, "%f,%f", &x, &y) != 2)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Couldn't parse vector2 %s", CS::Quote::Single (value));
	  return false;
	}
	var->SetValue (csVector2 (x,y));
      }
      break;
    case ParamVector3:
      {
	float x, y, z;
	const char* value = node->GetContentsValue();
	if (!value)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Node has no contents");
	  return false;
	}
	if (csScanStr (value, "%f,%f,%f", &x, &y, &z) != 3)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Couldn't parse vector3 %s", CS::Quote::Single (value));
	  return false;
	}
	var->SetValue (csVector3 (x,y,z));
      }
      break;
    case ParamVector4:
      {
	float x, y, z, w;
	const char* value = node->GetContentsValue();
	if (!value)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Node has no contents");
	  return false;
	}
	if (csScanStr (value, "%f,%f,%f,%f", &x, &y, &z, &w) != 4)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Couldn't parse vector4 %s", CS::Quote::Single (value));
	  return false;
	}
	var->SetValue (csVector4 (x,y,z,w));
      }
      break;
    case ParamMatrix:
      {
        csMatrix3 matrix;
	if (!synsrv->ParseMatrix (node, matrix))
	  return false;
        var->SetValue (matrix);
      }
      break;
    case ParamTransform:
      {
        csReversibleTransform t;
        csRef<iDocumentNode> matrix_node = node->GetNode ("matrix");
        if (matrix_node)
        {
          csMatrix3 m;
          if (!synsrv->ParseMatrix (matrix_node, m))
            return false;
          t.SetT2O (m);
        }
        csRef<iDocumentNode> vector_node = node->GetNode ("v");
        if (vector_node)
        {
          csVector3 v;
          if (!synsrv->ParseVector (vector_node, v))
            return false;
          t.SetOrigin (v);
        }
        var->SetValue (t);
      }
      break;
  }
  
  param.var = var;
  param.valid = true;
  return true;
}
Example #4
0
bool csWaterDemo::Initialize ()
{
  if (!csInitializer::SetupConfigManager (object_reg, 
    "/config/waterdemo.cfg"))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR, 
      "crystalspace.application.waterdemo",
      "Failed to initialize config!");
    return false;
  }

  if (!csInitializer::RequestPlugins (object_reg,
  	CS_REQUEST_VFS,
        CS_REQUEST_PLUGIN ("crystalspace.graphics3d.opengl", iGraphics3D),
        CS_REQUEST_ENGINE,
	CS_REQUEST_IMAGELOADER,
	CS_REQUEST_FONTSERVER,
	CS_REQUEST_REPORTER,
	CS_REQUEST_REPORTERLISTENER,
        CS_REQUEST_CONSOLEOUT,
        CS_REQUEST_LEVELLOADER,
 	CS_REQUEST_END))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.waterdemo",
	"Can't initialize plugins!");
    return false;
  }

  FocusGained = csevFocusGained (object_reg);
  FocusLost = csevFocusLost (object_reg);
  Frame = csevFrame (object_reg);
  KeyboardDown = csevKeyboardDown (object_reg);

  if (!csInitializer::SetupEventHandler (object_reg, SimpleEventHandler))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.waterdemo",
	"Can't initialize event handler!");
    return false;
  }

  // Check for commandline help.
  if (csCommandLineHelper::CheckHelp (object_reg))
  {
    csCommandLineHelper::Help (object_reg);
    return false;
  }

  vc = csQueryRegistry<iVirtualClock> (object_reg);
  if (vc == 0)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.waterdemo",
    	"No iVirtualClock plugin!");
    return false;
  }

  vfs = csQueryRegistry<iVFS> (object_reg);
  if (vfs == 0)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.waterdemo",
    	"No iVFS plugin!");
    return false;
  }

  r3d = csQueryRegistry<iGraphics3D> (object_reg);
  if (r3d == 0)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.waterdemo",
    	"No iGraphics3D plugin!");
    return false;
  }

  font = r3d->GetDriver2D ()->GetFontServer()->LoadFont(CSFONT_LARGE);

  engine = csQueryRegistry<iEngine> (object_reg);
  if (engine == 0)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.waterdemo",
    	"No iEngine plugin!");
    return false;
  }

  kbd = csQueryRegistry<iKeyboardDriver> (object_reg);
  if (kbd == 0)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.waterdemo",
    	"No iKeyboardDriver plugin!");
    return false;
  }

  mouse = csQueryRegistry<iMouseDriver> (object_reg);
  if (mouse == 0)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.waterdemo",
    	"No iMouseDriver plugin!");
    return false;
  }

  csRef<iLoader> loader = csQueryRegistry<iLoader> (object_reg);
  if (loader == 0)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.waterdemo",
    	"No iLoader plugin!");
    return false;
  }

  vfs->ChDir ("/tmp");
  
  console = csQueryRegistry<iConsoleOutput> (object_reg);

  // 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.waterdemo",
    	"Error opening system!");
    return false;
  }

  csRef<iSector> room = engine->CreateSector ("room");

  view = csPtr<iView> (new csView (engine, r3d));
  view->GetCamera ()->SetSector (room);
  view->GetCamera ()->GetTransform ().SetOrigin (csVector3 (0, 5, 0));
  view->GetCamera ()->GetTransform ().LookAt (csVector3(5,-5,20), csVector3(0,1,0));
  csRef<iGraphics2D> g2d = r3d->GetDriver2D ();
  view->SetRectangle (0, 0, g2d->GetWidth (), g2d->GetHeight ());

  bool hasAccel;
  if (g2d->PerformExtension ("hardware_accelerated", &hasAccel))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_NOTIFY,
      "crystalspace.application.waterdemo",
      "Hardware acceleration %s.\n",
      hasAccel ? "present" : "not present");
  }
  else
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_NOTIFY,
      "crystalspace.application.waterdemo",
      "Hardware acceleration check not available.\n");
  }

  r3d->GetDriver2D ()->SetMouseCursor( csmcNone );

  csRef<iPluginManager> plugin_mgr (
    csQueryRegistry<iPluginManager> (object_reg));

  csRef<iStringSet> strings = 
    csQueryRegistryTagInterface<iStringSet> 
    (object_reg, "crystalspace.shared.stringset");

  csRef<iShaderVarStringSet> stringsSvName = 
    csQueryRegistryTagInterface<iShaderVarStringSet> 
    (object_reg, "crystalspace.shader.variablenameset");

  //get a custom renderloop
  csRef<iRenderLoop> rl = engine->GetRenderLoopManager ()->Create ();
  
  csRef<iRenderStepType> genType = csLoadPlugin<iRenderStepType> (
    plugin_mgr, "crystalspace.renderloop.step.generic.type");

  csRef<iRenderStepFactory> genFact = genType->NewFactory ();

  csRef<iRenderStep> step;
  csRef<iGenericRenderStep> genStep;

  step = genFact->Create ();
  rl->AddStep (step);
  genStep = scfQueryInterface<iGenericRenderStep> (step);

  genStep->SetShaderType ("general");
  genStep->SetZBufMode (CS_ZBUF_USE);
  genStep->SetZOffset (false);

  engine->GetRenderLoopManager ()->Register ("waterdemoRL", rl);
  engine->SetCurrentDefaultRenderloop (rl);

  // Load in lighting shaders
  csRef<iVFS> vfs (csQueryRegistry<iVFS> (object_reg));
  csRef<iFile> shaderFile = vfs->Open ("/shader/water.xml", VFS_FILE_READ);

  csRef<iDocumentSystem> docsys (
    csQueryRegistry<iDocumentSystem> (object_reg));
  csRef<iDocument> shaderDoc = docsys->CreateDocument ();
  shaderDoc->Parse (shaderFile, true);

  csRef<iShader> shader;
  csRef<iShaderManager> shmgr (csQueryRegistry<iShaderManager> (object_reg));
  csRef<iShaderCompiler> shcom (shmgr->GetCompiler ("XMLShader"));
  csRef<iLoaderContext> ldr_context = engine->CreateLoaderContext ();
  shader = shcom->CompileShader (ldr_context,
      shaderDoc->GetRoot ()->GetNode ("shader"));

  // setup the mesh 
  csRef<iMeshObjectType> gType = csLoadPluginCheck<iMeshObjectType> (
  	plugin_mgr, "crystalspace.mesh.object.genmesh");
  
  if (!gType)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
        "crystalspace.application.waterdemo",
        "Error loading genmesh baseobject!");
    return false;
  }

  
  gFact = gType->NewFactory ();
  csRef<iMeshFactoryWrapper> fw = engine->CreateMeshFactory (gFact, "waterFactory");
  gFactState = scfQueryInterface<iGeneralFactoryState> (gFact);

  gMesh = gFact->NewInstance ();
  gMeshState = scfQueryInterface<iGeneralMeshState> (gMesh);
  gMeshState->SetShadowCasting (false);
  gMeshState->SetShadowReceiving (false);

  //setup a wrapper too
  gMeshW = engine->CreateMeshWrapper (gMesh, "water", room);
  csMatrix3 m;
  m.Identity ();
  gMeshW->GetMovable ()->SetTransform (m);
  gMeshW->GetMovable ()->SetPosition (csVector3(0,-5,0));
  gMeshW->GetMovable ()->UpdateMove ();
  
  //setup a material
  csRef<iMaterial> mat = engine->CreateBaseMaterial (0);

  mat->SetShader (strings->Request ("general"), shader);

  csRef<iMaterialWrapper> matW = engine->GetMaterialList ()->NewMaterial (mat,
  	"waterMaterial");


  csRef<csImageCubeMapMaker> cubeMaker;
  cubeMaker.AttachNew (new csImageCubeMapMaker ());

  csRef<iImage> img = loader->LoadImage ("/lib/cubemap/cubemap_rt.jpg");
  cubeMaker->SetSubImage (0, img);
  img = loader->LoadImage ("/lib/cubemap/cubemap_lf.jpg");
  cubeMaker->SetSubImage (1, img);

  img = loader->LoadImage ("/lib/cubemap/cubemap_up.jpg");
  cubeMaker->SetSubImage (2, img);
  img = loader->LoadImage ("/lib/cubemap/cubemap_dn.jpg");
  cubeMaker->SetSubImage (3, img);

  img = loader->LoadImage ("/lib/cubemap/cubemap_fr.jpg");
  cubeMaker->SetSubImage (4, img);
  img = loader->LoadImage ("/lib/cubemap/cubemap_bk.jpg");
  cubeMaker->SetSubImage (5, img);


  csRef<iTextureHandle> tex = r3d->GetTextureManager ()->RegisterTexture (
    cubeMaker, CS_TEXTURE_3D | CS_TEXTURE_CLAMP | CS_TEXTURE_NOMIPMAPS);

  csRef<csShaderVariable> attvar (csPtr<csShaderVariable> (
    new csShaderVariable (stringsSvName->Request ("tex diffuse"))));
  attvar->SetValue (tex);
  mat->AddVariable (attvar);  


  gMesh->SetMaterialWrapper (matW);
  
  Width = Height = 64;

  water = new float[Width*Height];
  water1 = new float[Width*Height];
  water2 = new float[Width*Height];

  memset(water,0,Width*Height*sizeof(float));
  memset(water1,0,Width*Height*sizeof(float));
  memset(water2,0,Width*Height*sizeof(float));

  WaveSpeed = 0.3f;
  WaveLife = 0.1f;
  GridSize = 0.25f;
  TimeDelta = 0.12f;


  //setup the mesh
  gFactState->SetVertexCount (Width*Height);
  gFactState->SetTriangleCount (2*((Width-1)*(Height-1)));

  //setup ibuf
  int x, z, cnt=0,idx;
  csTriangle *ibuf=gFactState->GetTriangles ();
  for(x=0;x<(Height-1);x++)
  {
    for(z=0;z<(Width-1);z++)
    {
      idx = 2*(x*(Width-1)+z);
      ibuf[idx].a = x*Width+z;
      ibuf[idx].b = x*Width+z+1;
      ibuf[idx].c = (x+1)*Width+z;
      idx++;
      ibuf[idx].a = x*Width+z+1;
      ibuf[idx].b = (x+1)*Width+(z+1);
      ibuf[idx].c = (x+1)*Width+z;
    }
  }

  //setup our vbuf
  csVector3 *vbuf = gFactState->GetVertices ();
  cnt=0;
  for(x=0;x<Height;x++)
  {
    for(z=0;z<Width;z++)
    {
      idx = x*Width+z;
      vbuf[idx].x = x*GridSize;
      vbuf[idx].y = water[idx];
      vbuf[idx].z = z*GridSize;
    }
  }

  //setup texture
  csVector2 *tbuf = gFactState->GetTexels ();
  for(x=0;x<Height;x++)
  {
    for(z=0;z<Width;z++)
    {
      idx = x*Width+z;
      tbuf[idx].x = (float)x/(float)Height;
      tbuf[idx].y = (float)z/(float)Width;
    }
  }

  lastSimTime = nextSimTime = 0.0f;

  gFactState->Invalidate ();

  engine->Prepare ();

  console->SetVisible (false);
  hasfocus = true;
  int w = r3d->GetDriver2D ()->GetWidth()/2;
  int h = r3d->GetDriver2D ()->GetHeight()/2;
  r3d->GetDriver2D ()->SetMousePosition (w, h);

  printer.AttachNew (new FramePrinter (object_reg));

  return true;
}
Example #5
0
bool FrankieScene::CreateAvatar ()
{
  printf ("Loading Frankie...\n");

  // Load animesh factory
  csLoadResult rc = hairTest->loader->Load ("/lib/frankie/frankie.xml");
  if (!rc.success)
    return hairTest->ReportError ("Can't load Frankie library file!");

  // Load some fur
  rc = hairTest->loader->Load ("/lib/hairtest/frankie_furmesh.xml");
  if (!rc.success)
    return hairTest->ReportError ("Can't load frankie furmesh library!");

  csRef<iMeshWrapper> frankieFurmeshObject = 
    hairTest->engine->FindMeshObject("frankie_furmesh_object");
  if (!frankieFurmeshObject)
    return hairTest->ReportError ("Can't find fur mesh object!");

  csRef<iMeshFactoryWrapper> meshfact =
    hairTest->engine->FindMeshFactory ("franky_frankie");
  if (!meshfact)
    return hairTest->ReportError ("Can't find Frankie's mesh factory!");

  animeshFactory = scfQueryInterface<CS::Mesh::iAnimatedMeshFactory>
    (meshfact->GetMeshObjectFactory ());
  if (!animeshFactory)
    return hairTest->ReportError ("Can't find Frankie's animesh factory!");

  // Load bodymesh (animesh's physical properties)
  rc = hairTest->loader->Load ("/lib/frankie/skelfrankie_body");
  if (!rc.success)
    return hairTest->ReportError ("Can't load Frankie's body mesh file!");

  csRef<CS::Animation::iBodyManager> bodyManager =
    csQueryRegistry<CS::Animation::iBodyManager> (hairTest->GetObjectRegistry ());
  csRef<CS::Animation::iBodySkeleton> bodySkeleton = bodyManager->FindBodySkeleton ("frankie_body");
  if (!bodySkeleton)
    return hairTest->ReportError ("Can't find Frankie's body mesh description!");

  // Create a new animation tree. The structure of the tree is:
  //   + ragdoll controller node (root node - only if physics are enabled)
  //     + 'LookAt' controller node
  //       + 'speed' controller node
  //         + animation nodes for all speeds
  csRef<CS::Animation::iSkeletonAnimPacketFactory> animPacketFactory =
    animeshFactory->GetSkeletonFactory ()->GetAnimationPacket ();

  // Create the 'random' node
  csRef<CS::Animation::iSkeletonRandomNodeFactory> randomNodeFactory =
    animPacketFactory->CreateRandomNode ("random");
  randomNodeFactory->SetAutomaticSwitch (true);

  // Create the 'idle' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> idleNodeFactory =
    animPacketFactory->CreateAnimationNode ("idle");
  idleNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("Frankie_Idle1"));

  // Create the 'walk_slow' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> walkSlowNodeFactory =
    animPacketFactory->CreateAnimationNode ("walk_slow");
  walkSlowNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("Frankie_WalkSlow"));

  // Create the 'walk' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> walkNodeFactory =
    animPacketFactory->CreateAnimationNode ("walk");
  walkNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("Frankie_Walk"));

  // Create the 'walk_fast' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> walkFastNodeFactory =
    animPacketFactory->CreateAnimationNode ("walk_fast");
  walkFastNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("Frankie_WalkFast"));

  // Create the 'footing' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> footingNodeFactory =
    animPacketFactory->CreateAnimationNode ("footing");
  footingNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("Frankie_Runs"));

  // Create the 'run_slow' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> runSlowNodeFactory =
    animPacketFactory->CreateAnimationNode ("run_slow");
  runSlowNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("Frankie_RunSlow"));

  // Create the 'run' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> runNodeFactory =
    animPacketFactory->CreateAnimationNode ("run");
  runNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("Frankie_Run"));

  // Create the 'run_fast' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> runFastNodeFactory =
    animPacketFactory->CreateAnimationNode ("run_fast");
  runFastNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("Frankie_RunFaster"));

  // Create the 'run_jump' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> runJumpNodeFactory =
    animPacketFactory->CreateAnimationNode ("run_jump");
  runJumpNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("Frankie_RunFast2Jump"));

  idleNodeFactory->SetAutomaticReset (true);
  walkSlowNodeFactory->SetAutomaticReset (true);
  walkNodeFactory->SetAutomaticReset (true);
  walkFastNodeFactory->SetAutomaticReset (true);
  footingNodeFactory->SetAutomaticReset (true);
  runSlowNodeFactory->SetAutomaticReset (true);
  runNodeFactory->SetAutomaticReset (true);
  runFastNodeFactory->SetAutomaticReset (true);
  runJumpNodeFactory->SetAutomaticReset (true);

  idleNodeFactory->SetAutomaticStop (false);
  walkSlowNodeFactory->SetAutomaticStop (false);
  walkNodeFactory->SetAutomaticStop (false);
  walkFastNodeFactory->SetAutomaticStop (false);
  footingNodeFactory->SetAutomaticStop (false);
  runSlowNodeFactory->SetAutomaticStop (false);
  runNodeFactory->SetAutomaticStop (false);
  runFastNodeFactory->SetAutomaticStop (false);
  runJumpNodeFactory->SetAutomaticStop (false);

  randomNodeFactory->AddNode (idleNodeFactory, 1.0f);
  randomNodeFactory->AddNode (walkSlowNodeFactory, 1.0f);
  randomNodeFactory->AddNode (walkNodeFactory, 1.0f);
  randomNodeFactory->AddNode (walkFastNodeFactory, 1.0f);
  randomNodeFactory->AddNode (footingNodeFactory, 1.0f);
  randomNodeFactory->AddNode (runSlowNodeFactory, 1.0f);
  randomNodeFactory->AddNode (runNodeFactory, 1.0f);
  randomNodeFactory->AddNode (runFastNodeFactory, 1.0f);
  randomNodeFactory->AddNode (runJumpNodeFactory, 1.0f);

  if (hairTest->physicsEnabled)
  {
    // Create the ragdoll controller
    csRef<CS::Animation::iSkeletonRagdollNodeFactory> ragdollNodeFactory =
      hairTest->ragdollManager->CreateAnimNodeFactory ("ragdoll");
    animPacketFactory->SetAnimationRoot (ragdollNodeFactory);
    ragdollNodeFactory->SetBodySkeleton (bodySkeleton);
    ragdollNodeFactory->SetChildNode (randomNodeFactory);

    // Create a bone chain for the whole body and add it to the ragdoll controller.
    // The chain will be in kinematic mode when Frankie is alive, and in dynamic state
    // when Frankie has been killed.
    bodyChain = bodySkeleton->CreateBodyChain
      ("body_chain", animeshFactory->GetSkeletonFactory ()->FindBone ("Frankie_Main"));
    bodyChain->AddSubChain (animeshFactory->GetSkeletonFactory ()->FindBone ("CTRL_Pelvis"));
    bodyChain->AddSubChain (animeshFactory->GetSkeletonFactory ()->FindBone ("CTRL_Head"));
    ragdollNodeFactory->AddBodyChain (bodyChain, CS::Animation::STATE_KINEMATIC);

    // Create a bone chain for the tail of Frankie and add it to the ragdoll controller.
    // The chain will be in kinematic mode most of the time, and in dynamic mode when the
    // user ask for it with the 'f' key or when Frankie has been killed.
    tailChain = bodySkeleton->CreateBodyChain
      ("tail_chain", animeshFactory->GetSkeletonFactory ()->FindBone ("Tail_1"));
    tailChain->AddSubChain (animeshFactory->GetSkeletonFactory ()->FindBone ("Tail_8"));
    ragdollNodeFactory->AddBodyChain (tailChain, CS::Animation::STATE_KINEMATIC);
  }

  else
    animPacketFactory->SetAnimationRoot (randomNodeFactory);

  // Create the animated mesh
  csRef<iMeshWrapper> avatarMesh =
    hairTest->engine->CreateMeshWrapper (meshfact, "Frankie",
					   hairTest->room, csVector3 (0.0f));
  animesh = scfQueryInterface<CS::Mesh::iAnimatedMesh> (avatarMesh->GetMeshObject ());

  // When the animated mesh is created, the animation nodes are created too.
  // We can therefore set them up now.
  CS::Animation::iSkeletonAnimNode* rootNode =
    animesh->GetSkeleton ()->GetAnimationPacket ()->GetAnimationRoot ();

  // Setup of the ragdoll controller
  if (hairTest->physicsEnabled)
  {
    ragdollNode =
      scfQueryInterface<CS::Animation::iSkeletonRagdollNode> (rootNode->FindNode ("ragdoll"));

    // Start the ragdoll animation node in order to have the rigid bodies created
    ragdollNode->SetDynamicSystem (hairTest->dynamicSystem);
    ragdollNode->Play ();
  }

  // Load fur material
  rc = hairTest-> loader ->Load ("/lib/hairtest/fur_material_frankie.xml");
  if (!rc.success)
    hairTest->ReportError("Can't load Fur library file!");

  // Load material shader
  csRef<iMaterialWrapper> materialWrapper = 
    hairTest->engine->FindMaterial("kajiya_and_kay_frankie");
  if (!materialWrapper)
    hairTest->ReportError("Can't find fur material!");

  // Surface properties
  animesh->GetSubMesh(0)->SetMaterial(materialWrapper);

  // Get plugin manager
  csRef<iPluginManager> plugmgr = 
    csQueryRegistry<iPluginManager> (hairTest->GetObjectRegistry ());
  if (!plugmgr)
    return hairTest->ReportError("Failed to locate Plugin Manager!");

  // Load furMesh
  csRef<CS::Mesh::iFurMeshType> furMeshType = 
    csQueryRegistry<CS::Mesh::iFurMeshType> (hairTest->GetObjectRegistry ());
  if (!furMeshType)
    return hairTest->ReportError("Failed to locate CS::Mesh::iFurMeshType plugin!");

  csRef<iRigidBody> mainBody = ragdollNode->GetBoneRigidBody
    (animeshFactory->GetSkeletonFactory ()->FindBone ("Frankie_Main"));

  // Load animationPhysicsControl
  animationPhysicsControl = scfQueryInterface<CS::Animation::iFurAnimatedMeshControl>
      (furMeshType->CreateFurAnimatedMeshControl("frankie_fur_animation"));

  animationPhysicsControl->SetAnimatedMesh(animesh);

  furPhysicsControl = scfQueryInterface<CS::Animation::iFurPhysicsControl>
    (furMeshType->CreateFurPhysicsControl("frankie_fur_physics"));

  furPhysicsControl->SetBulletDynamicSystem(hairTest->bulletDynamicSystem);
  furPhysicsControl->SetRigidBody(mainBody);
  furPhysicsControl->SetAnimatedMesh(animesh);

  // Create hairMeshProperties
  csRef<CS::Mesh::iFurMeshMaterialProperties> hairMeshProperties = 
    furMeshType->CreateFurMeshBasicProperties("frankie_kajiya_and_kay");

  hairMeshProperties->SetMaterial(materialWrapper->GetMaterial());

  iSector* sector = hairTest->engine->FindSector("room");

  if (!sector)
    return hairTest->ReportError("Could not find default room!");

  frankieFurmeshObject->GetMovable()->SetSector(sector);
  frankieFurmeshObject->GetMovable()->UpdateMove();

  csRef<iMeshObject> imo = frankieFurmeshObject->GetMeshObject();

  // Get reference to the iFurMesh interface
  furMesh = scfQueryInterface<CS::Mesh::iFurMesh>(imo);

  furMesh->SetFurMeshProperties(hairMeshProperties);

  furMesh->SetAnimatedMesh(animesh);
  furMesh->SetMeshFactory(animeshFactory);
  furMesh->SetMeshFactorySubMesh(animesh -> GetSubMesh(0)->GetFactorySubMesh());
  furMesh->GenerateGeometry(hairTest->view, hairTest->room);

  furMesh->SetAnimationControl(animationPhysicsControl);
  furMesh->StartAnimationControl();

  furMesh->SetGuideLOD(0);
  furMesh->SetStrandLOD(1);

  // Reset the scene so as to put the parameters of the animation nodes in a default state
  ResetScene ();

  return true;
}
Example #6
0
bool KrystalScene::CreateAvatar ()
{
  printf ("Loading Krystal...\n");

  // Load animesh factory
  csLoadResult rc = hairTest->loader->Load ("/lib/krystal/krystal.xml");
  if (!rc.success)
    return hairTest->ReportError ("Can't load Krystal library file!");

  csRef<iMeshFactoryWrapper> meshfact =
    hairTest->engine->FindMeshFactory ("krystal");
  if (!meshfact)
    return hairTest->ReportError ("Can't find Krystal's mesh factory!");

  animeshFactory = scfQueryInterface<CS::Mesh::iAnimatedMeshFactory>
    (meshfact->GetMeshObjectFactory ());
  if (!animeshFactory)
    return hairTest->ReportError ("Can't find Krystal's animesh factory!");

  // Load bodymesh (animesh's physical properties)
  rc = hairTest->loader->Load ("/lib/krystal/skelkrystal_body");
  if (!rc.success)
    return hairTest->ReportError ("Can't load Krystal's body mesh file!");

  csRef<CS::Animation::iBodyManager> bodyManager =
    csQueryRegistry<CS::Animation::iBodyManager> (hairTest->GetObjectRegistry ());
  csRef<CS::Animation::iBodySkeleton> bodySkeleton = 
    bodyManager->FindBodySkeleton ("krystal_body");
  if (!bodySkeleton)
    return hairTest->ReportError ("Can't find Krystal's body mesh description!");

  // Load some fur
  rc = hairTest->loader->Load ("/lib/hairtest/krystal_furmesh.xml");
  if (!rc.success)
    return hairTest->ReportError ("Can't load krystal furmesh library!");

  csRef<iMeshWrapper> krystalFurmeshObject = 
    hairTest->engine->FindMeshObject ("krystal_furmesh_object");
  if (!krystalFurmeshObject)
    return hairTest->ReportError ("Can't find fur mesh object!");

  // Get plugin manager
  csRef<iPluginManager> plugmgr = 
    csQueryRegistry<iPluginManager> (hairTest->GetObjectRegistry ());
  if (!plugmgr)
    return hairTest->ReportError("Failed to locate Plugin Manager!");

  // Find the fur mesh plugin
  csRef<CS::Mesh::iFurMeshType> furMeshType = 
    csQueryRegistry<CS::Mesh::iFurMeshType> (hairTest->GetObjectRegistry ());
  if (!furMeshType)
    return hairTest->ReportError("Failed to locate CS::Mesh::iFurMeshType plugin!");

  // Create a new animation tree. The structure of the tree is:
  //   + ragdoll controller node (root node - only if physics are enabled)
  //     + Random node
  //       + idle animation nodes
  csRef<CS::Animation::iSkeletonAnimPacketFactory> animPacketFactory =
    animeshFactory->GetSkeletonFactory ()->GetAnimationPacket ();

  // Create the 'random' node
  csRef<CS::Animation::iSkeletonRandomNodeFactory> randomNodeFactory =
    animPacketFactory->CreateRandomNode ("random");
  randomNodeFactory->SetAutomaticSwitch (true);

  // Create the 'idle01' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> idle01NodeFactory =
    animPacketFactory->CreateAnimationNode ("idle01");
  idle01NodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("idle01"));

  // Create the 'idle02' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> idle02NodeFactory =
    animPacketFactory->CreateAnimationNode ("idle02");
  idle02NodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("idle02"));

  // Create the 'idle03' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> idle03NodeFactory =
    animPacketFactory->CreateAnimationNode ("idle03");
  idle03NodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("idle03"));

  // Create the 'idle04' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> idle04NodeFactory =
    animPacketFactory->CreateAnimationNode ("idle04");
  idle04NodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("idle04"));

  // Create the 'idle05' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> idle05NodeFactory =
    animPacketFactory->CreateAnimationNode ("idle05");
  idle05NodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("idle05"));

  // Create the 'idle06' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> idle06NodeFactory =
    animPacketFactory->CreateAnimationNode ("idle06");
  idle06NodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("idle06"));

  // Create the 'stand' animation node
  csRef<CS::Animation::iSkeletonAnimationNodeFactory> standNodeFactory =
    animPacketFactory->CreateAnimationNode ("stand");
  standNodeFactory->SetAnimation
    (animPacketFactory->FindAnimation ("stand"));

  idle01NodeFactory->SetAutomaticReset (true);
  idle02NodeFactory->SetAutomaticReset (true);
  idle03NodeFactory->SetAutomaticReset (true);
  idle04NodeFactory->SetAutomaticReset (true);
  idle05NodeFactory->SetAutomaticReset (true);
  idle06NodeFactory->SetAutomaticReset (true);
  standNodeFactory->SetAutomaticReset (true);

  idle01NodeFactory->SetAutomaticStop (false);
  idle02NodeFactory->SetAutomaticStop (false);
  idle03NodeFactory->SetAutomaticStop (false);
  idle04NodeFactory->SetAutomaticStop (false);
  idle05NodeFactory->SetAutomaticStop (false);
  idle06NodeFactory->SetAutomaticStop (false);
  standNodeFactory->SetAutomaticStop (false);
  
  randomNodeFactory->AddNode (idle01NodeFactory, 1.0f);
  randomNodeFactory->AddNode (idle02NodeFactory, 1.0f);
//   randomNodeFactory->AddNode (idle03NodeFactory, 1.0f);
  randomNodeFactory->AddNode (idle04NodeFactory, 1.0f);
//   randomNodeFactory->AddNode (idle05NodeFactory, 1.0f);
  randomNodeFactory->AddNode (idle06NodeFactory, 1.0f);
  randomNodeFactory->AddNode (standNodeFactory, 1.0f);
  
  if (hairTest->physicsEnabled)
  {
    // Create the ragdoll controller
    csRef<CS::Animation::iSkeletonRagdollNodeFactory> ragdollNodeFactory =
      hairTest->ragdollManager->CreateAnimNodeFactory ("ragdoll");
    animPacketFactory->SetAnimationRoot (ragdollNodeFactory);
    ragdollNodeFactory->SetBodySkeleton (bodySkeleton);
    ragdollNodeFactory->SetChildNode (randomNodeFactory);

    // Create bone chain for whole body and add it to the ragdoll controller. The chain
    // will be in kinematic mode when Krystal is alive, and in dynamic state when
    // Krystal has been killed.
    bodyChain = bodySkeleton->CreateBodyChain
      ("body_chain", animeshFactory->GetSkeletonFactory ()->FindBone ("Hips"));
    bodyChain->AddSubChain (animeshFactory->GetSkeletonFactory ()->FindBone ("Head"));
    bodyChain->AddSubChain (animeshFactory->GetSkeletonFactory ()->FindBone ("RightFoot"));
    bodyChain->AddSubChain (animeshFactory->GetSkeletonFactory ()->FindBone ("RightHand"));
    bodyChain->AddSubChain (animeshFactory->GetSkeletonFactory ()->FindBone ("LeftFoot"));
    bodyChain->AddSubChain (animeshFactory->GetSkeletonFactory ()->FindBone ("LeftHand"));
    ragdollNodeFactory->AddBodyChain (bodyChain, CS::Animation::STATE_KINEMATIC);

  }

  else
    animPacketFactory->SetAnimationRoot (randomNodeFactory);

  // Create the animated mesh
  csRef<iMeshWrapper> avatarMesh =
    hairTest->engine->CreateMeshWrapper (meshfact, "krystal",
    hairTest->room, csVector3 (0.0f));
  animesh = scfQueryInterface<CS::Mesh::iAnimatedMesh> (avatarMesh->GetMeshObject ());

  // When the animated mesh is created, the animation nodes are created too.
  // We can therefore set them up now.
  CS::Animation::iSkeletonAnimNode* rootNode =
    animesh->GetSkeleton ()->GetAnimationPacket ()->GetAnimationRoot ();

  // Setup of the ragdoll controller
  if (hairTest->physicsEnabled)
  {
    ragdollNode =
      scfQueryInterface<CS::Animation::iSkeletonRagdollNode> (rootNode->FindNode ("ragdoll"));

    // Start the ragdoll animation node in order to have the rigid bodies created
    ragdollNode->SetDynamicSystem (hairTest->dynamicSystem);
    ragdollNode->Play ();
  }

  csRef<iRigidBody> headBody = ragdollNode->GetBoneRigidBody
    (animeshFactory->GetSkeletonFactory ()->FindBone ("Head"));

  // Load the fur material
  rc = hairTest-> loader ->Load ("/lib/hairtest/fur_material_krystal.xml");
  if (!rc.success)
    hairTest->ReportError ("Can't load Fur library file!");

  // Load the Marschner shader
  csRef<iMaterialWrapper> materialWrapper = 
    hairTest->engine->FindMaterial ("marschner_material");
  if (!materialWrapper)
    hairTest->ReportError ("Can't find marschner material!");

  // Create the fur properties for the hairs
  csRef<CS::Mesh::iFurMeshMaterialProperties> hairMeshProperties = 
    furMeshType->CreateHairMeshMarschnerProperties ("krystal_marschner");
  hairMeshProperties->SetMaterial(materialWrapper->GetMaterial ());
  animesh->GetSubMesh (1)->SetMaterial (materialWrapper);

  // Create the two possible animation control's. We'll switch between than at the user request.
  hairPhysicsControl = scfQueryInterface<CS::Animation::iFurPhysicsControl>
    (furMeshType->CreateFurPhysicsControl ("krystal_hairs_physics"));
  animationPhysicsControl = scfQueryInterface<CS::Animation::iFurAnimatedMeshControl>
    (furMeshType->CreateFurAnimatedMeshControl ("krystal_hairs_animation"));

  hairPhysicsControl->SetBulletDynamicSystem (hairTest->bulletDynamicSystem);
  hairPhysicsControl->SetRigidBody (headBody);
//   hairPhysicsControl->SetAnimatedMesh(animesh);

  animationPhysicsControl->SetAnimatedMesh (animesh);

  iSector* sector = hairTest->engine->FindSector("room");

  if (!sector)
    return hairTest->ReportError("Could not find default room!");

  krystalFurmeshObject->GetMovable()->SetSector(sector);
  krystalFurmeshObject->GetMovable()->UpdateMove();

  csRef<iMeshObject> imo = krystalFurmeshObject->GetMeshObject();

  // Get reference to the iFurMesh interface
  furMesh = scfQueryInterface<CS::Mesh::iFurMesh> (imo);

  csRef<CS::Mesh::iFurMeshState> ifms = 
    scfQueryInterface<CS::Mesh::iFurMeshState> (furMesh);

  animationPhysicsControl->SetDisplacement (ifms->GetDisplacement ());

  furMesh->SetFurMeshProperties (hairMeshProperties);

  furMesh->SetAnimatedMesh (animesh);
  furMesh->SetMeshFactory (animeshFactory);
  furMesh->SetMeshFactorySubMesh (animesh->GetSubMesh (2)->GetFactorySubMesh ());
  furMesh->GenerateGeometry (hairTest->view, hairTest->room);

  furMesh->SetAnimationControl (hairPhysicsControl);
  furMesh->StartAnimationControl ();

  furMesh->SetGuideLOD (0);
  furMesh->SetStrandLOD (1);
  furMesh->SetControlPointsLOD (0.0f);

  // Reset the scene so as to put the parameters of the animation nodes in a default state
  ResetScene ();

  return true;
}
Example #7
0
const csVector3 psLinearMovement::GetFullPosition () const
{
  // user will get a warning and a nothing if theres no mesh
  if (!mesh)  return csVector3 ();
  return mesh->GetMovable ()->GetFullPosition ();
}
Example #8
0
// Do the actual move
int psLinearMovement::MoveV (float delta)
{
  if (velBody < SMALL_EPSILON && velWorld < SMALL_EPSILON && (!colldet || colldet->IsOnGround ()))
    return PS_MOVE_DONTMOVE;  // didn't move anywhere

  int ret = PS_MOVE_SUCCEED;
  iMovable* movable = mesh->GetMovable ();
  if (movable->GetSectors ()->GetCount () <= 0)
    return PS_MOVE_DONTMOVE;  // didn't move anywhere

  csMatrix3 mat;

  // To test collision detection we use absolute position and transformation
  // (this is relevant if we are anchored). Later on we will correct that.
  csReversibleTransform fulltransf = movable->GetFullTransform ();
  mat = fulltransf.GetT2O ();
  delta *= speed;

  csVector3 worldVel (fulltransf.This2OtherRelative (velBody) + velWorld);
  csVector3 oldpos (fulltransf.GetOrigin ());
  csVector3 newpos (worldVel*delta + oldpos);
  csVector3 bufpos = newpos;

  // Check for collisions and adjust position
  if (colldet)
  {
    if (!colldet->AdjustForCollisions (oldpos, newpos, worldVel,
    	delta, movable))
    {
      ret = PS_MOVE_FAIL;
      newpos = oldpos;
    }
    else
    {
      // check if we collided
      if ((newpos - bufpos).Norm () > 0.000001f)
      {
        ret = PS_MOVE_PARTIAL;
      }
    }
  }

  csVector3 origNewpos = newpos;
  bool mirror = false;

  // Update position to account for portals
  iSector* new_sector = movable->GetSectors ()->Get (0);
  iSector* old_sector = new_sector;

  // @@@ Jorrit: had to do this add!
  // We need to measure slightly above the position of the actor or else
  // we won't really cross a portal.
  float height5 = (bottomSize.y + topSize.y) / 10.0f;
  newpos.y += height5;
  csMatrix3 id;
  csOrthoTransform transform_oldpos (id, oldpos +
  	csVector3 (0.0f, height5, 0.0f));

  new_sector = new_sector->FollowSegment (transform_oldpos, newpos, mirror,
  	PS_LINMOVE_FOLLOW_ONLY_PORTALS);
  newpos.y -= height5;
  if (new_sector != old_sector)
    movable->SetSector (new_sector);

  portalDisplaced += newpos - origNewpos;
  if(!IsOnGround ())
  {
	  //printf("Applying gravity: velY: %g.\n", velWorld.y);
    // gravity! move down!
    velWorld.y  -= gravity * delta;
    /*
     * Terminal velocity
     *   ((120 miles/hour  / 3600 second/hour) * 5280 feet/mile)
     *   / 3.28 feet/meter = 53.65 m/s
     */
    // The body velocity is figured in here too.
    if (velWorld.y < 0)
    {

      if (fulltransf.This2OtherRelative (velBody).y
      	+ velWorld.y < -(ABS_MAX_FREEFALL_VELOCITY))
      	velWorld.y = -(ABS_MAX_FREEFALL_VELOCITY)
      	- fulltransf.This2OtherRelative (velBody).y;
      if (velWorld.y > 0){
	      // printf("Reset other y %g\n", fulltransf.This2OtherRelative (velBody).y);
        velWorld.y = 0;
      }
    }  
  }
  else
  {
    if(velWorld.y < 0)
    {
      velWorld.y = 0;
    }

    if (hugGround)
      HugGround (newpos, new_sector);
  }

  // Move to the new position. If we have an anchor we have to convert
  // the new position from absolute to relative.
  movable->GetTransform ().SetOrigin (newpos);
  movable->GetTransform ().SetT2O(
  	movable->GetTransform ().GetT2O () * transform_oldpos.GetT2O ());

  if (colldet)
  {
    // Part 4: Add us to all nearby sectors.
    mesh->PlaceMesh ();
  }

  movable->UpdateMove ();

  return ret;
}
Example #9
0
void AvatarTest::Frame ()
{
  // First get elapsed time from the virtual clock.
  csTicks elapsed_time = vc->GetElapsedTicks ();

  // Now rotate the camera according to keyboard state
  const float speed = elapsed_time / 1000.0f;

  // Compute camera and animesh position
  iCamera* c = view->GetCamera ();
  csVector3 cameraPosition = c->GetTransform ().GetOrigin ();
  csVector3 avatarPosition = avatarScene->GetCameraTarget ();

  // Move camera
  if (kbd->GetKeyState (CSKEY_SHIFT))
  {
    // If the user is holding down shift, the Up/Down arrow keys will cause
    // the camera to go forwards and backwards (forward only allowed if camera 
    // not too close). Left/Right arrows work also when shift is hold.
    if (kbd->GetKeyState (CSKEY_UP)
	&& (cameraPosition - avatarPosition).Norm () > 0.5f)
      c->Move (CS_VEC_FORWARD * 4 * speed);
    if (kbd->GetKeyState (CSKEY_DOWN))
      c->Move (CS_VEC_BACKWARD * 4 * speed);
    if (kbd->GetKeyState (CSKEY_RIGHT))
      c->Move (CS_VEC_RIGHT * 4 * speed);
    if (kbd->GetKeyState (CSKEY_LEFT))
      c->Move (CS_VEC_LEFT * 4 * speed);
  }
  else
  {
    // Left and right arrows cause the camera to strafe on the X axis; up and 
    // down arrows cause the camera to strafe on the Y axis
    if (kbd->GetKeyState (CSKEY_RIGHT))
      c->Move (CS_VEC_RIGHT * 4 * speed);
    if (kbd->GetKeyState (CSKEY_LEFT))
      c->Move (CS_VEC_LEFT * 4 * speed);

    // Avoid gimbal lock of camera
    cameraPosition.Normalize ();
    float cameraDot = cameraPosition * csVector3 (0.0f, 1.0f, 0.0f);
    if (kbd->GetKeyState (CSKEY_UP)
	&& cameraDot < 0.98f)
      c->Move (CS_VEC_UP * 4 * speed);
    if (kbd->GetKeyState (CSKEY_DOWN)
	&& cameraDot > -0.98f)
      c->Move (CS_VEC_DOWN * 4 * speed);
  }

  // Make the camera look at the animesh
  c->GetTransform ().LookAt (avatarPosition - c->GetTransform ().GetOrigin (),
			     csVector3 (0.0f, 1.0f, 0.0f) );

  // Step the dynamic simulation (we slow down artificially the simulation in
  // order to achieve a 'slow motion' effect)
  if (physicsEnabled)
    dynamics->Step (speed / 4.0f);

  // Update the avatar
  avatarScene->Frame ();

  // 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 ();

  // Write FPS and other info
  if(!g3d->BeginDraw (CSDRAW_2DGRAPHICS)) return;
  avatarScene->DisplayKeys ();
}