//
	// 设置本地朝向
	//
	VOID CSceneNode::SetLocalOrientation(FLOAT x, FLOAT y, FLOAT z, FLOAT w)
	{
		m_bNeedUpdateAABB = TRUE;
		m_bNeedUpdateTransform = TRUE;

		QuatSet(&m_localOrientation, x, y, z, w);
	}
示例#2
0
void
CL_Init_Entity (entity_t *ent)
{
	memset (ent, 0, sizeof (*ent));

	ent->skin = 0;
	QuatSet (1.0, 1.0, 1.0, 1.0, ent->colormod);
	ent->scale = 1.0;
	ent->pose1 = ent->pose2 = -1;
}
	//
	// 初始化
	//
	VOID CSceneNode::Identity(VOID)
	{
		m_bNeedUpdateAABB = TRUE;
		m_bNeedUpdateTransform = TRUE;

		Vec3Set(&m_localScale, 1.0f, 1.0f, 1.0f);
		Vec3Set(&m_localPosition, 0.0f, 0.0f, 0.0f);
		QuatSet(&m_localOrientation, 0.0f, 0.0f, 0.0f, 1.0f);
		MtxIdentity(&m_mtxLocal);
	}
示例#4
0
float *findRotChannel(skcHeader_t *h, const char *name, int frameNum, int parentIndex) {
#if 0
	char channelName[32];
	strcpy(channelName,name);
	strcat(channelName," rot");
	return getChannelValue(h,channelName,frameNum);
#else
static int i = 0;
	static quat_t qs[1024];
	float *q;
	char channelName[32];
	float *f;
	float len;
	
	i++;
	i %= 1024;
	q = qs[i];

	strcpy(channelName,name);
	strcat(channelName," rot");
	f = getChannelValue(h,channelName,frameNum);
	if(f == 0) {
		//return quat_identity;
		QuatSet(q,0,0,0,-1);
	} else {
		QuatCopy(f,q);
	}
	//QuatInverse(q);
	////if(parentIndex == -1)
	//	QuatInverse(q);
	len = QuatNormalize(q);
	if(abs(len-1.f) > 0.1) {
		T_Error("Non-normalized quat in skc file (%f)\n",len);
	}
#if 1
	FixQuatForMD5_P(q);
#endif
	return q;
#endif
}
	//
	// 设置世界朝向
	//
	VOID CSceneNode::SetWorldOrientation(FLOAT x, FLOAT y, FLOAT z, FLOAT w)
	{
		if (m_pParentNode) {
			// 算法:
			// worldOrientation = localOrientation * parentOrientation
			// localOrientation = worldOrientation * parentOrientationInv

			QUAT parentOrientationInv;
			QuatInverse(&parentOrientationInv, m_pParentNode->GetWorldOrientation());

			QUAT localOrientation;
			QUAT worldOrientation;
			QuatSet(&worldOrientation, x, y, z, w);
			QuatMul(&localOrientation, &worldOrientation, &parentOrientationInv);

			x = localOrientation[0];
			y = localOrientation[1];
			z = localOrientation[2];
			w = localOrientation[3];
		}

		SetLocalOrientation(x, y, z, w);
	}
示例#6
0
tAnim_t *appendSKC(tModel_t *m, const char *fname, float scale) {
	int len;
	skcHeader_t *h;
	skcFrame_t *f; //, *firstFrame;
	tAnim_t *out;
	tFrame_t *of;
//	const char *c;
	int i, j;
	int cFlags[512];
	bone_t baseFrame[512];
	int numAnimatedComponents;

	T_Printf("Loading MoHAA skc animation file %s...\n",fname);

	len = F_LoadBuf(fname,(byte**)&h);

	if(len == -1) {
		T_Printf("Cannot open %s\n",fname);
		return 0;
	}

	memset(cFlags,0,sizeof(cFlags));

	out = T_Malloc(sizeof(tAnim_t));
	out->frameRate = 1.f / h->frameTime;
	out->numBones = m->numBones;
	out->numFrames = h->numFrames;
	out->frames = T_Malloc(sizeof(tFrame_t)*h->numFrames);
	out->boneData = T_Malloc(sizeof(tAnimBone_t)*m->numBones);

	// copy frame bounding boxes
	f = (skcFrame_t *)( (byte *)h + sizeof(*h) );
	of = out->frames;
	for(i = 0; i < h->numFrames; i++,of++,f++) {
		//anim->frames[i].radius = f->radius;
		VectorCopy(f->bounds[1],of->maxs);
		VectorCopy(f->bounds[0],of->mins);
	}

	// detect which components changes
	for(j = 0; j < m->numBones; j++) {
		float *baseRot, *testRot;
		float *basePos, *testPos;

		basePos = findPosChannel(h,m->bones[j].name,0);
		if(basePos == 0) {
			VectorSet(baseFrame[j].p,0,0,0);
		} else {
			VectorScale(basePos,scale,basePos);
			VectorCopy(basePos,baseFrame[j].p);
			for(i = 1; i < h->numFrames; i++) {
				testPos = findPosChannel(h,m->bones[j].name,i);
				VectorScale(testPos,scale,testPos);
				// detect X change
				if(testPos[0] != basePos[0]) {
					cFlags[j] |= COMPONENT_BIT_TX;
				}
				// detect Y change
				if(testPos[1] != basePos[1]) {
					cFlags[j] |= COMPONENT_BIT_TY;
				}
				// detect Z change
				if(testPos[2] != basePos[2]) {
					cFlags[j] |= COMPONENT_BIT_TZ;
				}
			}	
		}

		baseRot = findRotChannel(h,m->bones[j].name,0,m->bones[j].parent);
		if(baseRot == 0) {
			QuatSet(baseFrame[j].q,0,0,0,-1);
		} else {
			QuatCopy(baseRot,baseFrame[j].q);
			for(i = 1; i < h->numFrames; i++) {
				testRot = findRotChannel(h,m->bones[j].name,i,m->bones[j].parent);
				// detect X change
				if(testRot[0] != baseRot[0]) {
					cFlags[j] |= COMPONENT_BIT_QX;
				}
				// detect Y change
				if(testRot[1] != baseRot[1]) {
					cFlags[j] |= COMPONENT_BIT_QY;
				}
				// detect Z change
				if(testRot[2] != baseRot[2]) {
					cFlags[j] |= COMPONENT_BIT_QZ;
				}
				// NOTE: quaternion W component is not stored at all in md5 files
			}	
		}
	}

	// count the number of animated components and copy some bone data
	numAnimatedComponents = 0;
	for(j = 0; j < m->numBones; j++) {
		//int c;

		out->boneData[j].firstComponent = numAnimatedComponents;
		//c = 0;

		for(i = 0; i < 6; i++) {
			if(cFlags[j] & (1 << i)) {
				numAnimatedComponents++;
			//	c++;
			}
		}

		//out->boneData[j].numAnimatedComponents = c;
		out->boneData[j].componentBits = cFlags[j];
		strcpy(out->boneData[j].name,m->bones[j].name);
		out->boneData[j].parent = m->bones[j].parent;
	}

	// copy results out
	out->baseFrame = T_Malloc(sizeof(bone_t)*m->numBones);
	memcpy(out->baseFrame,baseFrame,sizeof(bone_t)*m->numBones);
	out->numAnimatedComponents = numAnimatedComponents;
	of = out->frames;
	for(i = 0; i < h->numFrames; i++,of++) {
		int c;
		float *cp;

		cp = of->components = T_Malloc(numAnimatedComponents*sizeof(float));

		//c = 0;
		for(j = 0; j < m->numBones; j++) {
			float *pos, *rot;

			pos = findPosChannel(h,m->bones[j].name,i);
			if(pos) {
				VectorScale(pos,scale,pos);
				// write X change
				if(cFlags[j] & COMPONENT_BIT_TX) {
					*cp = pos[0];
					cp++;
				}
				// write Y change
				if(cFlags[j] & COMPONENT_BIT_TY) {
					*cp = pos[1];
					cp++;
				}
				// write Z change
				if(cFlags[j] & COMPONENT_BIT_TZ) {
					*cp = pos[2];
					cp++;
				}
			}

			rot = findRotChannel(h,m->bones[j].name,i,m->bones[j].parent);
			if(rot) {
				// write X change
				if(cFlags[j] & COMPONENT_BIT_QX) {
					*cp = rot[0];
					cp++;
				}
				// write Y change
				if(cFlags[j] & COMPONENT_BIT_QY) {
					*cp = rot[1];
					cp++;
				}
				// write Z change
				if(cFlags[j] & COMPONENT_BIT_QZ) {
					*cp = rot[2];
					cp++;
				}	
			}
		}

		c = cp - of->components;
		assert(c == numAnimatedComponents);
	}

#if 0
	// validate generated tAnim_t components
	for(i = 0; i < out->numFrames; i++) {
		bone_t *b = setupMD5AnimBones(out,0); 
		for(j = 0; j < m->numBones; j++, b++) {
			float *o;
			o = findRotChannel_raw(h,m->bones[j].name,i,m->bones[j].parent);
			if(o) {
				T_Printf("Generated: %f %f %f %f, original %f %f %f %f\n",b->q[0],b->q[1],b->q[2],b->q[3],
					o[0],o[1],o[2],o[3]);
			} else {
				T_Printf("Generated: %f %f %f %f, original <none>\n",b->q[0],b->q[1],b->q[2],b->q[3]);
			}

			
		}
	}

#endif

	// generate baseFrame, but only once,
	// from the first appended SKC
	if(m->baseFrame == 0) {
#if 0
		// FIXME!
		bone_t *b = setupMD5AnimBones(out,0); 
		//for(i = 0; i < m->numBones; i++) {
		//	QuatInverse(b[i].q);
		//}
#else
		bone_t b[512];
		for(i = 0; i < m->numBones; i++) {
			float *p, *q;
			
			p = findPosChannel(h,m->bones[i].name,0);
			if(p) {
				VectorScale(p,scale,b[i].p);
			} else {
				VectorSet(b[i].p,0,0,0);
			}

			q = findRotChannel(h,m->bones[i].name,0,m->bones[i].parent);
			if(q) {
				QuatCopy(q,b[i].q);
			} else {
				QuatSet(b[i].q,0,0,0,1);
			}
		}
#endif
		md5AnimateBones(m,b);
		m->baseFrame = T_Malloc(m->numBones*sizeof(bone_t));
		memcpy(m->baseFrame,b,m->numBones*sizeof(bone_t));
	}

	F_FreeBuf((byte*)h);

	T_Printf("Succesfully loaded MoHAA animation %s\n",fname);


	return out;
}
示例#7
0
void
CL_ParseTEnt (void)
{
	byte        type;
	dlight_t   *dl;
	tent_obj_t *to;
	explosion_t *ex;
	int         colorStart, colorLength;
	int         cnt = -1;
	vec3_t      pos;
	sfx_t      *spike_sound[] = {
		cl_sfx_ric3, cl_sfx_ric3, cl_sfx_ric2, cl_sfx_ric1,
	};

	type = MSG_ReadByte (net_message);
	switch (type) {
		case TE_WIZSPIKE:				// spike hitting wall
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_WizSpikeEffect (pos);
			S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
			break;

		case TE_KNIGHTSPIKE:			// spike hitting wall
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_KnightSpikeEffect (pos);
			S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
			break;

		case TE_SPIKE:					// spike hitting wall
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_SpikeEffect (pos);
			{
				int		i;
				sfx_t  *sound;

				i = (rand () % 20) - 16;
				if (i >= 0)
					sound = spike_sound[i];
				else
					sound = cl_sfx_tink1;
				S_StartSound (-1, 0, sound, pos, 1, 1);
			}
			break;

		case TE_SUPERSPIKE:				// super spike hitting wall
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_SuperSpikeEffect (pos);
			{
				int		i;
				sfx_t  *sound;

				i = (rand () % 20) - 16;
				if (i >= 0)
					sound = spike_sound[i];
				else
					sound = cl_sfx_tink1;
				S_StartSound (-1, 0, sound, pos, 1, 1);
			}
			break;

		case TE_EXPLOSION:				// rocket explosion
			// particles
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_ParticleExplosion (pos);

			// light
			dl = r_funcs->R_AllocDlight (0);
			if (dl) {
				VectorCopy (pos, dl->origin);
				dl->radius = 350;
				dl->die = cl.time + 0.5;
				dl->decay = 300;
				QuatSet (0.86, 0.31, 0.24, 0.7, dl->color);
			}

			// sound
			S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);

			// sprite
			to = new_tent_object ();
			to->next = cl_explosions;
			cl_explosions = to;
			ex = &to->to.ex;
			ex->tent = new_temp_entity ();

			VectorCopy (pos, ex->tent->ent.origin);
			ex->start = cl.time;
			//FIXME need better model management
			if (!cl_spr_explod->cache.data)
				cl_spr_explod = Mod_ForName ("progs/s_explod.spr", true);
			ex->tent->ent.model = cl_spr_explod;
			CL_TransformEntity (&ex->tent->ent, ex->tent->ent.angles, true);
			break;

		case TE_TAREXPLOSION:			// tarbaby explosion
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_BlobExplosion (pos);

			S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
			break;

		case TE_LIGHTNING1:				// lightning bolts
			CL_ParseBeam (cl_mod_bolt);
			break;

		case TE_LIGHTNING2:				// lightning bolts
			CL_ParseBeam (cl_mod_bolt2);
			break;

		case TE_LIGHTNING3:				// lightning bolts
			CL_ParseBeam (cl_mod_bolt3);
			break;

		// PGM 01/21/97
		case TE_BEAM:					// grappling hook beam
			CL_ParseBeam (cl_mod_beam);
			break;
		// PGM 01/21/97

		case TE_LAVASPLASH:
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_LavaSplash (pos);
			break;

		case TE_TELEPORT:
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_TeleportSplash (pos);
			break;

		case TE_EXPLOSION2:				// color mapped explosion
			MSG_ReadCoordV (net_message, pos);
			colorStart = MSG_ReadByte (net_message);
			colorLength = MSG_ReadByte (net_message);
			S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
			r_funcs->particles->R_ParticleExplosion2 (pos, colorStart,
													  colorLength);
			dl = r_funcs->R_AllocDlight (0);
			if (!dl)
				break;
			VectorCopy (pos, dl->origin);
			dl->radius = 350;
			dl->die = cl.time + 0.5;
			dl->decay = 300;
			colorStart = (colorStart + (rand () % colorLength)) * 3;
			VectorScale (&r_data->vid->palette[colorStart], 1.0 / 255.0,
						 dl->color);
			dl->color[3] = 0.7;
			break;

		case TE_GUNSHOT:				// bullet hitting wall
			cnt = MSG_ReadByte (net_message) * 20;
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_GunshotEffect (pos, cnt);
			break;

		case TE_BLOOD:					// bullet hitting body
			cnt = MSG_ReadByte (net_message) * 20;
			MSG_ReadCoordV (net_message, pos);
			r_funcs->particles->R_BloodPuffEffect (pos, cnt);
			break;

		case TE_LIGHTNINGBLOOD:			// lightning hitting body
			MSG_ReadCoordV (net_message, pos);

			// light
			dl = r_funcs->R_AllocDlight (0);
			if (dl) {
				VectorCopy (pos, dl->origin);
				dl->radius = 150;
				dl->die = cl.time + 0.1;
				dl->decay = 200;
				QuatSet (0.25, 0.40, 0.65, 1, dl->color);
			}

			r_funcs->particles->R_LightningBloodEffect (pos);
			break;

		default:
			Sys_Error ("CL_ParseTEnt: bad type %d", type);
	}
}