From c01469dddabe404506ef3a64542e8423f9e11f2c Mon Sep 17 00:00:00 2001 From: Aki Date: Sun, 30 Jan 2022 17:44:05 +0100 Subject: Converted Opcode and Ice into unix newlines format --- Opcode/OPC_Picking.cpp | 364 ++++++++++++++++++++++++------------------------- 1 file changed, 182 insertions(+), 182 deletions(-) (limited to 'Opcode/OPC_Picking.cpp') diff --git a/Opcode/OPC_Picking.cpp b/Opcode/OPC_Picking.cpp index 5971971..5a48403 100644 --- a/Opcode/OPC_Picking.cpp +++ b/Opcode/OPC_Picking.cpp @@ -1,182 +1,182 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/* - * OPCODE - Optimized Collision Detection - * Copyright (C) 2001 Pierre Terdiman - * Homepage: http://www.codercorner.com/Opcode.htm - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Contains code to perform "picking". - * \file OPC_Picking.cpp - * \author Pierre Terdiman - * \date March, 20, 2001 - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Precompiled Header -#include "StdAfx.h" - -using namespace Opcode; - -#ifdef OPC_RAYHIT_CALLBACK - -/* - Possible RayCollider usages: - - boolean query (shadow feeler) - - closest hit - - all hits - - number of intersection (boolean) - -*/ - -bool Opcode::SetupAllHits(RayCollider& collider, CollisionFaces& contacts) -{ - struct Local - { - static void AllContacts(const CollisionFace& hit, void* user_data) - { - CollisionFaces* CF = (CollisionFaces*)user_data; - CF->AddFace(hit); - } - }; - - collider.SetFirstContact(false); - collider.SetHitCallback(Local::AllContacts); - collider.SetUserData(&contacts); - return true; -} - -bool Opcode::SetupClosestHit(RayCollider& collider, CollisionFace& closest_contact) -{ - struct Local - { - static void ClosestContact(const CollisionFace& hit, void* user_data) - { - CollisionFace* CF = (CollisionFace*)user_data; - if(hit.mDistancemDistance) *CF = hit; - } - }; - - collider.SetFirstContact(false); - collider.SetHitCallback(Local::ClosestContact); - collider.SetUserData(&closest_contact); - closest_contact.mDistance = MAX_FLOAT; - return true; -} - -bool Opcode::SetupShadowFeeler(RayCollider& collider) -{ - collider.SetFirstContact(true); - collider.SetHitCallback(null); - return true; -} - -bool Opcode::SetupInOutTest(RayCollider& collider) -{ - collider.SetFirstContact(false); - collider.SetHitCallback(null); - // Results with collider.GetNbIntersections() - return true; -} - -bool Opcode::Picking( -CollisionFace& picked_face, -const Ray& world_ray, const Model& model, const Matrix4x4* world, -float min_dist, float max_dist, const IcePoint& view_point, CullModeCallback callback, void* user_data) -{ - struct Local - { - struct CullData - { - CollisionFace* Closest; - float MinLimit; - CullModeCallback Callback; - void* UserData; - IcePoint ViewPoint; - const MeshInterface* IMesh; - }; - - // Called for each stabbed face - static void RenderCullingCallback(const CollisionFace& hit, void* user_data) - { - CullData* Data = (CullData*)user_data; - - // Discard face if we already have a closer hit - if(hit.mDistance>=Data->Closest->mDistance) return; - - // Discard face if hit IcePoint is smaller than min limit. This mainly happens when the face is in front - // of the near clip plane (or straddles it). If we keep the face nonetheless, the user can select an - // object that he may not even be able to see, which is very annoying. - if(hit.mDistance<=Data->MinLimit) return; - - // This is the index of currently stabbed triangle. - udword StabbedFaceIndex = hit.mFaceID; - - // We may keep it or not, depending on backface culling - bool KeepIt = true; - - // Catch *render* cull mode for this face - CullMode CM = (Data->Callback)(StabbedFaceIndex, Data->UserData); - - if(CM!=CULLMODE_NONE) // Don't even compute culling for double-sided triangles - { - // Compute backface culling for current face - - VertexPointers VP; - Data->IMesh->GetTriangle(VP, StabbedFaceIndex); - if(VP.BackfaceCulling(Data->ViewPoint)) - { - if(CM==CULLMODE_CW) KeepIt = false; - } - else - { - if(CM==CULLMODE_CCW) KeepIt = false; - } - } - - if(KeepIt) *Data->Closest = hit; - } - }; - - RayCollider RC; - RC.SetMaxDist(max_dist); - RC.SetTemporalCoherence(false); - RC.SetCulling(false); // We need all faces since some of them can be double-sided - RC.SetFirstContact(false); - RC.SetHitCallback(Local::RenderCullingCallback); - - picked_face.mFaceID = INVALID_ID; - picked_face.mDistance = MAX_FLOAT; - picked_face.mU = 0.0f; - picked_face.mV = 0.0f; - - Local::CullData Data; - Data.Closest = &picked_face; - Data.MinLimit = min_dist; - Data.Callback = callback; - Data.UserData = user_data; - Data.ViewPoint = view_point; - Data.IMesh = model.GetMeshInterface(); - - if(world) - { - // Get matrices - Matrix4x4 InvWorld; - InvertPRMatrix(InvWorld, *world); - - // Compute camera position in mesh space - Data.ViewPoint *= InvWorld; - } - - RC.SetUserData(&Data); - if(RC.Collide(world_ray, model, world)) - { - return picked_face.mFaceID!=INVALID_ID; - } - return false; -} - -#endif +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code to perform "picking". + * \file OPC_Picking.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "StdAfx.h" + +using namespace Opcode; + +#ifdef OPC_RAYHIT_CALLBACK + +/* + Possible RayCollider usages: + - boolean query (shadow feeler) + - closest hit + - all hits + - number of intersection (boolean) + +*/ + +bool Opcode::SetupAllHits(RayCollider& collider, CollisionFaces& contacts) +{ + struct Local + { + static void AllContacts(const CollisionFace& hit, void* user_data) + { + CollisionFaces* CF = (CollisionFaces*)user_data; + CF->AddFace(hit); + } + }; + + collider.SetFirstContact(false); + collider.SetHitCallback(Local::AllContacts); + collider.SetUserData(&contacts); + return true; +} + +bool Opcode::SetupClosestHit(RayCollider& collider, CollisionFace& closest_contact) +{ + struct Local + { + static void ClosestContact(const CollisionFace& hit, void* user_data) + { + CollisionFace* CF = (CollisionFace*)user_data; + if(hit.mDistancemDistance) *CF = hit; + } + }; + + collider.SetFirstContact(false); + collider.SetHitCallback(Local::ClosestContact); + collider.SetUserData(&closest_contact); + closest_contact.mDistance = MAX_FLOAT; + return true; +} + +bool Opcode::SetupShadowFeeler(RayCollider& collider) +{ + collider.SetFirstContact(true); + collider.SetHitCallback(null); + return true; +} + +bool Opcode::SetupInOutTest(RayCollider& collider) +{ + collider.SetFirstContact(false); + collider.SetHitCallback(null); + // Results with collider.GetNbIntersections() + return true; +} + +bool Opcode::Picking( +CollisionFace& picked_face, +const Ray& world_ray, const Model& model, const Matrix4x4* world, +float min_dist, float max_dist, const IcePoint& view_point, CullModeCallback callback, void* user_data) +{ + struct Local + { + struct CullData + { + CollisionFace* Closest; + float MinLimit; + CullModeCallback Callback; + void* UserData; + IcePoint ViewPoint; + const MeshInterface* IMesh; + }; + + // Called for each stabbed face + static void RenderCullingCallback(const CollisionFace& hit, void* user_data) + { + CullData* Data = (CullData*)user_data; + + // Discard face if we already have a closer hit + if(hit.mDistance>=Data->Closest->mDistance) return; + + // Discard face if hit IcePoint is smaller than min limit. This mainly happens when the face is in front + // of the near clip plane (or straddles it). If we keep the face nonetheless, the user can select an + // object that he may not even be able to see, which is very annoying. + if(hit.mDistance<=Data->MinLimit) return; + + // This is the index of currently stabbed triangle. + udword StabbedFaceIndex = hit.mFaceID; + + // We may keep it or not, depending on backface culling + bool KeepIt = true; + + // Catch *render* cull mode for this face + CullMode CM = (Data->Callback)(StabbedFaceIndex, Data->UserData); + + if(CM!=CULLMODE_NONE) // Don't even compute culling for double-sided triangles + { + // Compute backface culling for current face + + VertexPointers VP; + Data->IMesh->GetTriangle(VP, StabbedFaceIndex); + if(VP.BackfaceCulling(Data->ViewPoint)) + { + if(CM==CULLMODE_CW) KeepIt = false; + } + else + { + if(CM==CULLMODE_CCW) KeepIt = false; + } + } + + if(KeepIt) *Data->Closest = hit; + } + }; + + RayCollider RC; + RC.SetMaxDist(max_dist); + RC.SetTemporalCoherence(false); + RC.SetCulling(false); // We need all faces since some of them can be double-sided + RC.SetFirstContact(false); + RC.SetHitCallback(Local::RenderCullingCallback); + + picked_face.mFaceID = INVALID_ID; + picked_face.mDistance = MAX_FLOAT; + picked_face.mU = 0.0f; + picked_face.mV = 0.0f; + + Local::CullData Data; + Data.Closest = &picked_face; + Data.MinLimit = min_dist; + Data.Callback = callback; + Data.UserData = user_data; + Data.ViewPoint = view_point; + Data.IMesh = model.GetMeshInterface(); + + if(world) + { + // Get matrices + Matrix4x4 InvWorld; + InvertPRMatrix(InvWorld, *world); + + // Compute camera position in mesh space + Data.ViewPoint *= InvWorld; + } + + RC.SetUserData(&Data); + if(RC.Collide(world_ray, model, world)) + { + return picked_face.mFaceID!=INVALID_ID; + } + return false; +} + +#endif -- cgit v1.1