void CameraManager::GenerateRays(PintRaycastData* rays, udword nb_rays, float max_dist) { GLint viewPort[4]; GLdouble modelMatrix[16]; GLdouble projMatrix[16]; glGetIntegerv(GL_VIEWPORT, viewPort); glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); const float fScreenWidth = float(gScreenWidth)/float(nb_rays); const float fScreenHeight = float(gScreenHeight)/float(nb_rays); const Point Origin = GetCameraPos(); udword Offset=0; for(udword j=0;j<nb_rays;j++) { const udword yi = udword(fScreenHeight*float(j)); for(udword i=0;i<nb_rays;i++) { const udword xi = udword(fScreenWidth*float(i)); rays[Offset].mOrigin = Origin; rays[Offset].mDir = ComputeWorldRay(viewPort, modelMatrix, projMatrix, xi, yi); rays[Offset].mMaxDist = max_dist; Offset++; } } }
void CapsuleMeshQuery::MotionCallback(int x, int y) { if(mValidHit) { Point Dir = ComputeWorldRay(x, y); mWorld.SetTrans(GetCameraPos() + Dir*mDist - mLocalHit); } }
void CapsuleMeshQuery::MouseCallback(int button, int state, int x, int y) { mValidHit = false; if(!button && !state) { Point Dir = ComputeWorldRay(x, y); float s[2]; if(RayCapsuleOverlap(GetCameraPos(), Dir, mCapsule, s)) { mValidHit = true; mDist = s[0]; Point hit = GetCameraPos() + Dir * mDist; mLocalHit = hit - (Point)mWorld.GetTrans(); } } }
void OBBMeshQuery::MotionCallback(int x, int y) { if(mValidHit) { Point Dir = ComputeWorldRay(x, y); mBox.mCenter = GetCameraPos() + Dir*mDist - mLocalHit; } }
void LantirnClass::DrawTerrain() { AircraftClass *playerAC = SimDriver.GetPlayerAircraft(); Tpoint cameraPos; GetCameraPos (&cameraPos); ((RenderIR*)display)->StartDraw(); #if 0 display->SetColor (0x03000000); display->Tri (-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 1.0F); display->Tri (-1.0F, -1.0F, 1.0F, -1.0F, 1.0F, 1.0F); display->SetColor (0xff00ff00); #endif Trotation viewRotation; mlTrig tha, psi, phi; mlSinCos(&tha, playerAC->Pitch()+m_dpitch); mlSinCos(&psi, playerAC->Yaw()); mlSinCos(&phi, playerAC->Roll()); viewRotation.M11 = psi.cos * tha.cos; viewRotation.M21 = psi.sin * tha.cos; viewRotation.M31 = -tha.sin; viewRotation.M12 = -psi.sin*phi.cos + psi.cos*tha.sin*phi.sin; viewRotation.M22 = psi.cos*phi.cos + psi.sin*tha.sin*phi.sin; viewRotation.M32 = tha.cos*phi.sin; viewRotation.M13 = psi.sin*phi.sin + psi.cos*tha.sin*phi.cos; viewRotation.M23 = -psi.cos*phi.sin + psi.sin*tha.sin*phi.cos; viewRotation.M33 = tha.cos*phi.cos; Tpoint p; Trotation *r = &viewRotation; p.x = cameraPos.x; p.y = cameraPos.y; p.z = cameraPos.z; cameraPos.x = p.x * r->M11 + p.y * r->M12 + p.z * r->M13; cameraPos.y = p.x * r->M21 + p.y * r->M22 + p.z * r->M23; cameraPos.z = p.x * r->M31 + p.y * r->M32 + p.z * r->M33; ((RenderIR*)display)->DrawScene(&cameraPos, &viewRotation); //JAM 12Dec03 - ZBUFFERING OFF if(DisplayOptions.bZBuffering) ((RenderIR*)display)->context.FlushPolyLists(); // ((RenderIR*)display)->PostSceneCloudOcclusion(); ((RenderIR*)display)->EndDraw(); }
void OBBMeshQuery::MouseCallback(int button, int state, int x, int y) { mValidHit = false; if(!button && !state) { Point Dir = ComputeWorldRay(x, y); float d; Point hit; if(RayOBB(GetCameraPos(), Dir, mBox, d, hit)) { mValidHit = true; mDist = d; mLocalHit = hit - mBox.mCenter; } } }
// カメラを任意の座標に向ける static void LookAt(float posX, float posY, float posZ, float wait) { PlayerCharacter* player = *g_thePlayer; NiPoint3 cameraPos; double x, y, z, xy; double rotZ, rotX; GetCameraPos(&cameraPos); x = posX - cameraPos.x; y = posY - cameraPos.y; z = posZ - cameraPos.z; xy = sqrt(x*x + y*y); rotZ = atan2(x, y); rotX = atan2(-z, xy); if (rotZ - player->rot.z > M_PI) rotZ -= M_PI * 2; else if (rotZ - player->rot.z < -M_PI) rotZ += M_PI * 2; SetPlayerAngle(rotZ, rotX, wait); }
// 一定距離内に居るアクターをすべて返す 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; }