Ejemplo n.º 1
0
//===========================================================================
// Demo particle system (fountain).
//===========================================================================
static void add_particles_fountain (WalkTest* Sys, iSector* sector, char* matname, int num,
	const csVector3& origin)
{
  iEngine* engine = Sys->Engine;

  // First check if the material exists.
  iMaterialWrapper* mat = engine->GetMaterialList ()->FindByName (matname);
  if (!mat)
  {
    Sys->Report (CS_REPORTER_SEVERITY_NOTIFY, "Can't find material '%s'!", matname);
    return;
  }

  csRef<iMeshFactoryWrapper> mfw = engine->CreateMeshFactory (
      "crystalspace.mesh.object.particles", "fountain");
  if (!mfw) return;

  csRef<iMeshWrapper> exp = engine->CreateMeshWrapper (mfw, "custom fountain",
	sector, origin);

  exp->SetZBufMode(CS_ZBUF_TEST);
  exp->GetMeshObject()->SetMixMode (CS_FX_ADD);
  exp->GetMeshObject()->SetMaterialWrapper (mat);

  csRef<iParticleBuiltinEmitterFactory> emit_factory = 
      csLoadPluginCheck<iParticleBuiltinEmitterFactory> (
        Sys->object_reg, "crystalspace.mesh.object.particles.emitter", false);
  csRef<iParticleBuiltinEffectorFactory> eff_factory = 
      csLoadPluginCheck<iParticleBuiltinEffectorFactory> (
        Sys->object_reg, "crystalspace.mesh.object.particles.effector", false);

  csRef<iParticleBuiltinEmitterCone> conemit = emit_factory->CreateCone ();
  float velocity = 3.0f;
  float seconds_to_live = 1.5f;
  conemit->SetExtent (csVector3 (0, 0.5f, 0));
  conemit->SetConeAngle (0.3f);
  conemit->SetParticlePlacement (CS_PARTICLE_BUILTIN_VOLUME);
  conemit->SetEmissionRate (float (num) / seconds_to_live);
  conemit->SetInitialMass (8.0f, 10.0f);
  conemit->SetInitialTTL (seconds_to_live, seconds_to_live);
  conemit->SetInitialVelocity (csVector3 (0, velocity, 0), csVector3 (0));

  csRef<iParticleBuiltinEffectorLinColor> lincol = eff_factory->
    CreateLinColor ();
  lincol->AddColor (csColor4 (0.25f, 0.35f, 0.55f, 1), seconds_to_live);

  csRef<iParticleBuiltinEffectorForce> force = eff_factory->
    CreateForce ();
  force->SetAcceleration (csVector3 (0.0f, -3.0f, 0.0f));

  csRef<iParticleSystem> partstate =
  	scfQueryInterface<iParticleSystem> (exp->GetMeshObject ());
  partstate->SetParticleSize (csVector2 (0.1f, 0.1f));
  partstate->AddEmitter (conemit);
  partstate->AddEffector (lincol);
  partstate->AddEffector (force);
}
void SimpleStaticLighter::ShineLights (iMeshWrapper* mesh, iEngine* engine, int maxlights,
    ShadowType shadow_type)
{
  iMovable* movable = mesh->GetMovable ();
  if (!movable->InSector ()) return;	// No movable, do nothing.

  const csBox3& world_box = mesh->GetWorldBoundingBox ();
  CS_ALLOC_STACK_ARRAY (iLight*, lights, maxlights);
  size_t num = engine->GetNearbyLights (movable->GetSectors ()->Get (0),
	world_box, lights, maxlights);

  if (num == 0)
  {
    ConstantColor (mesh, csColor4 (0, 0, 0, 0));
    return;
  }
  if (num == 1)
  {
    ShineLight (mesh, lights[0], shadow_type);
    return;
  }

  iMeshFactoryWrapper* meshfact = mesh->GetFactory ();
  if (!meshfact) return;
  csRef<iGeneralFactoryState> fact_state = scfQueryInterface<
    iGeneralFactoryState> (meshfact->GetMeshObjectFactory ());
  if (!fact_state) return;	// Not a mesh we recognize.
  size_t count = fact_state->GetVertexCount ();
  csRef<iRenderBuffer> rbuf = csRenderBuffer::CreateRenderBuffer (
      count, CS_BUF_STATIC, CS_BUFCOMP_FLOAT, 4);
  CS_ALLOC_STACK_ARRAY (csColor4, colors, count);

  size_t l;
  for (l = 0 ; l < num ; l++)
  {
    iLight* light = lights[l];
    CalculateLighting (mesh, fact_state, light, shadow_type, colors, l == 0);
  }

  rbuf->CopyInto (colors, count);
  csRef<iGeneralMeshState> state = scfQueryInterface<iGeneralMeshState> (mesh->GetMeshObject ());
  state->AddRenderBuffer ("static color", rbuf);
  
  mesh->GetFlags().Set (CS_ENTITY_STATICLIT);
}
void SimpleStaticLighter::CalculateLighting (iMeshWrapper* mesh,
    iGeneralFactoryState* fact_state, iLight* light,
    ShadowType shadow_type, csColor4* colors, bool init)
{
  size_t count = fact_state->GetVertexCount ();
  size_t i;

  csVector3 center = light->GetMovable ()->GetFullTransform ().GetOrigin ();
  iSector* light_sector = light->GetMovable ()->GetSectors ()->Get (0);
  csReversibleTransform mesh_trans = mesh->GetMovable ()->GetFullTransform ();

  if (shadow_type == CS_SHADOW_CENTER)
  {
    csSectorHitBeamResult rc = light_sector->HitBeamPortals (center,
	mesh_trans.GetOrigin ());
    if (rc.mesh != 0 && rc.mesh != mesh)
    {
      // Shadow.
      if (init)
        for (i = 0 ; i < count ; i++)
          colors[i] = csColor4 (0, 0, 0, 0);
      return;
    }
  }
  else if (shadow_type == CS_SHADOW_BOUNDINGBOX)
  {
    const csBox3& world_box = mesh->GetWorldBoundingBox ();
    bool shadowed = true;
    for (int j = 0 ; shadowed && j < 8 ; j++)
    {
      csSectorHitBeamResult rc = light_sector->HitBeamPortals (center,
        world_box.GetCorner (j));
      if (rc.mesh == 0 || rc.mesh == mesh) shadowed = false;
    }
    if (shadowed)
    {
      // Shadow.
      if (init)
        for (i = 0 ; i < count ; i++)
          colors[i] = csColor4 (0, 0, 0, 0);
      return;
    }
  }


  // Shaders multiply by 2. So we need to divide by 2 here.
  csColor color = 0.5f * light->GetColor ();
  float sqcutoff = light->GetCutoffDistance ();
  sqcutoff *= sqcutoff;

  csVector3* verts = fact_state->GetVertices ();
  csVector3* normals = fact_state->GetNormals ();

  if (shadow_type != CS_SHADOW_FULL)
  {
    // Transform light to object space here since we don't have to do
    // full accurate shadows anyway.
    center = mesh_trans.Other2This (center);
    for (i = 0 ; i < count ; i++)
    {
      csVector3 relpos = center-verts[i];
      float dist = relpos * relpos;
      bool dark = init;
      if (dist < sqcutoff)
      {
        dist = sqrt (dist);
        float bright = light->GetBrightnessAtDistance (dist);
        bright *= (normals[i] * relpos) / relpos.Norm ();
        if (bright > SMALL_EPSILON)
        {
	  if (init)
            colors[i] = color * bright;
	  else
	    colors[i] += color * bright;
          colors[i].Clamp (1.0, 1.0, 1.0);
	  dark = false;
        }
      }
      if (dark) colors[i].Set (0, 0, 0, 0);
    }
  }
  else
  {
    // With full shadows we need world space coordinates to be
    // able to check the shadow beams.
    bool mesh_trans_identity = mesh_trans.IsIdentity ();
    for (i = 0 ; i < count ; i++)
    {
      csVector3 vworld;
      if (mesh_trans_identity)
	vworld = verts[i];
      else
	vworld = mesh_trans.This2Other (verts[i]);
      csVector3 relpos = center-vworld;
      float dist = relpos * relpos;
      bool dark = init;
      if (dist < sqcutoff)
      {
        dist = sqrt (dist);
        float bright = light->GetBrightnessAtDistance (dist);
        bright *= (normals[i] * relpos) / relpos.Norm ();
        if (bright > SMALL_EPSILON)
        {
	  csSectorHitBeamResult rc = light_sector->HitBeamPortals (center, vworld);
	  if (rc.mesh == 0 || rc.mesh == mesh)
	  {
	    if (init)
              colors[i] = color * bright;
	    else
              colors[i] += color * bright;
            colors[i].Clamp (1.0, 1.0, 1.0);
	    dark = false;
	  }
	}
      }
      if (dark) colors[i].Set (0, 0, 0, 0);
    }
  }
}
Ejemplo n.º 4
0
//===========================================================================
// Demo particle system (rain).
//===========================================================================
static void add_particles_rain (WalkTest* Sys, iSector* sector, char* matname, int num,
    float speed, bool do_camera)
{
  iEngine* engine = Sys->Engine;
  // First check if the material exists.
  iMaterialWrapper* mat = engine->GetMaterialList ()->FindByName (matname);
  if (!mat)
  {
    Sys->Report (CS_REPORTER_SEVERITY_NOTIFY,
    	"Can't find material '%s' in memory!", matname);
    return;
  }

  csBox3 bbox;
  if (do_camera)
    bbox.Set (-5, -5, -5, 5, 5, 5);
  else
    sector->CalculateSectorBBox (bbox, true);

  csRef<iMeshFactoryWrapper> mfw = engine->CreateMeshFactory (
      "crystalspace.mesh.object.particles", "rain");
  if (!mfw) return;

  csRef<iMeshWrapper> exp = engine->CreateMeshWrapper (mfw, "custom rain",
	sector, csVector3 (0, 0, 0));

  if (do_camera)
  {
    iEngine* e = Sys->Engine;
    int c = e->GetAlphaRenderPriority ();
    exp->GetFlags ().Set (CS_ENTITY_CAMERA);
    exp->SetRenderPriority (c);
  }
  exp->SetZBufMode(CS_ZBUF_TEST);
  exp->GetMeshObject()->SetMixMode (CS_FX_ADD);
  exp->GetMeshObject()->SetMaterialWrapper (mat);

  csRef<iParticleBuiltinEmitterFactory> emit_factory = 
      csLoadPluginCheck<iParticleBuiltinEmitterFactory> (
        Sys->object_reg, "crystalspace.mesh.object.particles.emitter", false);
  csRef<iParticleBuiltinEffectorFactory> eff_factory = 
      csLoadPluginCheck<iParticleBuiltinEffectorFactory> (
        Sys->object_reg, "crystalspace.mesh.object.particles.effector", false);

  csRef<iParticleBuiltinEmitterBox> boxemit = emit_factory->CreateBox ();
  // Time to live depends on height of sector.
  float velocity = 2.84f * speed / 2.0f;
  float seconds_to_live = (bbox.MaxY () - bbox.MinY ()) / velocity;
  csBox3 emit_bbox = bbox;
  emit_bbox.SetMin (1, emit_bbox.MaxY ());
  boxemit->SetBox (emit_bbox);
  boxemit->SetParticlePlacement (CS_PARTICLE_BUILTIN_VOLUME);
  boxemit->SetEmissionRate (float (num) / seconds_to_live);
  boxemit->SetInitialMass (5.0f, 7.5f);
  boxemit->SetUniformVelocity (true);
  boxemit->SetInitialTTL (seconds_to_live, seconds_to_live);
  boxemit->SetInitialVelocity (csVector3 (0, -velocity, 0),
      csVector3 (0));

  csRef<iParticleBuiltinEffectorLinColor> lincol = eff_factory->
    CreateLinColor ();
  lincol->AddColor (csColor4 (.25,.25,.25,1), seconds_to_live);

  csRef<iParticleSystem> partstate =
  	scfQueryInterface<iParticleSystem> (exp->GetMeshObject ());
  partstate->SetMinBoundingBox (bbox);
  partstate->SetParticleSize (csVector2 (0.3f/50.0f, 0.3f));
  partstate->SetParticleRenderOrientation (CS_PARTICLE_ORIENT_COMMON);
  partstate->SetCommonDirection (csVector3 (0, 1, 0));
  partstate->AddEmitter (boxemit);
  partstate->AddEffector (lincol);
}
Ejemplo n.º 5
0
//===========================================================================
// Demo particle system (explosion).
//===========================================================================
static void add_particles_explosion (WalkTest* Sys, iSector* sector, iEngine* engine,
	const csVector3& center, const char* matname)
{
  // First check if the material exists.
  iMaterialWrapper* mat = Sys->Engine->GetMaterialList ()->
  	FindByName (matname);
  if (!mat)
  {
    Sys->Report (CS_REPORTER_SEVERITY_NOTIFY, "Can't find material '%s' in memory!", matname);
    return;
  }

  csRef<iMeshFactoryWrapper> mfw = engine->CreateMeshFactory (
      "crystalspace.mesh.object.particles", "explosion");
  if (!mfw) return;

  csRef<iMeshWrapper> exp = engine->CreateMeshWrapper (mfw, "custom explosion",
	sector, center);

  exp->SetZBufMode(CS_ZBUF_TEST);
  exp->SetRenderPriority (engine->GetAlphaRenderPriority ());
  exp->GetMeshObject()->SetMaterialWrapper (mat);
  exp->GetMeshObject()->SetMixMode (CS_FX_ALPHA);
  exp->GetMeshObject()->SetColor (csColor (1, 1, 0));

  csRef<iParticleBuiltinEmitterFactory> emit_factory = 
      csLoadPluginCheck<iParticleBuiltinEmitterFactory> (
        Sys->object_reg, "crystalspace.mesh.object.particles.emitter", false);
  csRef<iParticleBuiltinEffectorFactory> eff_factory = 
      csLoadPluginCheck<iParticleBuiltinEffectorFactory> (
        Sys->object_reg, "crystalspace.mesh.object.particles.effector", false);

  csRef<iParticleBuiltinEmitterSphere> sphereemit = emit_factory->
    CreateSphere ();
  sphereemit->SetRadius (0.1f);
  sphereemit->SetParticlePlacement (CS_PARTICLE_BUILTIN_CENTER);
  sphereemit->SetPosition (csVector3 (0, 0, 0));
  sphereemit->SetInitialVelocity (csVector3 (1, 0, 0), csVector3 (3, 3, 3));
  sphereemit->SetUniformVelocity (false);
  sphereemit->SetDuration (0.1f);
  sphereemit->SetEmissionRate (1000.0f);
  sphereemit->SetInitialTTL (1.0f, 1.0f);

  csRef<iParticleBuiltinEffectorLinColor> lincol = eff_factory->
    CreateLinColor ();
  lincol->AddColor (csColor4 (1,1,1,1), 1.0f);
  lincol->AddColor (csColor4 (1,1,1,0), 0.0f);

  csRef<iParticleSystem> partstate =
  	scfQueryInterface<iParticleSystem> (exp->GetMeshObject ());
  partstate->SetParticleSize (csVector2 (0.15f, 0.15f));
  partstate->SetRotationMode (CS_PARTICLE_ROTATE_VERTICES);
  partstate->SetIntegrationMode (CS_PARTICLE_INTEGRATE_BOTH);
  partstate->AddEmitter (sphereemit);
  partstate->AddEffector (lincol);

  Sys->Engine->DelayedRemoveObject (1100, exp);
  Sys->Engine->DelayedRemoveObject (1101, mfw);

  exp->PlaceMesh ();
}
Ejemplo n.º 6
0
//===========================================================================
// Demo particle system (fire).
//===========================================================================
static void add_particles_fire (WalkTest* Sys, iSector* sector, char* matname, int num,
	const csVector3& origin)
{
  iEngine* engine = Sys->Engine;

  // First check if the material exists.
  iMaterialWrapper* mat = engine->GetMaterialList ()->FindByName (matname);
  if (!mat)
  {
    Sys->Report (CS_REPORTER_SEVERITY_NOTIFY, "Can't find material '%s' in memory!", matname);
    return;
  }

  csRef<iMeshFactoryWrapper> mfw = engine->CreateMeshFactory (
      "crystalspace.mesh.object.particles", "fire");
  if (!mfw) return;

  csRef<iMeshWrapper> exp = engine->CreateMeshWrapper (mfw, "custom fire",
	sector, origin);

  exp->SetZBufMode(CS_ZBUF_TEST);
  exp->GetMeshObject()->SetMixMode (CS_FX_ADD);
  exp->GetMeshObject()->SetMaterialWrapper (mat);

  csRef<iParticleBuiltinEmitterFactory> emit_factory = 
      csLoadPluginCheck<iParticleBuiltinEmitterFactory> (
        Sys->object_reg, "crystalspace.mesh.object.particles.emitter", false);
  csRef<iParticleBuiltinEffectorFactory> eff_factory = 
      csLoadPluginCheck<iParticleBuiltinEffectorFactory> (
        Sys->object_reg, "crystalspace.mesh.object.particles.effector", false);

  csRef<iParticleBuiltinEmitterSphere> sphemit = emit_factory->CreateSphere ();
  float velocity = 0.5f;
  float seconds_to_live = 2.0f;
  sphemit->SetRadius (.2f);
  sphemit->SetParticlePlacement (CS_PARTICLE_BUILTIN_VOLUME);
  sphemit->SetEmissionRate (float (num) / seconds_to_live);
  sphemit->SetInitialMass (5.0f, 7.5f);
  sphemit->SetUniformVelocity (true);
  sphemit->SetInitialTTL (seconds_to_live, seconds_to_live);
  sphemit->SetInitialVelocity (csVector3 (0, velocity, 0),
      csVector3 (0));

  csRef<iParticleBuiltinEffectorLinColor> lincol = eff_factory->
    CreateLinColor ();
  lincol->AddColor (csColor4 (0.00f, 0.00f, 0.00f, 1.00f), 2.0000f);
  lincol->AddColor (csColor4 (1.00f, 0.35f, 0.00f, 0.00f), 1.5000f);
  lincol->AddColor (csColor4 (1.00f, 0.22f, 0.00f, 0.10f), 1.3125f);
  lincol->AddColor (csColor4 (1.00f, 0.12f, 0.00f, 0.30f), 1.1250f);
  lincol->AddColor (csColor4 (0.80f, 0.02f, 0.00f, 0.80f), 0.9375f);
  lincol->AddColor (csColor4 (0.60f, 0.00f, 0.00f, 0.90f), 0.7500f);
  lincol->AddColor (csColor4 (0.40f, 0.00f, 0.00f, 0.97f), 0.5625f);
  lincol->AddColor (csColor4 (0.20f, 0.00f, 0.00f, 1.00f), 0.3750f);
  lincol->AddColor (csColor4 (0.00f, 0.00f, 0.00f, 1.00f), 0.1875f);
  lincol->AddColor (csColor4 (0.00f, 0.00f, 0.00f, 1.00f), 0.0000f);

  csRef<iParticleBuiltinEffectorForce> force = eff_factory->
    CreateForce ();
  force->SetRandomAcceleration (csVector3 (1.5f, 1.5f, 1.5f));

  csRef<iParticleSystem> partstate =
  	scfQueryInterface<iParticleSystem> (exp->GetMeshObject ());
  //partstate->SetMinBoundingBox (bbox);
  partstate->SetParticleSize (csVector2 (0.04f, 0.08f));
  partstate->AddEmitter (sphemit);
  partstate->AddEffector (lincol);
  partstate->AddEffector (force);
}