bool GetNodeLocalPosition(StaticFunctionTag* base, TESObjectREFR * obj, BSFixedString nodeName, VMArray<float> inArray, bool firstPerson)
	{
		NiAVObject	* object = ResolveNode(obj, nodeName, firstPerson);
		if(object && inArray.Length() == 3) {
			inArray.Set(&object->m_localTransform.pos.x, 0);
			inArray.Set(&object->m_localTransform.pos.y, 1);
			inArray.Set(&object->m_localTransform.pos.z, 2);
			return true;
		}

		return false;
	}
	bool GetRelativeNodePosition(StaticFunctionTag* base, TESObjectREFR * obj, BSFixedString nodeNameA, BSFixedString nodeNameB, VMArray<float> inArray, bool firstPerson)
	{
		NiAVObject	* objectA = ResolveNode(obj, nodeNameA, firstPerson);
		NiAVObject	* objectB = ResolveNode(obj, nodeNameB, firstPerson);
		if(objectA && objectB && inArray.Length() == 3) {
			float x = objectB->m_worldTransform.pos.x - objectA->m_worldTransform.pos.x;
			float y = objectB->m_worldTransform.pos.y - objectA->m_worldTransform.pos.y;
			float z = objectB->m_worldTransform.pos.z - objectA->m_worldTransform.pos.z;
			inArray.Set(&x, 0);
			inArray.Set(&y, 1);
			inArray.Set(&z, 2);
			return true;
		}

		return false;
	}
Beispiel #3
0
void SetFloatByIndex(VMArray<float> &dest, UInt32 index, float iniVal, float min, float max)
{
	//Enforce limits
	if (iniVal < min)
		iniVal = min;
	else if (iniVal > max)
		iniVal = max;

	dest.Set(&iniVal, index);
}
	bool GetNodeWorldRotationEuler(StaticFunctionTag* base, TESObjectREFR * obj, BSFixedString nodeName, VMArray<float> inArray, bool firstPerson)
	{
		NiAVObject	* object = ResolveNode(obj, nodeName, firstPerson);
		if(object && inArray.Length() == 3) {
			float heading, attitude, bank;
			object->m_localTransform.rot.GetEulerAngles(&heading, &attitude, &bank);

			// Radians to degrees
			heading *= 180 / MATH_PI;
			attitude *= 180 / MATH_PI;
			bank *= 180 / MATH_PI;

			inArray.Set(&heading, 0);
			inArray.Set(&attitude, 1);
			inArray.Set(&bank, 2);
			return true;
		}

		return false;
	}
Beispiel #5
0
void ApplyMultByIndex(VMArray<float> &multsToModify, UInt32 index, float iniVal, float max)
{
	//Enforce limits
	if (iniVal < 0.0)
		iniVal = 0.0;
	else if (iniVal > max)
		iniVal = max;

	float data;
	multsToModify.Get(&data, index);
	data *= iniVal;
	multsToModify.Set(&data, index);
}
	bool GetNodeWorldRotationMatrix(StaticFunctionTag* base, TESObjectREFR * obj, BSFixedString nodeName, VMArray<float> inArray, bool firstPerson)
	{
		NiAVObject	* object = ResolveNode(obj, nodeName, firstPerson);
		if(object && inArray.Length() == 9) {
			inArray.Set(&object->m_worldTransform.rot.data[0][0], 0);
			inArray.Set(&object->m_worldTransform.rot.data[0][1], 1);
			inArray.Set(&object->m_worldTransform.rot.data[0][2], 2);

			inArray.Set(&object->m_worldTransform.rot.data[1][0], 3);
			inArray.Set(&object->m_worldTransform.rot.data[1][1], 4);
			inArray.Set(&object->m_worldTransform.rot.data[1][2], 5);

			inArray.Set(&object->m_worldTransform.rot.data[2][0], 6);
			inArray.Set(&object->m_worldTransform.rot.data[2][1], 7);
			inArray.Set(&object->m_worldTransform.rot.data[2][2], 8);
			return true;
		}

		return false;
	}
Beispiel #7
0
	// 一定距離内に居るアクターをすべて返す
	VMArray<Actor*> FindCloseActor(float distance, UInt32 sortOrder)
	{
		enum Order {
			kSortOrder_distance		= 0,		// 距離が近い順
			kSortOrder_crosshair	= 1,		// クロスヘアに近い順
			kSortOrder_zaxis_clock	= 2,		// Z軸時計回り
			kSortOrder_zaxis_rclock	= 3,		// Z軸逆時計回り
			kSortOrder_invalid      = 4
		};

		double fovThreshold = (double)PlayerCamera::GetSingleton()->worldFOV / 180.0 * M_PI /2;

		VMArray<Actor*> result;
		result.arr = NULL;

		tArray<UInt32>* actorHandles = &(*s_cellInfo)->actorHandles;
		if (actorHandles->count == 0)
			return result;

		std::vector<std::pair<double, Actor*>> vec;
		vec.reserve(actorHandles->count);

		PlayerCharacter* player = *g_thePlayer;
		NiPoint3 camPos;
		GetCameraPos(&camPos);

		UInt32 handle;
		size_t i = 0;
		while (actorHandles->GetNthItem(i++, handle))
		{
			TESObjectREFR* ref = NULL;
			if (handle != *g_invalidRefHandle)
				LookupREFRByHandle(&handle, &ref);

			if (ref && ref->formType == kFormType_Character)
			{
				Actor* actor = (Actor*)ref;
				NiPoint3 pos;
				GetTargetPos(actor, &pos);
				double dx = pos.x - camPos.x;
				double dy = pos.y - camPos.y;
				double dz = pos.z - camPos.z;
				double dd = sqrt(dx*dx + dy*dy + dz*dz);

				if (distance <= 0 || dd <= distance)
				{
					double point;
					NiPoint3 cameraAngle;
					GetCameraAngle(&cameraAngle);
					double angleZ = NormalRelativeAngle(atan2(dx, dy) - cameraAngle.z);
					double angleX = NormalRelativeAngle(atan2(-dz, sqrt(dx*dx + dy*dy)) - cameraAngle.x);
					
					if (abs(angleZ) < fovThreshold)
					{
						switch (sortOrder)
						{
						case kSortOrder_distance:
							point = dd;
							break;
						case kSortOrder_crosshair:
							point = sqrt(angleZ*angleZ + angleX*angleX);
							break;
						case kSortOrder_zaxis_clock:
							point = NormalAbsoluteAngle(atan2(dx, dy) - cameraAngle.z);
							break;
						case kSortOrder_zaxis_rclock:
							point = 2*M_PI - NormalAbsoluteAngle(atan2(dx, dy) - cameraAngle.z);
							break;
						default:
							point = 0;
							break;
						}

						if (point >= 0)
						{
							vec.push_back(std::make_pair(point, actor));
						}
					}
				}
			}
		}

		if (vec.size() == 0)
			return result;

		if (sortOrder < kSortOrder_invalid)
			std::sort(vec.begin(), vec.end());

		// Papyrusに返す配列を確保
		if (result.Allocate(vec.size()))
		{
			for (i = 0; i < vec.size(); i++)
			{
				result.Set(&vec[i].second, i);
			}
		}

		return result;
	}