/*=========================================================================== * * DFBlocks_D3D.CPP - Dave Humphrey (uesp@m0use.net), 19 November 2000 * *=========================================================================*/ /* Include Files */ #include "dfblocks_d3d.h" #include "dfcommon_d3d.h" #include "profile.h" #undef __FUNC__ #define __FUNC__ "CDFRMBFileD3D::CreateBlockRecords()" /*=========================================================================== * * Class CDFRMBFileD3D Method - void CreateBlockRecords (void); * * Allocates the block records. A virtual and protected class method. * *=========================================================================*/ void CDFRMBFileD3D::CreateBlockRecords (void) { CreatePointerArray(pOutsideRecords, CDFRMBRecordD3D, FLDData.NumBlocks); CreatePointerArray(pInsideRecords, CDFRMBRecordD3D, FLDData.NumBlocks); } /*=========================================================================== * End of Class Method CDFRMBFile::CreateBlockRecords() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFRMBRecordD3D::Create3DObjects()" /*=========================================================================== * * Class CDFRMBRecordD3D Method - boolean Create3DObjects (pDestFrame) * * Creates and adds all the 3D Objects in the RMB record to the given * reference frame. Returns FALSE on any error. Protected class method. * *=========================================================================*/ boolean CDFRMBRecordD3D::Create3DObjects (CD3DFrame* pDestFrame) { CD3DFrame* pFrame = NULL; CD3DMeshBuilder* pBuilder; d3dbox_t Box; HRESULT Result; int LoopCounter; long ObjectID; float YPos; for (LoopCounter = 0; LoopCounter < Header.Num3DObjectRecords; LoopCounter++) { RELEASE(pFrame); /* Create the temporary reference frame */ Result = GetD3DRM()->CreateFrame(pDestFrame, &pFrame); if (FAILED(Result)) { SET_D3D_ERROR2(Result, "Failed to create block record frame!"); return (FALSE); } START_PROFILE(GetBuilder); /* Ensure the given Arch3D object ID is valid */ ObjectID = (long) (p3DObjectRecords[LoopCounter].ObjectID1*100 + p3DObjectRecords[LoopCounter].ObjectID2); pBuilder = DFArch3D.GetD3DBuilder(ObjectID); if (pBuilder == NULL) continue; END_PROFILE(GetBuilder); START_PROFILE(AddVisual); /* Add the visual mesh builder */ Result = pFrame->AddVisual(pBuilder); if (FAILED(Result)) { SET_D3D_ERROR2(Result, "Failed to add block record visual to frame!"); RELEASE(pFrame); return (FALSE); } END_PROFILE(AddVisual); pBuilder->GetBox(&Box); /* Compute the proper Y-Position for the object */ switch(p3DObjectRecords[LoopCounter].Unknown1) { case 3: YPos = -D3DVAL(p3DObjectRecords[LoopCounter].YPos2) - (Box.max.y - Box.min.y)/2; break; default: YPos = D3DVAL(p3DObjectRecords[LoopCounter].YPos2); break; } /* Set the position of object's frame */ Result = pFrame->SetPosition(pDestFrame, D3DVAL(p3DObjectRecords[LoopCounter].XPos2), YPos, D3DVAL(p3DObjectRecords[LoopCounter].ZPos2)); /* Set the rotation of the object's frame */ Result = pFrame->AddRotation(D3DRMCOMBINE_BEFORE, D3DVAL(0.0), D3DVAL(-1.0), D3DVAL(0.0), D3DVAL(p3DObjectRecords[LoopCounter].Angle)/1024.0*M_PI); SystemLog.Printf ("Item %d of %d:", LoopCounter, Header.Num3DObjectRecords); SystemLog.Printf ("\t\tUnknowns = 0x%02X 0x%08lX 0x%08lX 0x%08lX 0x%08lX 0x%08lX", p3DObjectRecords[LoopCounter].Unknown1, p3DObjectRecords[LoopCounter].Unknown2, p3DObjectRecords[LoopCounter].Unknown3, p3DObjectRecords[LoopCounter].Unknown4, p3DObjectRecords[LoopCounter].Unknown5, p3DObjectRecords[LoopCounter].Unknown6); SystemLog.Printf ("\t\tPosition = (%ld, %ld, %ld)", p3DObjectRecords[LoopCounter].XPos2, p3DObjectRecords[LoopCounter].YPos2, p3DObjectRecords[LoopCounter].ZPos2); SystemLog.Printf ("\t\tPosition1 = (%ld, %ld, %ld)", p3DObjectRecords[LoopCounter].XPos1, p3DObjectRecords[LoopCounter].YPos1, p3DObjectRecords[LoopCounter].ZPos1); } RELEASE(pFrame); return (TRUE); } /*=========================================================================== * End of Class Method CDFRMBRecordD3D::Create3DObjects() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFRMBRecordD3D::CreateFlats()" /*=========================================================================== * * Class CDFRMBRecordD3D Method - boolean CreateFlats (pDestFrame) * * Creates and adds all the Flat Objects in the RMB record to the given * reference frame. Returns FALSE on any error. Protected class method. * *=========================================================================*/ boolean CDFRMBRecordD3D::CreateFlats (CD3DFrame* pDestFrame) { CD3DFrame* pFrame = NULL; CD3DTexture* pTexture; d3dimage_t* pImageInfo; HRESULT Result; int LoopCounter; /* Add all flats to the destination frame */ for (LoopCounter = 0; LoopCounter < Header.NumFlatObjectRecords; LoopCounter++) { RELEASE(pFrame); /* Create the temporary reference frame */ Result = GetD3DRM()->CreateFrame(pDestFrame, &pFrame); if (FAILED(Result)) { SET_D3D_ERROR2(Result, "Failed to create flat object record frame!"); return (FALSE); } /* Get the decal texture */ pTexture = DFGetD3DTexture(pFlatObjectRecords[LoopCounter].TextureIndex, pFlatObjectRecords[LoopCounter].SubImageIndex); if (pTexture == NULL) continue; /* Set the decal options */ pTexture->SetDecalScale(TRUE); pTexture->SetDecalTransparency(TRUE); pTexture->SetDecalTransparentColor(D3DRGB(0,0,0)); pImageInfo = pTexture->GetImage(); ASSERT(pImageInfo != NULL); pTexture->SetDecalOrigin(pImageInfo->width/2, pImageInfo->height); pTexture->SetDecalSize(DFD3D_DECAL_SCALE(pImageInfo->width), DFD3D_DECAL_SCALE(pImageInfo->height)); /* Add the visual texture decal */ Result = pFrame->AddVisual(pTexture); if (FAILED(Result)) { SET_D3D_ERROR2(Result, "Failed to add flat record visual to frame!"); RELEASE(pFrame); return (FALSE); } /* Translate texture decal frame */ Result = pFrame->SetPosition(pDestFrame, D3DVAL(pFlatObjectRecords[LoopCounter].XPos), D3DVAL(pFlatObjectRecords[LoopCounter].YPos), D3DVAL(pFlatObjectRecords[LoopCounter].ZPos)); } RELEASE(pFrame); return (TRUE); } /*=========================================================================== * End of Class Method CDFRMBRecordD3D::CreateFlats() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFRMBRecordD3D::CreatePeople()" /*=========================================================================== * * Class CDFRMBRecordD3D Method - boolean CreatePeople (pDestFrame) * * Creates and adds all the People Objects in the RMB record to the given * reference frame. Returns FALSE on any error. Protected class method. * *=========================================================================*/ boolean CDFRMBRecordD3D::CreatePeople (CD3DFrame* pDestFrame) { CD3DFrame* pFrame = NULL; CD3DTexture* pTexture; d3dimage_t* pImageInfo; HRESULT Result; int LoopCounter; /* Add all flats to the destination frame */ for (LoopCounter = 0; LoopCounter < Header.NumPeopleRecords; LoopCounter++) { RELEASE(pFrame); /* Create the temporary reference frame */ Result = GetD3DRM()->CreateFrame(pDestFrame, &pFrame); if (FAILED(Result)) { SET_D3D_ERROR2(Result, "Failed to create people object frame!"); return (FALSE); } /* Get the decal texture */ pTexture = DFGetD3DTexture(pPeopleRecords[LoopCounter].TextureIndex, pPeopleRecords[LoopCounter].SubImageIndex); if (pTexture == NULL) continue; /* Set the decal options */ pTexture->SetDecalScale(TRUE); pTexture->SetDecalTransparency(TRUE); pTexture->SetDecalTransparentColor(D3DRGB(0,0,0)); pImageInfo = pTexture->GetImage(); ASSERT(pImageInfo != NULL); pTexture->SetDecalOrigin(pImageInfo->width/2, pImageInfo->height); pTexture->SetDecalSize(DFD3D_DECAL_SCALE(pImageInfo->width), DFD3D_DECAL_SCALE(pImageInfo->height)); /* Add the visual texture decal */ Result = pFrame->AddVisual(pTexture); if (FAILED(Result)) { SET_D3D_ERROR2(Result, "Failed to add people record visual to frame!"); RELEASE(pFrame); return (FALSE); } /* Translate texture decal frame */ Result = pFrame->SetPosition(pDestFrame, D3DVAL(pPeopleRecords[LoopCounter].XPos), D3DVAL(pPeopleRecords[LoopCounter].YPos), D3DVAL(pPeopleRecords[LoopCounter].ZPos)); } RELEASE(pFrame); return (TRUE); } /*=========================================================================== * End of Class Method CDFRMBRecordD3D::CreatePeople() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFRMBFileD3D::CreateD3DBlock()" /*=========================================================================== * * Class CDFRMBRecordD3D Method - boolean CreateD3DBlock (Flags, pDestFrame); * * Attempts to add 3D objects in the RMB record to the given frame according * to the given creation options. Returns FALSE on any error. * *=========================================================================*/ boolean CDFRMBRecordD3D::CreateD3DBlock (const dfblk_flag_t Flags, CD3DFrame* pDestFrame) { boolean Result; /* Ensure valid objects */ ASSERT(pDestFrame != NULL); ASSERT(GetD3DRM() != NULL); PROFILE_INC(); /* Add all 3D objects to the frame if required */ if (Flags & DFBLK_FLAG_3DOBJECTS) { Result = Create3DObjects(pDestFrame); if (!Result) return (FALSE); } /* Add all flat objects to the frame if required */ if (Flags & DFBLK_FLAG_FLATS) { Result = CreateFlats(pDestFrame); if (!Result) return (FALSE); } /* Add all people objects to the frame if required */ if (Flags & DFBLK_FLAG_PEOPLE) { Result = CreatePeople(pDestFrame); if (!Result) return (FALSE); } PROFILE_DEC(); return (TRUE); } /*=========================================================================== * End of Class Method CDFRMBRecordD3D::CreateD3DBlock() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFRMBFileD3D::CreateD3DBlock()" /*=========================================================================== * * Class CDFRMBFileD3D Method - boolean CreateD3DBlock (Flags, pDestFrame); * * Attempts to add 3D objects in the RMB file to the given frame according * to the given options. Returns FALSE on any error. * *=========================================================================*/ boolean CDFRMBFileD3D::CreateD3DBlock (const dfblk_flag_t Flags, CD3DFrame* pDestFrame) { CD3DFrame* pFrame = NULL; HRESULT Result = TRUE; int LoopCounter; /* Ensure valid input */ ASSERT(pDestFrame != NULL); PROFILE_INC(); /* Add all blocks to the frame */ for (LoopCounter = 0; LoopCounter < FLDData.NumBlocks; LoopCounter++) { RELEASE(pFrame); START_PROFILE(CreateFrame); /* Create the temporary reference frame */ Result = GetD3DRM()->CreateFrame(pDestFrame, &pFrame); if (FAILED(Result)) { SET_D3D_ERROR2(Result, "Failed to create block record frame!"); return (FALSE); } END_PROFILE(CreateFrame); START_PROFILE(CreateOutsideBlock); /* Add the outside blocks */ if (Flags & DFBLK_FLAG_OUTSIDE) { Result = ((CDFRMBRecordD3D *)pOutsideRecords)[LoopCounter].CreateD3DBlock(Flags, pFrame); if (!Result) break; } END_PROFILE(CreateOutsideBlock); START_PROFILE(CreateInsideBlock); /* Add the inside blocks */ if (Flags & DFBLK_FLAG_INSIDE) { Result = ((CDFRMBRecordD3D *)pInsideRecords)[LoopCounter].CreateD3DBlock(Flags, pFrame); if (!Result) break; } END_PROFILE(CreateInsideBlock); /* Set the appropriate frame position */ Result = pFrame->SetPosition(pDestFrame, D3DVAL(FLDData.PositionRecords[LoopCounter].XPos), D3DVAL(-200.0), D3DVAL(FLDData.PositionRecords[LoopCounter].ZPos)); } PROFILE_DEC(); RELEASE(pFrame); return ((boolean)Result); } /*=========================================================================== * End of Class Method CDFRMBFileD3D::CreateD3DBlock() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFRMBFileD3D::CreateRMBFile()" /*=========================================================================== * * Class CDFBlocksFileD3D Method - void CreateRMBFile (Index); * * Attempts to create a new RMBFile object in the given array index. Protected * class method. * *=========================================================================*/ void CDFBlocksFileD3D::CreateRMBFile (const int Index) { /* Unallocate if already allocated */ DestroyPointer(pRecords[Index]); /* Create new pointer */ CreatePointer(pRecords[Index], CDFRMBFileD3D); } /*=========================================================================== * End of Class Method CDFBlocksFileD3D::CreateRMBFile() *=========================================================================*/