Esempio n. 1
0
//
// MeshNode::VOnRestore				-  3rd Edition, Chapter 14, page 506
//
// This function loads the Mesh and ensures the Mesh has normals; it also optimizes the 
// Mesh for the graphics card's vertex cache, which improves performance by organizing 
// the internal triangle list for less cache misses.
//
HRESULT D3DMeshNode9::VOnRestore(Scene *pScene)
{
	if (m_XFileName.empty())
	{
		SetRadius(CalcBoundingSphere());
		return D3DSceneNode9::VOnRestore(pScene);
	}

	// Change post press - release the Mesh only if we have a valid Mesh file name to load.
	// Otherwise we likely created it on our own, and needs to be kept.
	SAFE_RELEASE(m_pMesh);

    WCHAR str[MAX_PATH];
    HRESULT hr;

    // Load the Mesh with D3DX and get back a ID3DXMesh*.  For this
    // sample we'll ignore the X file's embedded materials since we know 
    // exactly the model we're loading.  See the Mesh samples such as
    // "OptimizedMesh" for a more generic Mesh loading example.
	V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, m_XFileName.c_str() ) );

    V_RETURN( D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, DXUTGetD3D9Device(), NULL, NULL, NULL, NULL, &m_pMesh) );

    DWORD *rgdwAdjacency = NULL;

    // Make sure there are normals which are required for lighting
    if( !(m_pMesh->GetFVF() & D3DFVF_NORMAL) )
    {
        ID3DXMesh* pTempMesh;
        V( m_pMesh->CloneMeshFVF( m_pMesh->GetOptions(), 
                                  m_pMesh->GetFVF() | D3DFVF_NORMAL, 
                                  DXUTGetD3D9Device(), &pTempMesh ) );
        V( D3DXComputeNormals( pTempMesh, NULL ) );

        SAFE_RELEASE( m_pMesh );
        m_pMesh = pTempMesh;
    }

    // Optimize the Mesh for this graphics card's vertex cache 
    // so when rendering the Mesh's triangle list the vertices will 
    // cache hit more often so it won't have to re-execute the vertex shader 
    // on those vertices so it will improve perf.     

    rgdwAdjacency = GCC_NEW DWORD[m_pMesh->GetNumFaces() * 3];
    if( rgdwAdjacency == NULL )
        return E_OUTOFMEMORY;
    V( m_pMesh->ConvertPointRepsToAdjacency(NULL, rgdwAdjacency) );
    V( m_pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
    
	SAFE_DELETE_ARRAY(rgdwAdjacency);

	SetRadius(CalcBoundingSphere());

    return D3DSceneNode9::VOnRestore(pScene);
}
int32 GenerateSphereAsSimpleCollision(UStaticMesh* StaticMesh)
{
	if (!PromptToRemoveExistingCollision(StaticMesh))
	{
		return INDEX_NONE;
	}

	UBodySetup* bs = StaticMesh->BodySetup;

	// Calculate bounding sphere.
	FRawMesh RawMesh;
	FStaticMeshSourceModel& SrcModel = StaticMesh->SourceModels[0];
	SrcModel.RawMeshBulkData->LoadRawMesh(RawMesh);

	FSphere bSphere, bSphere2, bestSphere;
	FVector unitVec = bs->BuildScale3D;
	CalcBoundingSphere(RawMesh, bSphere, unitVec);
	CalcBoundingSphere2(RawMesh, bSphere2, unitVec);

	if(bSphere.W < bSphere2.W)
		bestSphere = bSphere;
	else
		bestSphere = bSphere2;

	// Dont use if radius is zero.
	if(bestSphere.W <= 0.f)
	{
		FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "Prompt_10", "Could not create geometry.") );
		return INDEX_NONE;
	}

	bs->Modify();

	// Create new GUID
	bs->InvalidatePhysicsData();

	FKSphereElem SphereElem;
	SphereElem.Center = bestSphere.Center;
	SphereElem.Radius = bestSphere.W;
	bs->AggGeom.SphereElems.Add(SphereElem);

	// refresh collision change back to staticmesh components
	RefreshCollisionChange(StaticMesh);

	// Mark staticmesh as dirty, to help make sure it gets saved.
	StaticMesh->MarkPackageDirty();

	StaticMesh->bCustomizedCollision = true;	//mark the static mesh for collision customization
	return bs->AggGeom.SphereElems.Num() - 1;
}
HRESULT D3DShaderMeshNode11::OnRestore(Scene* pScene)
{
	HRESULT hr;

	V_RETURN(SceneNode::OnRestore(pScene));
	V_RETURN(m_VertexShader.OnRestore(pScene));
	V_RETURN(m_PixelShader.OnRestore(pScene));

	// reload the mesh
	Resource resource(m_sdkMeshFileName);
	shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
	shared_ptr<D3DSdkMeshResourceExtraData11> extra = static_pointer_cast<D3DSdkMeshResourceExtraData11>(pResourceHandle->GetExtra());

	SetRadius(CalcBoundingSphere(&extra->m_Mesh11));

	return S_OK;
}
Esempio n. 4
0
void Exporter::CalcBoundingSphere(INode *node, Point3 center, float& radius, int all)
{
	if (nullptr == node)
		return;

	Matrix3 tm = node->GetObjTMAfterWSM(0);
	Point3 pt = (tm.GetTrans() - center);
	float len = pt.Length();

	if (node->IsBoneShowing()) {
		radius = max(len, radius);
	}
	else {
		if (Object *o = node->GetObjectRef()) {
			if (o->SuperClassID() == GEOMOBJECT_CLASS_ID) {
				if (o->ClassID() == BONE_OBJ_CLASSID
					|| o->ClassID() == Class_ID(BONE_CLASS_ID, 0)
					|| o->ClassID() == Class_ID(0x00009125, 0) /* Biped Twist Helpers */
					)
				{
					radius = max(len, radius);
				}
				else
				{
					radius = max(len, radius);
				}
			}
			else if (mExportCameras && o->SuperClassID() == CAMERA_CLASS_ID)
			{
				radius = max(len, radius);
			}
		}
	}
	if (all < 0)
		return;

	all = (all>0 ? all : -1);
	for (int i = 0; i < node->NumberOfChildren(); i++) {
		CalcBoundingSphere(node->GetChildNode(i), center, radius, all);
	}
}
Esempio n. 5
0
Bool MeshRoot::MRMGen( List<U16> * verts) // = NULL)
{
#ifndef DOMRMGEN
  verts;

  return FALSE;

#else

	// Initialize COM:
	CoInitialize(NULL);

	// Ok, Now create the mrmgen COM object:
	IMRMGen2 * s_lpMRMGen = NULL;
	HRESULT hr = CoCreateInstance(CLSID_CMRMGEN, NULL, CLSCTX_INPROC_SERVER, IID_IMRMGEN2,(void ** ) &s_lpMRMGen);

	// Did we get a valid interface:
  if( (FAILED(hr)) || (!(s_lpMRMGen)) ) 
	{
    LOG_DIAG( ("couldn't connect to mrmgen.dll; is it registered?") );
    return FALSE;
	}

  IMESH *imesh = new IMESH;
	initIMESH( imesh);

  MeshRootToIMesh( *this, *imesh);

//#define DOWRITEMRM
#ifdef DOWRITEMRM
	MRMWrite( imesh, NULL, "in.mrm");
#endif

	Utils::Memset( &params, 0, sizeof( params));
	params.size = sizeof(MRMGenParams);
	params.flags = 0;  // no parameters are valid
  params.flags |= MRMGP_MERGETHRESH | MRMGP_NORMALSMODE | MRMGP_CREASEANGLE;
  params.mergeThresh = Vid::Var::mrmMergeThresh;
  params.normalsCreaseAngle = Vid::Var::mrmNormalCrease;
 	params.normalsMode = Vid::Var::mrmMultiNormals ? PerFacePerVertex : PerVertex;

#define VERTTHRESH  0.1f

  // automatic shadow plane base verts
  //
  U32 baseCount = 0, heapSize = vertices.count << 2;
  U32 * baseIndices = (U32 *) Vid::Heap::Request( heapSize);

  if (shadowPlane)
  {
    Mesh *mesh = NULL;
    U32 i, j;
    for (i = 0; i < states.count; i++)
    {
    	if (!strnicmp(states[i].GetMeshFromRoot()->name.str, "sp-", 3))
      {
        mesh = states[i].GetMeshFromRoot();
        break;
      }
    }
    if (mesh && mesh->local)
    {
      for (i = 0; i < mesh->local->vertices.count; i++)
      {
        Vector v0;
        mesh->WorldMatrix().Transform( v0, mesh->local->vertices[i]);

        for (j = 0; j < vertices.count; j++)
        {
          Vector &v1 = vertices[j];
          if ((F32)fabs(v0.x - v1.x) < VERTTHRESH
           && (F32)fabs(v0.y - v1.y) < VERTTHRESH
           && (F32)fabs(v0.z - v1.z) < VERTTHRESH)
          {
            baseIndices[baseCount] = j;
            baseCount++;
          }
        }
      }
    }
  }

  // selected base verts
  //
  if (verts)
  {
    U32 startBaseCount = baseCount;

    List<U16>::Iterator vi( verts);
    U16 * index;
    while ((index = vi++) != NULL)
    {
      U32 i, hit = FALSE; 
      for (i = 0; i < startBaseCount; i++)
      {
        if (*index == baseIndices[i])
        {
          hit = TRUE;
          break;
        }
      }
      if (!hit)
      {
        baseIndices[baseCount] = *index;
        baseCount++;
      }
    }
  } 

  if (baseCount)
  {
    params.flags |= MRMGP_NUMBASEVERTICES;
    params.numBaseVertices = baseCount;
    params.baseVertices = baseIndices;
    LOG_DIAG( ("MeshRoot::MRMGen: baseCount = %d", baseCount) );
  }

  MRMResults *mrmResults;

  // Invoke the algorithm and collect the results:
	s_lpMRMGen->GenerateMRM(imesh, &params, &mrmResults);

  // baseIndices
  Vid::Heap::Restore( heapSize);

  MRMUpdates *mrmUpdates = mrmResults->pMrmUpdates;
  if (!mrmUpdates)
  {
    // Free memory associated with the results:
	  s_lpMRMGen->FreeMRMResults(mrmResults);

  	// Release memory:
	  freeIMESH( imesh);

  	hr = s_lpMRMGen->Release();

	// Shut down COM:
  	CoUninitialize();

    return FALSE;
  }
  IMESH *orderedImesh = mrmResults->pIMesh;

//  ASSERT( orderedImesh->numFaces == faces.count);

#ifdef DOWRITEMRM
	MRMWrite (orderedImesh, mrmUpdates, "out.mrm");
#endif

  // copy ordered geometry data, if its not empty
  //
  if ((orderedImesh->numVertices == 0 || orderedImesh->numFaces == 0) 
   || !IMeshToMeshRoot( *this, *orderedImesh, *mrmResults))
  {
    // Free memory associated with the results:
	  s_lpMRMGen->FreeMRMResults(mrmResults);

  	// Release memory:
	  freeIMESH( imesh);

  	hr = s_lpMRMGen->Release();

	// Shut down COM:
  	CoUninitialize();

    return FALSE;
  }

  if (verts)
  {
    List<U16>::Iterator vi( verts);
    U16 * index;
    while ((index = vi++) != NULL)
    {
      if (mrmResults->pVertexMap[*index] == mrmResults->undefIndexValue)
      {
        verts->Unlink( index);
      }
      else
      {
        *index = (U16) mrmResults->pVertexMap[*index];
      }
    }
  }

  // allocate mrm data
  if (mrm)
  {
    delete mrm;
    mrm = NULL;
  }

  mrm = new MRM;
  ASSERT( mrm);
  mrm->vertCount = (U16)orderedImesh->numVertices;
  mrm->maxVertCount = mrm->vertCount;
  mrm->minMinVertCount = U16(baseCount > 7 ? baseCount : 7);
  if (mrm->minMinVertCount > mrm->vertCount)
  {
    mrm->minMinVertCount = mrm->vertCount;
  }
  mrm->minVertCount = mrm->minMinVertCount;

  mrm->vertex = new MRM::Vertex[mrm->vertCount];
  ASSERT( mrm->vertex);

//#define DOWRITEDATA
#ifdef DOWRITEDATA
  FILE *fp;
  fp = fopen( "mrmdata.txt", "w");
#endif

  FaceUpdate *update;
  // count total number of faceupdates
  U32 i, j, l, k = 0;
  for (i = 0; i < mrm->vertCount; i++)
  {
    U16 numfu = mrmUpdates->vertexUpdates[i].numFaceUpdates;
#ifdef DOWRITEDATA
    fprintf( fp, "\nverts %d : newfaces %d : faceupdates %d\n", 
      i, mrmUpdates->vertexUpdates[i].numNewFaces, numfu);
#endif
    for (j = l = 0; j < numfu; j++)
    {
      update = &mrmUpdates->vertexUpdates[i].faceUpdates[j];

      // validate mrm data
	    switch (update->attribToken)
		  {
		  case VertexA:
#ifdef DOWRITEDATA
        fprintf( fp, "face %d : VertexA %d : %d\n", update->faceIndex, update->value[0], update->value[1]);
#endif
        l++;
			  break;
		  case VertexB:
#ifdef DOWRITEDATA
        fprintf( fp, "face %d : VertexB %d : %d\n", update->faceIndex, update->value[0], update->value[1]);
#endif
        l++;
			  break;
		  case VertexC:
#ifdef DOWRITEDATA
        fprintf( fp, "face %d : VertexC %d : %d\n", update->faceIndex, update->value[0], update->value[1]);
#endif
        l++;
			  break;

		  case NormalA:
#ifdef DOWRITEDATA
        fprintf( fp, "face %d : NormalA %d : %d\n", update->faceIndex, update->value[0], update->value[1]);
#endif
//        if (!indexed)
        {
          l++;
        }
			  break;
      case NormalB:
#ifdef DOWRITEDATA
        fprintf( fp, "face %d : NormalB %d : %d\n", update->faceIndex, update->value[0], update->value[1]);
#endif
//        if (!indexed)
        {
          l++;
        }
			  break;
		  case NormalC:
#ifdef DOWRITEDATA
        fprintf( fp, "face %d : NormalC %d : %d\n", update->faceIndex, update->value[0], update->value[1]);
#endif
//        if (!indexed)
        {
          l++;
        }
			  break;

		  case TexCoord1A:
#ifdef DOWRITEDATA
        fprintf( fp, "face %d : TexCrdA %d : %d\n", update->faceIndex, update->value[0], update->value[1]);
#endif
//        if (!indexed)
        {
          l++;
        }
			  break;
		  case TexCoord1B:
#ifdef DOWRITEDATA
        fprintf( fp, "face %d : TexCrdB %d : %d\n", update->faceIndex, update->value[0], update->value[1]);
#endif
//        if (!indexed)
        {
          l++;
        }
			  break;
		  case TexCoord1C:
#ifdef DOWRITEDATA
        fprintf( fp, "face %d : TexCrdC %d : %d\n", update->faceIndex, update->value[0], update->value[1]);
#endif
//        if (!indexed)
        {
          l++;
        }
			  break;
		  }
    }
    mrmUpdates->vertexUpdates[i].numFaceUpdates = (U16) l;
    k += l;
  }
#ifdef DOWRITEDATA
  if (fp)
  {
    fclose(fp);
  }
#endif

  if (k == 0)
  {
    // Free memory associated with the results:
	  s_lpMRMGen->FreeMRMResults(mrmResults);

  	// Release memory:
	  freeIMESH( imesh);

  	hr = s_lpMRMGen->Release();

	// Shut down COM:
  	CoUninitialize();


    delete [] mrm->vertex;
    delete mrm;
    mrm = NULL;

    return FALSE;
  }

  mrm->faceCount = (U16)k;
  MRM::Face *mrmFace = new MRM::Face[k];
  ASSERT( mrmFace);
  mrm->vertex[0].face = mrmFace;

  // copy mrm data
  for (i = 0; i < mrm->vertCount; i++)
  {
    U16 numfu = mrmUpdates->vertexUpdates[i].numFaceUpdates;
    mrm->vertex[i].faceCount = numfu;
//    mrmUpdates->vertexUpdates[i].numFaceUpdates = (U16) numfu;
    mrm->vertex[i].face = mrmFace;
    mrm->vertex[i].newFaceCount = mrmUpdates->vertexUpdates[i].numNewFaces;
    mrm->vertex[i].newNormCount = mrmUpdates->vertexUpdates[i].numNewNormals;
    mrm->vertex[i].newTextCount = mrmUpdates->vertexUpdates[i].numNewTexCoords;

    for (j = 0; j < numfu; j++)
    {
      // validate mrm data
      FaceUpdate &fupdate = mrmUpdates->vertexUpdates[i].faceUpdates[j];
	    switch (fupdate.attribToken)
		  {
		  case VertexA:
		  case VertexB:
		  case VertexC:
        ASSERT( fupdate.value[0] < vertices.count);
        ASSERT( fupdate.value[1] < vertices.count);

        mrmFace->token = (MRM::Face::Token) fupdate.attribToken;
        mrmFace->index[0] = (U16) fupdate.value[0];
        mrmFace->index[1] = (U16) fupdate.value[1];
        mrmFace->face = (U16) fupdate.faceIndex;
        mrmFace++;
			  break;
		  case NormalA:
		  case NormalB:
		  case NormalC:
//        if (!indexed)
        ASSERT( fupdate.value[0] < normals.count);
        ASSERT( fupdate.value[1] < normals.count);

        mrmFace->token = (MRM::Face::Token) fupdate.attribToken;
        mrmFace->index[0] = (U16) fupdate.value[0];
        mrmFace->index[1] = (U16) fupdate.value[1];
        mrmFace->face = (U16) fupdate.faceIndex;
        mrmFace++;
  		  break;
		  case TexCoord1A:
		  case TexCoord1B:
		  case TexCoord1C:
//        if (!indexed)
        ASSERT( fupdate.value[0] < uvs.count);
        ASSERT( fupdate.value[1] < uvs.count);

        mrmFace->token = (MRM::Face::Token) fupdate.attribToken;
        mrmFace->index[0] = (U16) fupdate.value[0];
        mrmFace->index[1] = (U16) fupdate.value[1];
        mrmFace->face = (U16) fupdate.faceIndex;
        mrmFace++;
			  break;
		  }
    }
  }

  // Free memory associated with the results:
	s_lpMRMGen->FreeMRMResults(mrmResults);

	// Release memory:
	freeIMESH( imesh);

	hr = s_lpMRMGen->Release();

	// Shut down COM:
	CoUninitialize();

  Setup();
	SetupPlanes();
	CalcBoundingSphere();
  SortFaces();

  return TRUE;
#endif
}