コード例 #1
0
ファイル: mcmaptexturedplane.cpp プロジェクト: alexeyd/map2cs
mcTexDef::mcTexDef()
{
  m_shift = csVector2(0.0, 0.0);
  m_scale = csVector2(1.0, 1.0);
  m_rotate = 0.0;

  m_plane_normal = csVector3(0.0, 0.0, 1.0);
  m_max_axis = CS_AXIS_Z;
}
コード例 #2
0
ファイル: lghthalo.cpp プロジェクト: GameLemur/Crystal-Space
bool csLightHalo::Process (csTicks ElapsedTime, iCamera* camera, 
			   csEngine* Engine)
{
  // Whenever the center of halo (the light) is directly visible
  bool halo_vis = false;

  // Whenever at least a piece of halo is visible
  bool draw_halo = false;

  // top-left coordinates of halo rectangle
  float xtl = 0, ytl = 0;

  // Project the halo.
  csVector3 v = camera->GetTransform ().Other2This (
      Light->GetFullCenter ());

  // The clipped halo polygon
  csVector2 HaloClip[32];

  // Number of vertices in HaloClip array
  size_t HaloVCount = 32;

  halo_vis = IsVisible (camera, Engine, v);

  // Create a rectangle containing the halo and clip it against screen
  float hw = Handle->GetWidth () * 0.5f;
  float hh = Handle->GetHeight () * 0.5f;
  
  csVector2 HaloPoly[4] =
  {
    csVector2 (v.x - hw, v.y - hh),
    csVector2 (v.x - hw, v.y + hh),
    csVector2 (v.x + hw, v.y + hh),
    csVector2 (v.x + hw, v.y - hh)
  };

  // Clip the halo against clipper
  if (Engine->GetTopLevelClipper ()->GetClipper ()->Clip (
  	HaloPoly, 4, HaloClip, HaloVCount))
  {
    xtl = HaloPoly[0].x;
    ytl = HaloPoly[0].y;
    draw_halo = true;
  }

  float hintensity = Light->GetHalo ()->GetIntensity ();
  if (!ComputeNewIntensity (ElapsedTime, hintensity, halo_vis))
    return false; // halo is invisible now, kill it
  Light->GetHalo ()->SetIntensity (hintensity);

  if (draw_halo)
    Handle->Draw (xtl, ytl, -1, -1, hintensity, HaloClip, HaloVCount);
  return true;
}
コード例 #3
0
void psSlotManager::DropItem(bool guard)
{
    // get final position and rotation
    psPoint p = PawsManager::GetSingleton().GetMouse()->GetPosition();
    csVector3 pos;
    csVector3 rot;
    psengine->GetSceneManipulator()->GetPosition(pos, rot, csVector2(p.x, p.y));

    // Send drop message.
    psSlotMovementMsg msg( draggingSlot.containerID, draggingSlot.slotID,
      CONTAINER_WORLD, 0, draggingSlot.stackCount, &pos, &rot, guard, false);
    msg.SendMessage();

    // Remove outline mesh.
    psengine->GetSceneManipulator()->RemoveSelected();

    // Show inventory window again.
    if(hadInventory)
    {
        PawsManager::GetSingleton().GetMainWidget()->FindWidget("InventoryWindow")->Show();
    }

    // Reset flags.
    isDragging = false;
    isPlacing = false;
    isRotating = false;
    hadInventory = false;
}
コード例 #4
0
void psSlotManager::UpdateItem()
{
    // Get new position.
    psPoint p = PawsManager::GetSingleton().GetMouse()->GetPosition();

    // If we're rotating then we use mouse movement to determine rotation.
    if(isRotating)
    {
        psengine->GetSceneManipulator()->RotateSelected(csVector2(p.x, p.y));
    }
    else
    {
        // Else we use it to determine item position.
        psengine->GetSceneManipulator()->TranslateSelected(false,
            psengine->GetPSCamera()->GetICamera()->GetCamera(), csVector2(p.x, p.y));
    }
}
コード例 #5
0
ファイル: psslotmgr.cpp プロジェクト: garinh/planeshift
bool psSlotManager::HandleEvent( iEvent& ev )
{
    if(isDragging)
    {
        if(ev.Name == MouseMove)
        {
            if(isPlacing)
            {
                // Update item position.
                UpdateItem();
            }
        }
        else if(ev.Name == MouseDown)
        {
          uint button = csMouseEventHelper::GetButton(&ev);
          
          if(button == 0) // Left
          {
              if(isPlacing)
              {
                  // Drop the item at the current position.
                  if(isRotating)
                  {
                      DropItem();
                      return true;
                  }

                  // Else begin rotate...
                  isRotating = true;
                  basePoint = PawsManager::GetSingleton().GetMouse()->GetPosition();
                  psengine->GetSceneManipulator()->SaveCoordinates(csVector2(basePoint.x, basePoint.y));
                  return false;
              }

              // Else place...
              PlaceItem();
          }
          else
          {
              CancelDrag();

              // Show the inventory window, remove outline mesh etc. if we're placing.
              if(isPlacing)
              {
                  PawsManager::GetSingleton().GetMainWidget()->FindWidget("InventoryWindow")->Show();

                  // Remove outline mesh.
                  psengine->GetSceneManipulator()->RemoveSelected();

                  isPlacing = false;
                  isRotating = false;
              }
          }
        }
    }

    return false;
}
コード例 #6
0
ファイル: particles.cpp プロジェクト: garinh/cs
//===========================================================================
// 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);
}
コード例 #7
0
ファイル: box.cpp プロジェクト: garinh/cs
csVector2 csBox2::GetCorner (int corner) const
{
    switch (corner)
    {
    case CS_BOX_CORNER_xy:
        return Min ();
    case CS_BOX_CORNER_xY:
        return csVector2 (MinX (), MaxY ());
    case CS_BOX_CORNER_Xy:
        return csVector2 (MaxX (), MinY ());
    case CS_BOX_CORNER_XY:
        return Max ();
    case CS_BOX_CENTER2:
        return GetCenter ();
    }

    return csVector2 (0, 0);
}
コード例 #8
0
ファイル: cellrdata.cpp プロジェクト: GameLemur/Crystal-Space
void TerrainCellRData::SetupRoot ()
{
  if (rootBlock)
    return;

  rootBlock = terrainBlockAllocator.Alloc ();
  
  const csVector3& cellSize = cell->GetSize ();
  rootBlock->centerPos = cell->GetPosition () + 
    csVector2 (cellSize.x / 2.0f, cellSize.z / 2.0f);
  rootBlock->size = csVector2 (cellSize.x, cellSize.z);
  
  rootBlock->gridLeft = rootBlock->gridTop = 0;
  rootBlock->gridRight = cell->GetGridWidth () - 1;
  rootBlock->gridBottom = cell->GetGridHeight () - 1;

  rootBlock->stepSize = rootBlock->gridRight / blockResolution;
  rootBlock->renderData = this;
}
コード例 #9
0
ファイル: mcmaptexturedplane.cpp プロジェクト: alexeyd/map2cs
mcMapTexturedPlane::mcMapTexturedPlane(const csDVector3 &v0, 
                                     const csDVector3 &v1,
                                     const csDVector3 &v2,
                                     const csString &texture_name,
                                     double x_off, double y_off, 
                                     double rot_angle,
                                     double x_scale, double y_scale)
{
  m_texture_name = texture_name;

  csDMath3::CalcNormal(m_plane.norm, v0, v1, v2);
  m_plane.DD = -m_plane.norm * v0;

  m_plane.Normalize();

  m_texdef = mcTexDef(csVector2(x_off, y_off),
                      csVector2(x_scale, y_scale),
                      (M_PI * rot_angle) / 180.0,
                      m_plane.norm);
}
コード例 #10
0
ファイル: keys.cpp プロジェクト: GameLemur/Crystal-Space
// right mouse button
void WalkTest::MouseClick2Handler(iEvent &Event)
{
  int mx = csMouseEventHelper::GetX (&Event);
  int my = csMouseEventHelper::GetY (&Event);
  csScreenTargetResult result = csEngineTools::FindScreenTarget (
      csVector2 (mx, my), 100.0f, views->GetCamera ());
  iMeshWrapper* mesh = result.mesh;
  int sel = result.polygon_idx;

  csVector3 vw = result.isect;
  csVector3 v = views->GetCamera ()->GetTransform ().Other2This (vw);
  Sys->Report (CS_REPORTER_SEVERITY_NOTIFY,
  	"RMB down : cam:(%f,%f,%f) world:(%f,%f,%f)",
	v.x, v.y, v.z, vw.x, vw.y, vw.z);
  Sys->Report (CS_REPORTER_SEVERITY_NOTIFY,
  	"RMB down : cam:(%f,%f,%f) world:(%f,%f,%f)",
	v.x, v.y, v.z, vw.x, vw.y, vw.z);

  if (mesh && sel != -1)
  {
    Sys->selected_polygon = sel;

    iMeshObject* obj = mesh->GetMeshObject ();
    csRef<iObject> psobj = 
    	scfQueryInterface<iObject> (obj->GetMeshWrapper ());
    csString polystr;
    polystr.Format ("%s/%d", psobj ? psobj->GetName () : "<null>", sel);
    Sys->Report (CS_REPORTER_SEVERITY_DEBUG, "Hit object/polygon %s",
		 CS::Quote::Single (polystr.GetData()));
  }
  else if (mesh)
  {
    csRef<iObject> psobj = 
    	scfQueryInterface<iObject> (mesh->GetMeshObject ()->GetMeshWrapper ());
    Sys->Report (CS_REPORTER_SEVERITY_DEBUG, "Hit mesh %s",
    	CS::Quote::Single (psobj ? psobj->GetName () : "<null>"));
  }
  else
  {
    Sys->Report (CS_REPORTER_SEVERITY_DEBUG, "No hit");
  }

  extern csVector2 coord_check_vector;
  coord_check_vector.x = csMouseEventHelper::GetX(&Event);
  coord_check_vector.y = FRAME_HEIGHT-csMouseEventHelper::GetY(&Event);
  extern bool check_light;
  extern void select_object (iRenderView* rview, int type, void* entity);
  check_light = true;
  //view->GetEngine ()->DrawFunc (views->GetCamera (),
    //view->GetClipper (), select_object);
}
コード例 #11
0
ファイル: mcmaptexturedplane.cpp プロジェクト: alexeyd/map2cs
csVector2 mcTexDef::TexCoords(const csVector3 vertex,
                              int tex_width, int tex_height) const
{
  csVector2 inv_scale;

  float width  = static_cast<float>( tex_width );
  float height = static_cast<float>( tex_height );

  float s = sinf(-m_rotate);
  float c = cosf(-m_rotate);

  inv_scale.x = 1.0 / (m_scale.x * width);
  inv_scale.y = 1.0 / (m_scale.x * -height);

  CS::Math::Matrix4 local2tex = 
    CS::Math::Matrix4(c*inv_scale.x, -s*inv_scale.x, 0.0, m_shift.x / width,
                      s*inv_scale.y, c*inv_scale.y,  0.0, m_shift.y / height,
                      0.0,           0.0,            1.0, 0.0,
                      0.0,           0.0,            0.0, 1.0);


  csVector3 texcoords;

  texcoords.z = 1.0;

  switch(m_max_axis)
  {
    case CS_AXIS_X:
      texcoords.x = vertex.y;
      texcoords.y = vertex.z;
      break;

    case CS_AXIS_Y:
      texcoords.x = vertex.x;
      texcoords.y = vertex.z;
      break;

    case CS_AXIS_Z:
      texcoords.x = vertex.x;
      texcoords.y = vertex.y;
      break;

    default:
      CS_ASSERT(0);
  }

  texcoords *= local2tex.GetTransform();

  return csVector2(texcoords.x, texcoords.y);
}
コード例 #12
0
ファイル: basemapgen.cpp プロジェクト: garinh/cs
void BaseMapGen::ScanMaterials ()
{
  csRef<iDocumentNode> mats = rootnode->GetNode ("materials");
  if (!mats) return;

  csRef<iDocumentNodeIterator> it_mats = mats->GetNodes("material");
  while (it_mats->HasNext())
  {
    csRef<iDocumentNode> mat = it_mats->Next();
    csString matname = mat->GetAttributeValue ("name");
    
    // Get texture file name.
    csRef<iDocumentNode> tex = mat->GetNode ("texture");
    if (!tex) continue;
    const char* texname = tex->GetContentsValue();
    const char* texture_file = textureFiles.Get (texname, (const char*)0);
    if (!texture_file) continue;
    
    // Set the texture scale.
    csRef<iDocumentNodeIterator> it = mat->GetNodes("shadervar");
    csVector2 texscale(32,32);
    while (it->HasNext())
    {
      csRef<iDocumentNode> current = it->Next();
      csString name = current->GetAttributeValue("name");
      if ( name.Compare("texture scale"))
      {
	csString scalestr = current->GetContentsValue();
	size_t pos = scalestr.FindFirst(",",0);
	csString firststr = scalestr.Slice(0,pos);
	csString secondstr = scalestr.Slice(pos+1, scalestr.Length());
	int first = atoi(firststr.GetData());
	int second = atoi(secondstr.GetData());
	texscale = csVector2(first, second);
	break;
      }
    } // while

    csRef<MaterialLayer> material;
    material.AttachNew (new MaterialLayer);
    material->name = matname;
    material->texture_name = texname;
    material->texture_file = texture_file;
    material->texture_scale = texscale;
    materials.Put (matname, material);
  }
}
コード例 #13
0
ファイル: meshgen.cpp プロジェクト: Tank-D/Shards
csMeshGeneratorGeometry::csMeshGeneratorGeometry (
  csMeshGenerator* generator) : scfImplementationType (this),
  min_draw_dist (0),
  sq_min_draw_dist (0),
  min_opaque_dist (0),
  max_opaque_dist (CS::Infinity()),
  generator (generator)
{
  colldetID = generator->GetStringSet()->Request ("colldet");
  radius = 0.0f;
  density = 1.0f;
  total_max_dist = 0.0f;
  default_material_factor = 0.0f;
  celldim = 0;
  positions = 0;
  wind_direction = csVector2(0.0f);
  wind_bias = 1.0f;
  wind_speed = 1.0f;
}
コード例 #14
0
ファイル: lghthalo.cpp プロジェクト: GameLemur/Crystal-Space
bool csLightHalo::IsVisible (iCamera* camera, csEngine* Engine, csVector3 &v)
{
  if (v.z > SMALL_Z)
  {
    float fov, sx, sy;
    csRef<iPerspectiveCamera> pcam =
      scfQueryInterface<iPerspectiveCamera> (camera);
    if (pcam)
    {
      fov = pcam->GetFOV ();
      sx = pcam->GetShiftX ();
      sy = pcam->GetShiftY ();
    }
    else
    {
      fov = 1.0f;
      sx = 0.0f;
      sy = 0.0f;
    }
    float iz = fov / v.z;
    v.x = v.x * iz + sx;
    v.y = Engine->frameHeight - 1 - (v.y * iz + sy);

    if (Engine->GetTopLevelClipper ()->GetClipper ()->IsInside (
    	csVector2 (v.x, v.y)))
    {
        csSectorHitBeamResult hbresult;
        hbresult = camera->GetSector ()->HitBeamPortals (
	    camera->GetTransform().GetOrigin(),	Light->GetFullCenter());
        if(hbresult.mesh)
            return false; // hit a mesh
        if(hbresult.polygon_idx != -1) // double check on the above if
            return false; // hit a polygon
        return true;
    }
  }

  return false;
}
コード例 #15
0
ファイル: meshgen.cpp プロジェクト: Tank-D/Shards
void csMeshGeneratorGeometry::AddPositionsFromMap (iTerraFormer* map,
	const csBox2 &region, uint resx, uint resy, float value,
	const csStringID & type)
{
  csRef<iTerraSampler> sampler = map->GetSampler (region, resx, resy);
  float stepx = (region.MaxX () - region.MinX ())/resx;
  float stepy = (region.MaxY () - region.MinY ())/resy;

  const float* map_values = sampler->SampleFloat (type);
  float curx = region.MinX (), cury = region.MinY ();
  for (uint i = 0; i < resx; i++)
  {
    for (uint j = 0; j < resy; j++)
    {
      if (map_values[i*resx + j] == value)
      {
        AddPosition (csVector2 (curx, cury));
      }
      curx += stepx;
    }
    curx = region.MinX ();
    cury += stepy;
  }
}
コード例 #16
0
ファイル: curvemesh.cpp プロジェクト: Dracophoenix1/ares
    void CurvedFactory::GenerateGeometry (iMeshWrapper* thisMesh)
    {
# if VERBOSE
        printf ("#############################################################\n");
        fflush (stdout);
# endif
        csFlags oldFlags = thisMesh->GetFlags ();
        thisMesh->GetFlags ().Set (CS_ENTITY_NOHITBEAM);

        clingyPath.SetBasePoints (anchorPoints);
# if VERBOSE
        printf ("GenerateGeometry: Flatten\n");
        fflush (stdout);
# endif
        clingyPath.Flatten (thisMesh, width);
        csPath path (1);
# if VERBOSE
        printf ("GenerateGeometry: GeneratePath\n");
        fflush (stdout);
# endif
        clingyPath.GeneratePath (path);
        printf ("Path has %d control points\n",
                int (clingyPath.GetWorkingPointCount ()));
        fflush (stdout);
        float totalDistance = clingyPath.GetTotalDistance ();

        // @@@todo, the entire detail on the path should be customizable. Also it should
        // use less detail on relatively straight lines.
        float samplesPerUnit = 1.0;
        // Calculate a rounded number of samples from the samplesPerUnit and
        // then correct samplesPerUnit so that the samples are evenly spread.
        size_t samples = size_t (totalDistance / samplesPerUnit) + 1;
        samplesPerUnit = totalDistance / (samples - 1);

        state->SetVertexCount (samples * 4);
        state->SetTriangleCount ((samples-1) * 6);

        csVector3 pos, front, up, prevPos;
        csVector3* vertices = state->GetVertices ();
        csVector3* normals = state->GetNormals ();
        csVector2* texels = state->GetTexels ();

        path.CalculateAtTime (0);
        path.GetInterpolatedPosition (prevPos);

        float traveledDistance = 0;
        for (size_t i = 0 ; i < samples ; i++)
        {
            float time = float (i) / float (samples-1);
            path.CalculateAtTime (time);
            path.GetInterpolatedPosition (pos);
            traveledDistance += sqrt (csSquaredDist::PointPoint (pos, prevPos));
            //printf ("%d time=%g pos=%g,%g,%g dist=%g\n", i, time, pos.x, pos.y, pos.z, traveledDistance); fflush (stdout);
            prevPos = pos;

            path.GetInterpolatedForward (front);
            path.GetInterpolatedUp (up);

            csVector3 right = (width / 2.0) * (front % up);
            csVector3 down = -up.Unit () * sideHeight;
            csVector3 offsetUp = up.Unit () * offsetHeight;

            csVector3 rightPos = pos + right;
            csVector3 leftPos = pos - right;
            rightPos += offsetUp;
            leftPos += offsetUp;

            *vertices++ = rightPos;
            *vertices++ = leftPos;
            *vertices++ = rightPos + down;
            *vertices++ = leftPos + down;
            *normals++ = (up*.8+right*.2).Unit ();
            *normals++ = (up*.8-right*.2).Unit ();
            *normals++ = right;
            *normals++ = -right;
            *texels++ = csVector2 (0, traveledDistance / width);
            *texels++ = csVector2 (1, traveledDistance / width);
            *texels++ = csVector2 (-width/sideHeight, traveledDistance / width);
            *texels++ = csVector2 (width/sideHeight, traveledDistance / width);
        }

        csTriangle* tris = state->GetTriangles ();
        int vtidx = 0;
        for (size_t i = 0 ; i < samples-1 ; i++)
        {
            *tris++ = csTriangle (vtidx+5, vtidx+1, vtidx+0);
            *tris++ = csTriangle (vtidx+4, vtidx+5, vtidx+0);
            *tris++ = csTriangle (vtidx+6, vtidx+4, vtidx+0);
            *tris++ = csTriangle (vtidx+2, vtidx+6, vtidx+0);
            *tris++ = csTriangle (vtidx+3, vtidx+1, vtidx+7);
            *tris++ = csTriangle (vtidx+7, vtidx+1, vtidx+5);
            vtidx += 4;
        }

        factory->GetMeshObjectFactory ()->SetMaterialWrapper (material);
        state->Invalidate ();

        thisMesh->GetFlags ().SetAll (oldFlags.Get ());
    }
コード例 #17
0
ファイル: portalcontainer.cpp プロジェクト: Tank-D/Shards
  bool ClipAgainst (iClipper2D* clipper)
  {
    size_t clipOutputVerts = dest.GetVertexCount() + clipper->GetVertexCount();
    CS_ALLOC_STACK_ARRAY(csVector2, clipOut, clipOutputVerts);
    CS_ALLOC_STACK_ARRAY(csVertexStatus, clipOutStatus, clipOutputVerts);
    size_t outNum;
    csPoly2D destPx;
    destPx.SetVertexCount (dest.GetVertexCount());
    for (size_t p = 0; p < dest.GetVertexCount(); p++)
    {
      destPx[p].Set (dest[p].x, dest[p].y);
    }
    uint8 clipRes = clipper->Clip (
      destPx.GetVertices(), destPx.GetVertexCount(), clipOut, outNum,
      clipOutStatus);
    CS_ASSERT(outNum <= clipOutputVerts);
    if (clipRes == CS_CLIP_OUTSIDE) return false;
    if (clipRes == CS_CLIP_INSIDE) return true;
    
    csPoly2D orgDest2D (destPx);
    csPoly3D orgDest3D (dest3D);
    MakeEmpty ();
      
    for (size_t i = 0 ; i < outNum; i++)
    {
      dest.AddVertex (csVector2 (clipOut[i].x, clipOut[i].y));
      switch (clipOutStatus[i].Type)
      {
	case CS_VERTEX_ORIGINAL:
	  {
	    const size_t vt = clipOutStatus[i].Vertex;
	    dest3D.AddVertex (orgDest3D[vt]);
          }
	  break;
	case CS_VERTEX_ONEDGE:
	  {
	    const size_t vt = clipOutStatus[i].Vertex;
	    const size_t vt2 = (vt+1) % orgDest3D.GetVertexCount();
	    const float t = clipOutStatus[i].Pos;

            dest3D.AddVertex (LerpPC (orgDest3D[vt], orgDest3D[vt2], t));
	  }
          break;
	case CS_VERTEX_INSIDE:
	  {
	    float x = clipOut[i].x;
	    float y = clipOut[i].y;
	    size_t edge[2][2];
	    int edgeToFind = 0;
	    // Determine edges from which to interpolate the vertex data
	    size_t lastVert = orgDest2D.GetVertexCount() - 1;
	    for (size_t v = 0; v < orgDest2D.GetVertexCount(); v++)
	    {
	      if ((fabs(orgDest2D[lastVert].y - orgDest2D[v].y) > SMALL_EPSILON) 
		&& ((y >= orgDest2D[lastVert].y && y <= orgDest2D[v].y)
		|| (y <= orgDest2D[lastVert].y && y >= orgDest2D[v].y)))
	      {
		edge[edgeToFind][0] = lastVert;
		edge[edgeToFind][1] = v;
		edgeToFind++;
		if (edgeToFind >= 2) break;
	      }
	      lastVert = v;
	    }
	    CS_ASSERT(edgeToFind >= 2);
	    const csVector2& A = orgDest2D[edge[0][0]];
	    const csVector2& B = orgDest2D[edge[0][1]];
	    const csVector2& C = orgDest2D[edge[1][0]];
	    const csVector2& D = orgDest2D[edge[1][1]];
	    // Coefficients
	    const float t1 = (y - A.y) / (B.y - A.y);
	    const float t2 = (y - C.y) / (D.y - C.y);
	    const float x1 = A.x + t1 * (B.x - A.x);
	    const float x2 = C.x + t2 * (D.x - C.x);
	    const float dx = (x2 - x1);
	    const float t = dx ? ((x - x1) / dx) : 0.0f;
	    
	    dest3D.AddVertex (LerpPC (
	      LerpPC (orgDest3D[edge[0][0]], orgDest3D[edge[0][1]], t1),
	      LerpPC (orgDest3D[edge[1][0]], orgDest3D[edge[1][1]], t2),
	      t));
          }
	  break;
	default:
	  CS_ASSERT(false);
      }
    }
      
    return true;
  }
コード例 #18
0
bool psSlotManager::HandleEvent( iEvent& ev )
{
    if(isDragging)
    {
        int button = csMouseEventHelper::GetButton(&ev);
        if(ev.Name == MouseMove)
        {
            if(isPlacing)
            {
                // Update item position.
                UpdateItem();
            }
        }
        else if(ev.Name == MouseDown)
        {
            if(button == csmbLeft) // Left
            {
                if(isPlacing)
                {
                    // Drop the item at the current position.
                    DropItem(!(csMouseEventHelper::GetModifiers(&ev) & CSMASK_SHIFT));
                    return true;
                }
                else
                {
                    PlaceItem();
                }
            }
            else if(button == csmbRight) // right
            {
                if(!isRotating)
                {
                    basePoint = PawsManager::GetSingleton().GetMouse()->GetPosition();
                    isRotating = true;
                    if(csMouseEventHelper::GetModifiers(&ev) & CSMASK_SHIFT)
                    {
                        psengine->GetSceneManipulator()->SetRotation(PS_MANIPULATE_PITCH,PS_MANIPULATE_YAW);
                    }
                    else
                    {
                        psengine->GetSceneManipulator()->SetRotation(PS_MANIPULATE_ROLL,PS_MANIPULATE_NONE);
                    }
                    return true;
                }
            }
            else
            {
                CancelDrag();
            }
        }
        else if(ev.Name == MouseUp)
        {
            if(button == csmbRight) // right
            {
                if(isRotating)
                {
                    //PawsManager::GetSingleton().GetMouse()->SetPosition(basePoint.x, basePoint.y);
                    psengine->GetG2D()->SetMousePosition(basePoint.x, basePoint.y);
                    psengine->GetSceneManipulator()->SetPosition(csVector2(basePoint.x, basePoint.y));
                    isRotating = false;
                    return true;
                }
            }
        }
        /*else if(ev.Name == KeyDown)
        {
        }
        else if(ev.Name == KeyUp)
        {
        }*/
    }

    return false;
}
コード例 #19
0
ファイル: particles.cpp プロジェクト: garinh/cs
//===========================================================================
// 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);
}
コード例 #20
0
void psSlotManager::PlaceItem()
{
    if( draggingSlot.stackCount== 0 ) //stackCount==0 means this is a DnDButton. 
    {
        return;
    }

    // Get WS position.
    psPoint p = PawsManager::GetSingleton().GetMouse()->GetPosition();

    // Create mesh.
    outline = psengine->GetSceneManipulator()->CreateAndSelectMesh(draggingSlot.meshFactName,
        draggingSlot.materialName, psengine->GetPSCamera()->GetICamera()->GetCamera(), csVector2(p.x, p.y));

    // If created mesh is valid.
    if(outline)
    {
        // Hide the inventory so we can see where we're dropping.
        pawsWidget* inventory = PawsManager::GetSingleton().GetMainWidget()->FindWidget("InventoryWindow");
        hadInventory = inventory->IsVisible();
        inventory->Hide();

        // Get rid of icon.
        PawsManager::GetSingleton().SetDragDropWidget( NULL );

        // Mark placing.
        isPlacing = true;
    }
}
コード例 #21
0
ファイル: lghthalo.cpp プロジェクト: GameLemur/Crystal-Space
void csLightFlareHalo::ProcessFlareComponent (
  csEngine* engine,
  csFlareComponent *comp,
  csVector2 const &start,
  csVector2 const &deltapos)
{
  csVector2 pos = start + comp->position * deltapos;

  /// Compute size and position of this component
  float hw = (halosize * comp->width) * 0.5f;
  float hh = (halosize * comp->height) * 0.5f;
  
  csVector2 HaloUV[4] =
  {
    csVector2 (0.0, 0.0),
    csVector2 (0.0, 1.0),
    csVector2 (1.0, 1.0),
    csVector2 (1.0, 0.0)
  };


  if (!comp->image)
  {
    engine->Warn ("INTERNAL ERROR: flare used without material.");
    return ;
  }
  iMaterial* mat = comp->image->GetMaterial ();
  if (!mat)
  {
    engine->Warn ("INTERNAL ERROR: flare used without valid material.");
    return ;
  }

  comp->image->Visit ();

  csSimpleRenderMesh mesh;

  float intensity = flare->GetIntensity ();
  uint mode = comp->mixmode;
  if (!((mode & CS_FX_MASK_MIXMODE) == CS_FX_ADD) || (intensity >= 1.0f))
  {
    mode |= CS_FX_FLAT;
    intensity = 1.0f;
  }

  static uint indices[4] = {0, 1, 2, 3};
  csVector4 c = comp->color;
  c *= intensity;
  csVector4 colors[4] = {c, c, 
    c, c};

  pos.y = ((float)engine->G3D->GetHeight()) - pos.y;

  // Create a rectangle containing the halo and clip it against screen
  csVector3 HaloPoly[4] =
  {
    csVector3 (pos.x - hw, pos.y - hh, 0),
    csVector3 (pos.x + hw, pos.y - hh, 0),
    csVector3 (pos.x + hw, pos.y + hh, 0),
    csVector3 (pos.x - hw, pos.y + hh, 0)
  };

  mesh.meshtype = CS_MESHTYPE_QUADS;
  mesh.indexCount = 4;
  mesh.indices = indices;
  mesh.vertexCount = 4;
  mesh.vertices = HaloPoly;
  mesh.texcoords = HaloUV;
  mesh.colors = colors;
  mesh.texture = mat->GetTexture();
  mesh.mixmode = ((mode & CS_FX_MASK_MIXMODE) != CS_FX_ALPHA) ? mode : CS_FX_COPY;

  engine->G3D->DrawSimpleMesh (mesh, csSimpleMeshScreenspace);
}
コード例 #22
0
ファイル: particles.cpp プロジェクト: garinh/cs
//===========================================================================
// 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);
}
コード例 #23
0
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;
}
コード例 #24
0
ファイル: particles.cpp プロジェクト: garinh/cs
//===========================================================================
// 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 ();
}