/* Copy container of entities from another world to this one and select them. */
void CWorld::CopyEntities(CWorld &woOther, CDynamicContainer<CEntity> &cenToCopy,
  CEntitySelection &senCopied, const CPlacement3D &plOtherSystem)
{
  INDEX ctEntities = cenToCopy.Count();
  if (ctEntities<=0) {
    return;
  }


  ULONG ulCopyFlags = COPY_REMAP;
  if(_bReinitEntitiesWhileCopying) {
    ulCopyFlags|=COPY_REINIT;
  };

  // create array of pointer remaps
  _aprRemaps.Clear();
  _aprRemaps.New(ctEntities);


  // PASS 1: create entities

  // for each entity to copy
  INDEX iRemap = 0;
  {FOREACHINDYNAMICCONTAINER(cenToCopy, CEntity, itenToCopy) {
    CEntity &enToCopy = *itenToCopy;

    CEntity *penNew;
    CPlacement3D plEntity;
    // thansform the entity placement from the system of other world
    plEntity = enToCopy.en_plPlacement;
    plEntity.RelativeToAbsolute(plOtherSystem);

    // mirror and stretch placement if needed
    if (_bMirrorAndStretch) {
      MirrorAndStretchPlacement(plEntity);
    }

    /*
     * NOTE: We must use CreateEntity_t() overload with class name instead with class pointer
     * because the entity class must be obtained by the target world too!
     */
    // try to
    try {
      // create an entity of same class as the one to copy
      penNew = CreateEntity_t(plEntity, enToCopy.en_pecClass->GetName());
    // if not successfull
    } catch (char *strError) {
      (void)strError;
      ASSERT(FALSE);    // this should not happen
      FatalError(TRANS("Cannot CopyEntity():\n%s"), strError);
    }

    // remember its remap pointer
    _aprRemaps[iRemap].pr_penOriginal = &enToCopy;
    _aprRemaps[iRemap].pr_penCopy = penNew;
    iRemap++;
  }}
Beispiel #2
0
void CStock_TYPE::FreeUnused(void)
{
  BOOL bAnyRemoved;
  // repeat
  do {
    // create container of objects that should be freed
    CDynamicContainer<TYPE> ctToFree;
    {FOREACHINDYNAMICCONTAINER(st_ctObjects, TYPE, itt) {
      if (!itt->IsUsed()) {
        ctToFree.Add(itt);
      }
    }}
    bAnyRemoved = ctToFree.Count()>0;
    // for each object that should be freed
    {FOREACHINDYNAMICCONTAINER(ctToFree, TYPE, itt) {
      st_ctObjects.Remove(itt);
      st_ntObjects.Remove(itt);
      delete (&*itt);
    }}

  // as long as there is something to remove
  } while (bAnyRemoved);

}
Beispiel #3
0
/*
 * Converts data from Exploration3D format into arrays used for conversion to O3D
 */
void FillConversionArrays_t(const FLOATmatrix3D &mTransform)
{
#if USE_E3D
  // all polygons must be triangles
  if(_pe3Object->_facecount != 0)
  {
    throw("Error: Not all polygons are triangles!");
  }

  // check if we need flipping (if matrix is flipping, polygons need to be flipped)
  const FLOATmatrix3D &m = mTransform;
  FLOAT fDet = 
    m(1,1)*(m(2,2)*m(3,3)-m(2,3)*m(3,2))+
    m(1,2)*(m(2,3)*m(3,1)-m(2,1)*m(3,3))+
    m(1,3)*(m(2,1)*m(3,2)-m(2,2)*m(3,1));
  FLOAT bFlipped = fDet<0;

  // ------------  Convert object vertices (coordinates)
  INDEX ctVertices = _pe3Object->pointcount;
  avVertices.New(ctVertices);
  // copy vertices
  for( INDEX iVtx=0; iVtx<ctVertices; iVtx++)
  {
    avVertices[iVtx] = ((FLOAT3D &)_pe3Object->points[iVtx])*mTransform;
    avVertices[iVtx](1) = -avVertices[iVtx](1);
    avVertices[iVtx](3) = -avVertices[iVtx](3);
  }

  // ------------ Convert object's mapping vertices (texture vertices)
  INDEX ctTextureVertices = _pe3Object->txtcount;
  avTextureVertices.New(ctTextureVertices);
  // copy texture vertices
  for( INDEX iTVtx=0; iTVtx<ctTextureVertices; iTVtx++)
  {
    avTextureVertices[iTVtx] = (FLOAT2D &)_pe3Object->txtpoints[iTVtx];
  }
  
  // ------------ Organize triangles as list of surfaces
  // allocate triangles
  INDEX ctTriangles = _pe3Object->facecount;
  actTriangles.New(ctTriangles);

  acmMaterials.Lock();
  
  // sort triangles per surfaces
  for( INDEX iTriangle=0; iTriangle<ctTriangles; iTriangle++)
  {
    ConversionTriangle &ctTriangle = actTriangles[iTriangle];
    e3_TFACE *pe3Triangle = _pe3Object->GetFace( iTriangle);
    // copy vertex indices
    if (bFlipped) {
      ctTriangle.ct_iVtx[0] = pe3Triangle->v[2];
      ctTriangle.ct_iVtx[1] = pe3Triangle->v[1];
      ctTriangle.ct_iVtx[2] = pe3Triangle->v[0];
    } else {
      ctTriangle.ct_iVtx[0] = pe3Triangle->v[0];
      ctTriangle.ct_iVtx[1] = pe3Triangle->v[1];
      ctTriangle.ct_iVtx[2] = pe3Triangle->v[2];
    }
    // copy texture vertex indices
    if (bFlipped) {
      ctTriangle.ct_iTVtx[0] = pe3Triangle->t[2];
      ctTriangle.ct_iTVtx[1] = pe3Triangle->t[1];
      ctTriangle.ct_iTVtx[2] = pe3Triangle->t[0];
    } else {
      ctTriangle.ct_iTVtx[0] = pe3Triangle->t[0];
      ctTriangle.ct_iTVtx[1] = pe3Triangle->t[1];
      ctTriangle.ct_iTVtx[2] = pe3Triangle->t[2];
    }

    // obtain material
    e3_MATERIAL *pe3Mat = pe3Triangle->material;
    BOOL bNewMaterial = TRUE;
    // attach triangle into one material
    for( INDEX iMat=0; iMat<acmMaterials.Count(); iMat++)
    {
      // if this material already exist in array of materu
      if( acmMaterials[ iMat].cm_ulTag == (ULONG) pe3Mat)
      {
        // set index of surface
        ctTriangle.ct_iMaterial = iMat;
        // add triangle into surface list of triangles
        INDEX *piNewTriangle = new INDEX(1);
        *piNewTriangle = iTriangle;
        acmMaterials[ iMat].ms_Polygons.Add( piNewTriangle);
        bNewMaterial = FALSE;
        continue;
      }
    }
    // if material hasn't been added yet
    if( bNewMaterial)
    {
      // add new material
      ConversionMaterial *pcmNew = new ConversionMaterial;
      acmMaterials.Unlock();
      acmMaterials.Add( pcmNew);
      acmMaterials.Lock();
      // set polygon's material index 
      INDEX iNewMaterial = acmMaterials.Count()-1;
      ctTriangle.ct_iMaterial = iNewMaterial;
      // add triangle into new surface's list of triangles
      INDEX *piNewTriangle = new INDEX(1);
      *piNewTriangle = iTriangle;
      acmMaterials[ iNewMaterial].ms_Polygons.Add( piNewTriangle);
      
      // remember recognition tag (ptr)
      pcmNew->cm_ulTag = (ULONG) pe3Mat;

      // ---------- Set material's name
      // if not default material
      if( pe3Mat != NULL && pe3Mat->name != NULL)
      {
        acmMaterials[iNewMaterial].cm_strName = CTString(pe3Mat->name);
        // get color
        COLOR colColor = CLR_CLRF( pe3Mat->GetDiffuse().rgb());
        acmMaterials[iNewMaterial].cm_colColor = colColor;
      }
      else
      {
        acmMaterials[iNewMaterial].cm_strName = "Default";
        acmMaterials[iNewMaterial].cm_colColor = C_GRAY;
      }
    }
  }
  acmMaterials.Unlock();
#endif
}