Exemple #1
0
static sfx_t *S_FindName(const char *name, bool create)
{
	guard(S_FindName);

	int		i;
	sfx_t	*sfx;

	if (!name)		appError("NULL name\n");
	if (!name[0])	appError("empty name\n");
	if (strlen(name) >= MAX_QPATH) appError("Sound name too long: %s", name);

	TString<MAX_QPATH> Filename;
	Filename.filename(name);

	// see if already loaded
	for (i = 0, sfx = known_sfx; i < num_sfx; i++, sfx++)
		if (sfx->Name == Filename)
			return sfx;

	if (!create)
		return NULL;

	// find a free sfx
	for (i = 0, sfx = known_sfx; i < num_sfx; i++, sfx++)
		if (!sfx->Name[0])
			break;

	if (i == num_sfx)
	{
		// not found
		if (num_sfx == MAX_SFX)
		{
#if 0
			appError("too much sfx records");
#else
			Com_DPrintf("too much sfx records\n");
			return NULL;
#endif
		}
		// alloc next free record
		num_sfx++;
	}

	memset(sfx, 0, sizeof(*sfx));
	sfx->Name = Filename;
	sfx->registration_sequence = s_registration_sequence;
	return sfx;

	unguard;
}
Exemple #2
0
static void appDecompressLZX(byte *CompressedBuffer, int CompressedSize, byte *UncompressedBuffer, int UncompressedSize)
{
	guard(appDecompressLZX);

	// setup streams
	mspack_file src, dst;
	src.buf     = CompressedBuffer;
	src.bufSize = CompressedSize;
	src.pos     = 0;
	src.rest    = 0;
	dst.buf     = UncompressedBuffer;
	dst.bufSize = UncompressedSize;
	dst.pos     = 0;
	// prepare decompressor
	lzxd_stream *lzxd = lzxd_init(&lzxSys, &src, &dst, 17, 0, 256*1024, UncompressedSize);
	assert(lzxd);
	// decompress
	int r = lzxd_decompress(lzxd, UncompressedSize);
	if (r != MSPACK_ERR_OK)
		appError("lzxd_decompress(%d,%d) returned %d", CompressedSize, UncompressedSize, r);
	// free resources
	lzxd_free(lzxd);

	unguard;
}
Exemple #3
0
static sfx_t *S_AliasName(const char *aliasname, const char *truename)
{
	guard(S_AliasName);

	// find a free sfx
	sfx_t	*sfx;
	int		i;
	for (i = 0, sfx = known_sfx; i < num_sfx; i++, sfx++)
		if (!sfx->Name[0])
			break;

	if (i == num_sfx)
	{
		if (num_sfx == MAX_SFX)
		{
#if 0
			appError("too much sfx records");
#else
			Com_DPrintf("too much sfx records\n");
			return NULL;
#endif
		}
		num_sfx++;
	}

	memset(sfx, 0, sizeof(*sfx));
	sfx->Name.filename(aliasname);
	sfx->TrueName = truename;
	sfx->registration_sequence = s_registration_sequence;
	return sfx;

	unguard;
}
Exemple #4
0
void UMeshAnimation::SerializeSCell(FArchive &Ar)
{
	guard(SerializeSCell);

	// for logic of track decompression check UMeshAnimation::Moves() function
	int OldCompression = 0, CompressType = 0;
	TArray<MotionChunkFixedPoint>					T0;		// OldCompression!=0, CompressType=0
	TArray<MotionChunkCompress<Quat16Track> >		T1;		// CompressType=1
	TArray<MotionChunkCompress<FixPosTrack> >		T2;		// CompressType=2
	TArray<MotionChunkCompress<FixTimeTrack> >		T3;		// CompressType=3
	TArray<MotionChunkCompress<FixPosTimeTrack> >	T4;		// CompressType=4
	if (Version >= 1000)
	{
		Ar << OldCompression << T0;
		// note: this compression type is not supported (absent BoneIndices in MotionChunkFixedPoint)
	}
	if (Version >= 2000)
	{
		Ar << CompressType << T1 << T2 << T3 << T4;
		// decompress motion
		if (CompressType)
		{
			int i = 0, Count = 1;
			while (i < Count)
			{
				MotionChunkCompressBase *M = NULL;
				switch (CompressType)
				{
				case 1: Count = T1.Num(); M = &T1[i]; break;
				case 2: Count = T2.Num(); M = &T2[i]; break;
				case 3: Count = T3.Num(); M = &T3[i]; break;
				case 4: Count = T4.Num(); M = &T4[i]; break;
				default:
					appError("Unsupported CompressType: %d", CompressType);
				}
				if (!Count)
				{
					appNotify("CompressType=%d with no tracks", CompressType);
					break;
				}
				if (!i)
				{
					// 1st iteration, prepare Moves[] array
					Moves.Empty(Count);
					Moves.AddZeroed(Count);
				}
				// decompress current track
				M->Decompress(Moves[i]);
				// next track
				i++;
			}
		}
	}
//	if (OldCompression) appNotify("OldCompression=%d", OldCompression, CompressType);

	unguard;
}
Exemple #5
0
FArchive& operator<<(FArchive &Ar, FCompactIndex &I)
{
#if UNREAL3
	if (Ar.Engine() >= GAME_UE3) appError("FCompactIndex is missing in UE3");
#endif
	if (Ar.IsLoading)
	{
		byte b;
		Ar << b;
		int sign  = b & 0x80;	// sign bit
		int shift = 6;
		int r     = b & 0x3F;
		if (b & 0x40)			// has 2nd byte
		{
			do
			{
				Ar << b;
				r |= (b & 0x7F) << shift;
				shift += 7;
			} while (b & 0x80);	// has more bytes
		}
		I.Value = sign ? -r : r;
	}
	else
	{
		int v = I.Value;
		byte b = 0;
		if (v < 0)
		{
			v = -v;
			b |= 0x80;			// sign
		}
		b |= v & 0x3F;
		if (v <= 0x3F)
		{
			Ar << b;
		}
		else
		{
			b |= 0x40;			// has 2nd byte
			v >>= 6;
			Ar << b;
			assert(v);
			while (v)
			{
				b = v & 0x7F;
				v >>= 7;
				if (v)
					b |= 0x80;	// has more bytes
				Ar << b;
			}
		}
	}
	return Ar;
}
Exemple #6
0
static menuCommon_t *GetItem(menuFramework_t *menu, int index)
{
	int		i;
	menuCommon_t *item;

	for (i = 0, item = menu->itemList; i < index && item; i++, item = item->next) ;

	if (!item)
		appError("GetMenuItem: item index %d is out of bounds %d\n", index, menu->nitems);

	return item;
}
Exemple #7
0
static void SortBoneArray(CBoneProxy *Parent, int NumBones)
{
	for (int i = 0; i < NumBones; i++)
	{
		CBoneProxy *Bone = &Bones[i];
		if (Bone->Parent == Parent)
		{
			if (NumSortedBones >= NumBones) appError("Loop in skeleton");
			SortedBones[NumSortedBones++] = Bone;
			SortBoneArray(Bone, NumBones);
		}
	}
}
Exemple #8
0
void SetApp::mouseReleaseEvent ( QMouseEvent * event )
{
    qDebug() <<"mr" ;

    //进入应用程序管理状态后,再次点击鼠标会崩溃
    //apptimer的释放问题
    if(appTimer != NULL && appTimer->isActive())
    {
        appTimer->stop();
        delete appTimer;
        appTimer = NULL;
    }

    if(appManagerStatus == true && readyRun == true)
    {

        qDebug() << "delete " << appName << "?";

        uninstallAppMessageBox();

    }
    else
    {
        if(readyRun == true)
        {


            qDebug() << "start up "<< appName;
            if (appStatus == 1)
            {
                qDebug() << "app is running!";
            }else{
                appProcess = new QProcess();
                appProcess->start(appFullPath);
                appProcess->setWorkingDirectory(appWorkingDirectory);
                connect(appProcess,SIGNAL(started()),this,SLOT(appRunning()));
                connect(appProcess,SIGNAL(finished(int)),this,SLOT(appExiting()));
                connect(appProcess,SIGNAL(destroyed()),this,SLOT(appClear()));
                connect(appProcess,SIGNAL(error(QProcess::ProcessError)),this,SLOT(appError()));
                qDebug() << appProcess;

            }
        }
    }
Exemple #9
0
int main(int argc, char **argv) {
  int i;
  struct timeval startTime, endTime;

  if (argc != 3)
    usage(argv[0]);

  // Record start of total time
  gettimeofday(&startTime, NULL);

  // Initialize global variables and data-structures.
  P = atoi(argv[1]);
  initialize(argv[2], &cells, &constraints);
  nodeCount = 0;
  found = 0;

  jobQueues = (job_queue_t*)calloc(sizeof(job_queue_t), P);
  if (!jobQueues)
    unixError("Failed to allocated memory for the job queues");

  for (i = 0; i < P; i++)
    omp_init_lock(&(jobQueues[i].headLock));

  // Add initial job (nothing assigned) to root processor
  jobQueues[0].tail = 1;


  runParallel(P);
  if (!found)
    appError("No solution found");

  // Use final time to calculate total time
  gettimeofday(&endTime, NULL);
  totalTime = TIME_DIFF(endTime, startTime);

  // Print out number of nodes visited and calculated times
  printf("Nodes Visited: %lld\n", nodeCount);
  printf("Computation Time = %.3f millisecs\n", compTime);
  printf("      Total Time = %.3f millisecs\n", totalTime);

  return 0;
}
Exemple #10
0
void GL_SetMultitexture(int level)
{
	int		i;

	if (level > gl_config.maxActiveTextures)
		appError("R_SetMultitexture(%d > %d)", level, gl_config.maxActiveTextures);

	if (gl_state.locked)
	{
		for (i = 0; i < gl_config.maxActiveTextures; i++)
			if (i < level)
			{
				gl_state.newTexCoordEnabled[i] = true;
			}
			else
			{
				gl_state.newTexCoordEnabled[i] = false;
				gl_state.newTextureTarget[i] = 0;
			}
		return;
	}

	for (i = level; i < gl_config.maxActiveTextures; i++)
		if (gl_state.textureTarget[i] || gl_state.texCoordEnabled[i])
		{
			GL_SelectTexture(i);
			GL_Bind(NULL);
			if (gl_state.texCoordEnabled[i])
			{
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
				gl_state.texCoordEnabled[i] = false;
			}
		}
	for (i = level - 1; i >= 0; i--)
		if (!gl_state.texCoordEnabled[i])
		{
			GL_SelectTexture(i);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			gl_state.texCoordEnabled[i] = true;
		}
	GL_SelectTexture(0);
}
Exemple #11
0
void GL_CheckError(const char *msg)
{
	GLenum err = glGetError();
	if (!err) return;
	appError("%s error %X", msg ? msg : "OpenGL", err);
}
Exemple #12
0
int UE4UnversionedPackage(int verMin, int verMax)
{
	appError("Unversioned UE4 packages are not supported. Please restart UModel and select UE4 version in range %d-%d using UI or command line.", verMin, verMax);
	return -1;
}
Exemple #13
0
int appDecompress(byte *CompressedBuffer, int CompressedSize, byte *UncompressedBuffer, int UncompressedSize, int Flags)
{
	guard(appDecompress);

#if BLADENSOUL
	if (GForceGame == GAME_BladeNSoul && Flags == COMPRESS_LZO_ENC)	// note: GForceGame is required (to not pass 'Game' here)
	{
		if (CompressedSize >= 32)
		{
			static const char *key = "qiffjdlerdoqymvketdcl0er2subioxq";
			for (int i = 0; i < CompressedSize; i++)
				CompressedBuffer[i] ^= key[i % 32];
		}
		// overide compression
		Flags = COMPRESS_LZO;
	}
#endif // BLADENSOUL

#if TAO_YUAN
	if (GForceGame == GAME_TaoYuan)	// note: GForceGame is required (to not pass 'Game' here);
	{
		static const byte key[] =
		{
			137, 35, 95, 142, 69, 136, 243, 119, 25, 35, 111, 94, 101, 136, 243, 204,
			243, 67, 95, 158, 69, 106, 107, 187, 237, 35, 103, 142, 72, 142, 243
		};
		for (int i = 0; i < CompressedSize; i++)
			CompressedBuffer[i] ^= key[i % 31];		// note: "N % 31" is not the same as "N & 0x1F"
	}
#endif // TAO_YUAN

#if ALICE
	// this code exists in Alice: Madness Returns only
	if (GForceGame == GAME_Alice && CompressedSize == UncompressedSize)
	{
		// CompressedSize == UncompressedSize -> no compression
		memcpy(UncompressedBuffer, CompressedBuffer, UncompressedSize);
		return UncompressedSize;
	}
#endif // ALICE

	if (Flags == COMPRESS_FIND && CompressedSize >= 2)
	{
		byte b1 = CompressedBuffer[0];
		byte b2 = CompressedBuffer[1];
		// detect compression
		// zlib:
		//   http://tools.ietf.org/html/rfc1950
		//   http://stackoverflow.com/questions/9050260/what-does-a-zlib-header-look-like
		if ( b1 == 0x78 &&					// b1=CMF: 7=32k buffer (CINFO), 8=deflate (CM)
			(b2 == 0x9C || b2 == 0xDA) )	// b2=FLG
		{
			Flags = COMPRESS_ZLIB;
		}
		else
			Flags = COMPRESS_LZO;
	}

	if (Flags == COMPRESS_LZO)
	{
		int r;
		r = lzo_init();
		if (r != LZO_E_OK) appError("lzo_init() returned %d", r);
		lzo_uint newLen = UncompressedSize;
		r = lzo1x_decompress_safe(CompressedBuffer, CompressedSize, UncompressedBuffer, &newLen, NULL);
		if (r != LZO_E_OK) appError("lzo_decompress(%d,%d) returned %d", CompressedSize, UncompressedSize, r);
		if (newLen != UncompressedSize) appError("len mismatch: %d != %d", newLen, UncompressedSize);
		return newLen;
	}

	if (Flags == COMPRESS_ZLIB)
	{
#if 0
		appError("appDecompress: Zlib compression is not supported");
#else
		unsigned long newLen = UncompressedSize;
		int r = uncompress(UncompressedBuffer, &newLen, CompressedBuffer, CompressedSize);
		if (r != Z_OK) appError("zlib uncompress(%d,%d) returned %d", CompressedSize, UncompressedSize, r);
//		if (newLen != UncompressedSize) appError("len mismatch: %d != %d", newLen, UncompressedSize); -- needed by Bioshock
		return newLen;
#endif
	}

	if (Flags == COMPRESS_LZX)
	{
#if SUPPORT_XBOX360
#	if !USE_XDK
		appDecompressLZX(CompressedBuffer, CompressedSize, UncompressedBuffer, UncompressedSize);
		return UncompressedSize;
#	else
		void *context;
		int r;
		r = XMemCreateDecompressionContext(0, NULL, 0, &context);
		if (r < 0) appError("XMemCreateDecompressionContext failed");
		unsigned int newLen = UncompressedSize;
		r = XMemDecompress(context, UncompressedBuffer, &newLen, CompressedBuffer, CompressedSize);
		if (r < 0) appError("XMemDecompress failed");
		if (newLen != UncompressedSize) appError("len mismatch: %d != %d", newLen, UncompressedSize);
		XMemDestroyDecompressionContext(context);
		return newLen;
#	endif // USE_XDK
#else  // SUPPORT_XBOX360
		appError("appDecompress: LZX compression is not supported");
#endif // SUPPORT_XBOX360
	}

	appError("appDecompress: unknown compression flags: %d", Flags);
	return 0;

	unguardf("CompSize=%d UncompSize=%d Flags=0x%X", CompressedSize, UncompressedSize, Flags);
}
Exemple #14
0
void USkeleton::ConvertAnims(UAnimSequence4* Seq)
{
	guard(USkeleton::ConvertAnims);

	CAnimSet* AnimSet = ConvertedAnim;

	if (!AnimSet)
	{
		AnimSet = new CAnimSet(this);
		ConvertedAnim = AnimSet;

		// Copy bone names
		AnimSet->TrackBoneNames.Empty(ReferenceSkeleton.RefBoneInfo.Num());
		for (int i = 0; i < ReferenceSkeleton.RefBoneInfo.Num(); i++)
		{
			AnimSet->TrackBoneNames.Add(ReferenceSkeleton.RefBoneInfo[i].Name);
		}

		//TODO: verify if UE4 has AnimRotationOnly stuff
		AnimSet->AnimRotationOnly = false;
	}

	if (!Seq) return; // allow calling ConvertAnims(NULL) to create empty AnimSet

//	DBG("----------- Skeleton %s: %d seq, %d bones -----------\n", Name, Anims.Num(), ReferenceSkeleton.RefBoneInfo.Num());

	int NumTracks = Seq->GetNumTracks();

#if DEBUG_DECOMPRESS
	appPrintf("Sequence %s: %d bones, %d offsets (%g per bone), %d frames, %d compressed data\n"
		   "          trans %s, rot %s, scale %s, key %s\n",
		Seq->Name, NumTracks, Seq->CompressedTrackOffsets.Num(), Seq->CompressedTrackOffsets.Num() / (float)NumTracks,
		Seq->NumFrames, Seq->CompressedByteStream.Num(),
		EnumToName(Seq->TranslationCompressionFormat),
		EnumToName(Seq->RotationCompressionFormat),
		EnumToName(Seq->ScaleCompressionFormat),
		EnumToName(Seq->KeyEncodingFormat)
	);
	for (int i2 = 0; i2 < Seq->CompressedTrackOffsets.Num(); /*empty*/)
	{
		if (Seq->KeyEncodingFormat != AKF_PerTrackCompression)
		{
			FName BoneName = ReferenceSkeleton.RefBoneInfo[Seq->GetTrackBoneIndex(i2/4)].Name;
			int TransOffset = Seq->CompressedTrackOffsets[i2  ];
			int TransKeys   = Seq->CompressedTrackOffsets[i2+1];
			int RotOffset   = Seq->CompressedTrackOffsets[i2+2];
			int RotKeys     = Seq->CompressedTrackOffsets[i2+3];
			appPrintf("    [%d] = trans %d[%d] rot %d[%d] - %s\n", i2/4, TransOffset, TransKeys, RotOffset, RotKeys, *BoneName);
			i2 += 4;
		}
		else
		{
			FName BoneName = ReferenceSkeleton.RefBoneInfo[Seq->GetTrackBoneIndex(i2/2)].Name;
			int TransOffset = Seq->CompressedTrackOffsets[i2  ];
			int RotOffset   = Seq->CompressedTrackOffsets[i2+1];
			appPrintf("    [%d] = trans %d rot %d - %s\n", i2/2, TransOffset, RotOffset, *BoneName);
			i2 += 2;
		}
	}
#endif // DEBUG_DECOMPRESS

	// some checks
	int offsetsPerBone = 4;
	if (Seq->KeyEncodingFormat == AKF_PerTrackCompression)
		offsetsPerBone = 2;

	if (Seq->CompressedTrackOffsets.Num() != NumTracks * offsetsPerBone && !Seq->RawAnimationData.Num())
	{
		appNotify("AnimSequence %s has wrong CompressedTrackOffsets size (has %d, expected %d), removing track",
			Seq->Name, Seq->CompressedTrackOffsets.Num(), NumTracks * offsetsPerBone);
		return;
	}

	// create CAnimSequence
	CAnimSequence *Dst = new CAnimSequence;
	AnimSet->Sequences.Add(Dst);
	Dst->Name      = Seq->Name;
	Dst->NumFrames = Seq->NumFrames;
	Dst->Rate      = Seq->NumFrames / Seq->SequenceLength * Seq->RateScale;

	// bone tracks ...
	Dst->Tracks.Empty(NumTracks);

	FMemReader Reader(Seq->CompressedByteStream.GetData(), Seq->CompressedByteStream.Num());
	Reader.SetupFrom(*Package);

	bool HasTimeTracks = (Seq->KeyEncodingFormat == AKF_VariableKeyLerp);

	for (int BoneIndex = 0; BoneIndex < ReferenceSkeleton.RefBoneInfo.Num(); BoneIndex++)
	{
		CAnimTrack *A = new (Dst->Tracks) CAnimTrack;
		int TrackIndex = Seq->FindTrackForBoneIndex(BoneIndex);

		if (TrackIndex < 0)
		{
			// this track has no animation, use static pose from ReferenceSkeleton
			const FTransform& RefPose = ReferenceSkeleton.RefBonePose[BoneIndex];
			A->KeyPos.Add(CVT(RefPose.Translation));
			A->KeyQuat.Add(CVT(RefPose.Rotation));
			//!! RefPose.Scale3D
			continue;
		}

		int k;

		if (!Seq->CompressedTrackOffsets.Num())	//?? or if RawAnimData.Num() != 0
		{
			// using RawAnimData array
			assert(Seq->RawAnimationData.Num() == NumTracks);
			CopyArray(A->KeyPos,  CVT(Seq->RawAnimationData[TrackIndex].PosKeys));
			CopyArray(A->KeyQuat, CVT(Seq->RawAnimationData[TrackIndex].RotKeys));
			CopyArray(A->KeyTime, Seq->RawAnimationData[TrackIndex].KeyTimes);	// may be empty
			for (int k = 0; k < A->KeyTime.Num(); k++)
				A->KeyTime[k] *= Dst->Rate;
			continue;
		}

		FVector Mins, Ranges;	// common ...
		static const CVec3 nullVec  = { 0, 0, 0 };
		static const CQuat nullQuat = { 0, 0, 0, 1 };

		int offsetIndex = TrackIndex * offsetsPerBone;

		// PARAGON has invalid data inside some animation tracks. Not sure if game engine ignores them
		// or trying to process (this game has holes in data due to wrong pointers in CompressedTrackOffsets).
		// This causes garbage data to appear instead of real animation track header, with wrong compression
		// method etc. We're going to skip such tracks with displaying a warning message.
		if (0) // this is just a placeholder for error handler - it should be located somewhere
		{
		track_error:
			AnimSet->Sequences.RemoveSingle(Dst);
			delete Dst;
			return;
		}

		//----------------------------------------------
		// decode AKF_PerTrackCompression data
		//----------------------------------------------
		if (Seq->KeyEncodingFormat == AKF_PerTrackCompression)
		{
			// this format uses different key storage
			guard(PerTrackCompression);
			assert(Seq->TranslationCompressionFormat == ACF_Identity);
			assert(Seq->RotationCompressionFormat == ACF_Identity);

			int TransOffset = Seq->CompressedTrackOffsets[offsetIndex  ];
			int RotOffset   = Seq->CompressedTrackOffsets[offsetIndex+1];

			uint32 PackedInfo;
			AnimationCompressionFormat KeyFormat;
			int ComponentMask;
			int NumKeys;

#define DECODE_PER_TRACK_INFO(info)									\
			KeyFormat = (AnimationCompressionFormat)(info >> 28);	\
			ComponentMask = (info >> 24) & 0xF;						\
			NumKeys       = info & 0xFFFFFF;						\
			HasTimeTracks = (ComponentMask & 8) != 0;

			guard(TransKeys);
			// read translation keys
			if (TransOffset == -1)
			{
				A->KeyPos.Add(nullVec);
				DBG("    [%d] no translation data\n", TrackIndex);
			}
			else
			{
				Reader.Seek(TransOffset);
				Reader << PackedInfo;
				DECODE_PER_TRACK_INFO(PackedInfo);
				A->KeyPos.Empty(NumKeys);
				DBG("    [%d] trans: fmt=%d (%s), %d keys, mask %d\n", TrackIndex,
					KeyFormat, EnumToName(KeyFormat), NumKeys, ComponentMask
				);
				if (KeyFormat == ACF_IntervalFixed32NoW)
				{
					// read mins/maxs
					Mins.Set(0, 0, 0);
					Ranges.Set(0, 0, 0);
					if (ComponentMask & 1) Reader << Mins.X << Ranges.X;
					if (ComponentMask & 2) Reader << Mins.Y << Ranges.Y;
					if (ComponentMask & 4) Reader << Mins.Z << Ranges.Z;
				}
				for (k = 0; k < NumKeys; k++)
				{
					switch (KeyFormat)
					{
//					case ACF_None:
					case ACF_Float96NoW:
						{
							FVector v;
							if (ComponentMask & 7)
							{
								v.Set(0, 0, 0);
								if (ComponentMask & 1) Reader << v.X;
								if (ComponentMask & 2) Reader << v.Y;
								if (ComponentMask & 4) Reader << v.Z;
							}
							else
							{
								// ACF_Float96NoW has a special case for ((ComponentMask & 7) == 0)
								Reader << v;
							}
							A->KeyPos.Add(CVT(v));
						}
						break;
					TPR(ACF_IntervalFixed32NoW, FVectorIntervalFixed32)
					case ACF_Fixed48NoW:
						{
							uint16 X, Y, Z;
							CVec3 v;
							v.Set(0, 0, 0);
							if (ComponentMask & 1)
							{
								Reader << X; v[0] = DecodeFixed48_PerTrackComponent<7>(X);
							}
							if (ComponentMask & 2)
							{
								Reader << Y; v[1] = DecodeFixed48_PerTrackComponent<7>(Y);
							}
							if (ComponentMask & 4)
							{
								Reader << Z; v[2] = DecodeFixed48_PerTrackComponent<7>(Z);
							}
							A->KeyPos.Add(v);
						}
						break;
					case ACF_Identity:
						A->KeyPos.Add(nullVec);
						break;
					default:
						{
							char buf[1024];
							Seq->GetFullName(buf, 1024);
							appNotify("%s: unknown translation compression method: %d (%s) - dropping track", buf, KeyFormat, EnumToName(KeyFormat));
							goto track_error;
						}
					}
				}
				// align to 4 bytes
				Reader.Seek(Align(Reader.Tell(), 4));
				if (HasTimeTracks)
					ReadTimeArray(Reader, NumKeys, A->KeyPosTime, Seq->NumFrames);
			}
			unguard;

			guard(RotKeys);
			// read rotation keys
			if (RotOffset == -1)
			{
				A->KeyQuat.Add(nullQuat);
				DBG("    [%d] no rotation data\n", TrackIndex);
			}
			else
			{
				Reader.Seek(RotOffset);
				Reader << PackedInfo;
				DECODE_PER_TRACK_INFO(PackedInfo);
				A->KeyQuat.Empty(NumKeys);
				DBG("    [%d] rot  : fmt=%d (%s), %d keys, mask %d\n", TrackIndex,
					KeyFormat, EnumToName(KeyFormat), NumKeys, ComponentMask
				);
				if (KeyFormat == ACF_IntervalFixed32NoW)
				{
					// read mins/maxs
					Mins.Set(0, 0, 0);
					Ranges.Set(0, 0, 0);
					if (ComponentMask & 1) Reader << Mins.X << Ranges.X;
					if (ComponentMask & 2) Reader << Mins.Y << Ranges.Y;
					if (ComponentMask & 4) Reader << Mins.Z << Ranges.Z;
				}
				for (k = 0; k < NumKeys; k++)
				{
					switch (KeyFormat)
					{
//					TR (ACF_None, FQuat)
					case ACF_Float96NoW:
						{
							FQuatFloat96NoW q;
							Reader << q;
							FQuat q2 = q;				// convert
							A->KeyQuat.Add(CVT(q2));
						}
						break;
					case ACF_Fixed48NoW:
						{
							FQuatFixed48NoW q;
							q.X = q.Y = q.Z = 32767;	// corresponds to 0
							if (ComponentMask & 1) Reader << q.X;
							if (ComponentMask & 2) Reader << q.Y;
							if (ComponentMask & 4) Reader << q.Z;
							FQuat q2 = q;				// convert
							A->KeyQuat.Add(CVT(q2));
						}
						break;
					TR (ACF_Fixed32NoW, FQuatFixed32NoW)
					TRR(ACF_IntervalFixed32NoW, FQuatIntervalFixed32NoW)
					TR (ACF_Float32NoW, FQuatFloat32NoW)
					case ACF_Identity:
						A->KeyQuat.Add(nullQuat);
						break;
					default:
						{
							char buf[1024];
							Seq->GetFullName(buf, 1024);
							appNotify("%s: unknown rotation compression method: %d (%s) - dropping track", buf, KeyFormat, EnumToName(KeyFormat));
							goto track_error;
						}
					}
				}
				// align to 4 bytes
				Reader.Seek(Align(Reader.Tell(), 4));
				if (HasTimeTracks)
					ReadTimeArray(Reader, NumKeys, A->KeyQuatTime, Seq->NumFrames);
			}
			unguard;

			unguard;
			continue;
			// end of AKF_PerTrackCompression block ...
		}

		//----------------------------------------------
		// end of AKF_PerTrackCompression decoder
		//----------------------------------------------

		// read animations
		int TransOffset = Seq->CompressedTrackOffsets[offsetIndex  ];
		int TransKeys   = Seq->CompressedTrackOffsets[offsetIndex+1];
		int RotOffset   = Seq->CompressedTrackOffsets[offsetIndex+2];
		int RotKeys     = Seq->CompressedTrackOffsets[offsetIndex+3];
//		appPrintf("[%d:%d:%d] :  %d[%d]  %d[%d]  %d[%d]\n", j, Seq->RotationCompressionFormat, Seq->TranslationCompressionFormat, TransOffset, TransKeys, RotOffset, RotKeys, ScaleOffset, ScaleKeys);

		A->KeyPos.Empty(TransKeys);
		A->KeyQuat.Empty(RotKeys);

		// read translation keys
		if (TransKeys)
		{
			Reader.Seek(TransOffset);
			AnimationCompressionFormat TranslationCompressionFormat = Seq->TranslationCompressionFormat;
			if (TransKeys == 1)
				TranslationCompressionFormat = ACF_None;	// single key is stored without compression
			// read mins/ranges
			if (TranslationCompressionFormat == ACF_IntervalFixed32NoW)
			{
				Reader << Mins << Ranges;
			}

			for (k = 0; k < TransKeys; k++)
			{
				switch (TranslationCompressionFormat)
				{
				TP (ACF_None,               FVector)
				TP (ACF_Float96NoW,         FVector)
				TPR(ACF_IntervalFixed32NoW, FVectorIntervalFixed32)
				TP (ACF_Fixed48NoW,         FVectorFixed48)
				case ACF_Identity:
					A->KeyPos.Add(nullVec);
					break;
				default:
					appError("Unknown translation compression method: %d (%s)", TranslationCompressionFormat, EnumToName(TranslationCompressionFormat));
				}
			}

			// align to 4 bytes
			Reader.Seek(Align(Reader.Tell(), 4));
			if (HasTimeTracks)
				ReadTimeArray(Reader, TransKeys, A->KeyPosTime, Seq->NumFrames);
		}
		else
		{
//			A->KeyPos.Add(nullVec);
//			appNotify("No translation keys!");
		}
Exemple #15
0
static bool RegisterGameFile(const char *FullName, FVirtualFileSystem* parentVfs = NULL)
{
	guard(RegisterGameFile);

//	printf("..file %s\n", FullName);
	// return false when MAX_GAME_FILES
	if (GNumGameFiles >= ARRAY_COUNT(GameFiles))
		return false;

	if (!parentVfs)		// no nested VFSs
	{
		const char* ext = strrchr(FullName, '.');
		if (ext)
		{
			guard(MountVFS);

			ext++;
			FVirtualFileSystem* vfs = NULL;
			FArchive* reader = NULL;

#if SUPPORT_ANDROID
			if (!stricmp(ext, "obb"))
			{
				GForcePlatform = PLATFORM_ANDROID;
				reader = new FFileReader(FullName);
				if (!reader) return true;
				reader->Game = GAME_UE3;
				vfs = new FObbVFS();
			}
#endif // SUPPORT_ANDROID
#if UNREAL4
			if (!stricmp(ext, "pak"))
			{
				reader = new FFileReader(FullName);
				if (!reader) return true;
				reader->Game = GAME_UE4;
				vfs = new FPakVFS();
				//!! detect game by file name
			}
#endif // UNREAL4
			//!! process other VFS types here
			if (vfs)
			{
				assert(reader);
				// read VF directory
				if (!vfs->AttachReader(reader))
				{
					// something goes wrong
					delete vfs;
					delete reader;
					return true;
				}
				// add game files
				int NumVFSFiles = vfs->NumFiles();
				for (int i = 0; i < NumVFSFiles; i++)
				{
					if (!RegisterGameFile(vfs->FileName(i), vfs))
						return false;
				}
				return true;
			}

			unguard;
		}
	}

	bool IsPackage;
	if (FindExtension(FullName, ARRAY_ARG(PackageExtensions)))
	{
		IsPackage = true;
	}
	else
	{
#if HAS_SUPORT_FILES
		if (!FindExtension(FullName, ARRAY_ARG(KnownExtensions)))
#endif
		{
			// perhaps this file was exported by our tool - skip it
			if (FindExtension(FullName, ARRAY_ARG(SkipExtensions)))
				return true;
			// unknown file type
			if (++GNumForeignFiles >= MAX_FOREIGN_FILES)
				appError("Too much unknown files - bad root directory (%s)?", RootDirectory);
			return true;
		}
		IsPackage = false;
	}

	// create entry
	CGameFileInfo *info = new CGameFileInfo;
	GameFiles[GNumGameFiles++] = info;
	info->IsPackage = IsPackage;
	info->FileSystem = parentVfs;
	if (IsPackage) GNumPackageFiles++;

	if (!parentVfs)
	{
		// regular file
		FILE* f = fopen(FullName, "rb");
		if (f)
		{
			fseek(f, 0, SEEK_END);
			info->SizeInKb = (ftell(f) + 512) / 1024;
			fclose(f);
		}
		else
		{
			info->SizeInKb = 0;
		}
		// cut RootDirectory from filename
		const char *s = FullName + strlen(RootDirectory) + 1;
		assert(s[-1] == '/');
		appStrncpyz(info->RelativeName, s, ARRAY_COUNT(info->RelativeName));
	}
	else
	{
		// file in virtual file system
		info->SizeInKb = parentVfs->GetFileSize(FullName);
		appStrncpyz(info->RelativeName, FullName, ARRAY_COUNT(info->RelativeName));
	}

	// find filename
	const char* s = strrchr(info->RelativeName, '/');
	if (s) s++; else s = info->RelativeName;
	info->ShortFilename = s;
	// find extension
	s = strrchr(info->ShortFilename, '.');
	if (s) s++;
	info->Extension = s;
//	printf("..  -> %s (pkg=%d)\n", info->ShortFilename, info->IsPackage);

#if UNREAL3
	if (info->IsPackage && (strnicmp(info->ShortFilename, "startup", 7) == 0))
	{
		// Register a startup package
		// possible name variants:
		// - startup
		// - startup_int
		// - startup_*
		int startupWeight = 0;
		if (info->ShortFilename[7] == '.')
			startupWeight = 30;							// "startup.upk"
		else if (strnicmp(info->ShortFilename+7, "_int.", 5) == 0)
			startupWeight = 20;							// "startup_int.upk"
		else if (strnicmp(info->ShortFilename+7, "_loc_int.", 9) == 0)
			startupWeight = 20;							// "startup_int.upk"
		else if (info->ShortFilename[7] == '_')
			startupWeight = 1;							// non-int locale, lower priority - use if when other is not detected
		if (startupWeight > GStartupPackageInfoWeight)
		{
			GStartupPackageInfoWeight = startupWeight;
			GStartupPackageInfo = info;
		}
	}
#endif // UNREAL3

	// insert CGameFileInfo into hash table
	int hash = GetHashForFileName(info->ShortFilename);
	info->HashNext = GGameFileHash[hash];
	GGameFileHash[hash] = info;

	return true;

	unguardf("%s", FullName);
}
Exemple #16
0
static void ExportSection(ExportContext& Context, const CBaseMeshLod& Lod, const CMeshVertex* Verts, int SectonIndex, FArchive& Ar)
{
	guard(ExportSection);

	int VertexSize = Context.IsSkeletal() ? sizeof(CSkelMeshVertex) : sizeof(CStaticMeshVertex);

	const CMeshSection& S = Lod.Sections[SectonIndex];
	bool bLast = (SectonIndex == Lod.Sections.Num()-1);

	// Remap section indices to local indices
	CIndexBuffer::IndexAccessor_t GetIndex = Lod.Indices.GetAccessor();
	TArray<int> indexRemap; // old vertex index -> new vertex index
	indexRemap.Init(-1, Lod.NumVerts);
	int numLocalVerts = 0;
	int numLocalIndices = S.NumFaces * 3;
	for (int idx = 0; idx < numLocalIndices; idx++)
	{
		int vertIndex = GetIndex(S.FirstIndex + idx);
		if (indexRemap[vertIndex] == -1)
		{
			indexRemap[vertIndex] = numLocalVerts++;
		}
	}

	// Prepare buffers
	int IndexBufIndex = Context.Data.AddZeroed();
	int PositionBufIndex = Context.Data.AddZeroed();
	int NormalBufIndex = Context.Data.AddZeroed();
	int TangentBufIndex = Context.Data.AddZeroed();

	int BonesBufIndex = -1;
	int WeightsBufIndex = -1;
	if (Context.IsSkeletal())
	{
		BonesBufIndex = Context.Data.AddZeroed();
		WeightsBufIndex = Context.Data.AddZeroed();
	}

	int UVBufIndex[MAX_MESH_UV_SETS];
	for (int i = 0; i < Lod.NumTexCoords; i++)
	{
		UVBufIndex[i] = Context.Data.AddZeroed();
	}

	BufferData& IndexBuf = Context.Data[IndexBufIndex];
	BufferData& PositionBuf = Context.Data[PositionBufIndex];
	BufferData& NormalBuf = Context.Data[NormalBufIndex];
	BufferData& TangentBuf = Context.Data[TangentBufIndex];
	BufferData* UVBuf[MAX_MESH_UV_SETS];
	BufferData* BonesBuf = NULL;
	BufferData* WeightsBuf = NULL;

	PositionBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3));
	NormalBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3));
	TangentBuf.Setup(numLocalVerts, "VEC4", BufferData::FLOAT, sizeof(CVec4));
	for (int i = 0; i < Lod.NumTexCoords; i++)
	{
		UVBuf[i] = &Context.Data[UVBufIndex[i]];
		UVBuf[i]->Setup(numLocalVerts, "VEC2", BufferData::FLOAT, sizeof(CMeshUVFloat));
	}

	if (Context.IsSkeletal())
	{
		BonesBuf = &Context.Data[BonesBufIndex];
		WeightsBuf = &Context.Data[WeightsBufIndex];
		BonesBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_SHORT, sizeof(uint16)*4);
		WeightsBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_BYTE, sizeof(uint32), /*InNormalized=*/ true);
	}

	// Prepare and build indices
	TArray<int> localIndices;
	localIndices.AddUninitialized(numLocalIndices);
	int* pIndex = localIndices.GetData();
	for (int i = 0; i < numLocalIndices; i++)
	{
		*pIndex++ = GetIndex(S.FirstIndex + i);
	}

	if (numLocalVerts <= 65536)
	{
		IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_SHORT, sizeof(uint16));
		for (int idx = 0; idx < numLocalIndices; idx++)
		{
			IndexBuf.Put<uint16>(indexRemap[localIndices[idx]]);
		}
	}
	else
	{
		IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_INT, sizeof(uint32));
		for (int idx = 0; idx < numLocalIndices; idx++)
		{
			IndexBuf.Put<uint32>(indexRemap[localIndices[idx]]);
		}
	}

	// Build reverse index map for fast lookup of vertex by its new index.
	// It maps new vertex index to old vertex index.
	TArray<int> revIndexMap;
	revIndexMap.AddUninitialized(numLocalVerts);
	for (int i = 0; i < indexRemap.Num(); i++)
	{
		int newIndex = indexRemap[i];
		if (newIndex != -1)
		{
			revIndexMap[newIndex] = i;
		}
	}

	// Build vertices
	for (int i = 0; i < numLocalVerts; i++)
	{
		int vertIndex = revIndexMap[i];
		const CMeshVertex& V = VERT(vertIndex);

		CVec3 Position = V.Position;

		CVec4 Normal, Tangent;
		Unpack(Normal, V.Normal);
		Unpack(Tangent, V.Tangent);
		// Unreal (and we are) using normal.w for computing binormal. glTF
		// uses tangent.w for that. Make this value exactly 1.0 of -1.0 to make glTF
		// validator happy.
	#if 0
		// There's some problem: V.Normal.W == 0x80 -> -1.008 instead of -1.0
		if (Normal.w > 1.001 || Normal.w < -1.001)
		{
			appError("%X -> %g\n", V.Normal.Data, Normal.w);
		}
	#endif
		Tangent.w = (Normal.w < 0) ? -1 : 1;

		TransformPosition(Position);
		TransformDirection(Normal);
		TransformDirection(Tangent);

		Normal.Normalize();
		Tangent.Normalize();

		// Fill buffers
		PositionBuf.Put(Position);
		NormalBuf.Put(Normal.xyz);
		TangentBuf.Put(Tangent);
		UVBuf[0]->Put(V.UV);
	}

	// Compute bounds for PositionBuf
	CVec3 Mins, Maxs;
	ComputeBounds((CVec3*)PositionBuf.Data, numLocalVerts, sizeof(CVec3), Mins, Maxs);
	char buf[256];
	appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Mins));
	PositionBuf.BoundsMin = buf;
	appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Maxs));
	PositionBuf.BoundsMax = buf;

	if (Context.IsSkeletal())
	{
		for (int i = 0; i < numLocalVerts; i++)
		{
			int vertIndex = revIndexMap[i];
			const CMeshVertex& V0 = VERT(vertIndex);
			const CSkelMeshVertex& V = static_cast<const CSkelMeshVertex&>(V0);

			int16 Bones[NUM_INFLUENCES];
			static_assert(NUM_INFLUENCES == 4, "Code designed for 4 influences");
			static_assert(sizeof(Bones) == sizeof(V.Bone), "Unexpected V.Bones size");
			memcpy(Bones, V.Bone, sizeof(Bones));
			for (int j = 0; j < NUM_INFLUENCES; j++)
			{
				// We have INDEX_NONE as list terminator, should replace with something else for glTF
				if (Bones[j] == INDEX_NONE)
				{
					Bones[j] = 0;
				}
			}

			BonesBuf->Put(*(uint64*)&Bones);
			WeightsBuf->Put(V.PackedWeights);
		}
	}

	// Secondary UVs
	for (int uvIndex = 1; uvIndex < Lod.NumTexCoords; uvIndex++)
	{
		BufferData* pBuf = UVBuf[uvIndex];
		const CMeshUVFloat* srcUV = Lod.ExtraUV[uvIndex-1];
		for (int i = 0; i < numLocalVerts; i++)
		{
			int vertIndex = revIndexMap[i];
			pBuf->Put(srcUV[vertIndex]);
		}
	}

	// Write primitive information to json
	Ar.Printf(
		"        {\n"
		"          \"attributes\" : {\n"
		"            \"POSITION\" : %d,\n"
		"            \"NORMAL\" : %d,\n"
		"            \"TANGENT\" : %d,\n",
		PositionBufIndex, NormalBufIndex, TangentBufIndex
	);
	if (Context.IsSkeletal())
	{
		Ar.Printf(
			"            \"JOINTS_0\" : %d,\n"
			"            \"WEIGHTS_0\" : %d,\n",
			BonesBufIndex, WeightsBufIndex
		);
	}
	for (int i = 0; i < Lod.NumTexCoords; i++)
	{
		Ar.Printf(
			"            \"TEXCOORD_%d\" : %d%s\n",
			i, UVBufIndex[i], i < (Lod.NumTexCoords-1) ? "," : ""
		);
	}

	Ar.Printf(
		"          },\n"
		"          \"indices\" : %d,\n"
		"          \"material\" : %d\n"
		"        }%s\n",
		IndexBufIndex, SectonIndex,
		SectonIndex < (Lod.Sections.Num()-1) ? "," : ""
	);

	unguard;
}
Exemple #17
0
void* FArray::GetItem(int index, int elementSize) const
{
	if (!IsValidIndex(index)) appError("TArray: index %d is out of range (%d)", index, DataCount);
	return OffsetPointer(DataPtr, index * elementSize);
}