Raycast to Blueprint

odyeiop

25-03-2007 22:48:58

I'm trying to use a nxOgre RayCaster for my weapon, but it doesn't seem to pick up blueprint<character> hit bodys.

I have it right now so that when you hit a body, it rights out mCaster->mHitBody->getName() to a file. It works for all the nxOgre::body objects in my game, just none of the blueprints. Any idea why this is and/or how I could fix it?

betajaen

25-03-2007 23:01:02

Does the ray hit anything at all? I would think at least it would pick up the kinematic actor in the controller, it won't cast the Actor's userData to a body though. If it tried it'd crash.

odyeiop

25-03-2007 23:09:19


if(mCaster->cast(true))
{
[][]if(!mCaster->mHitBody->isStatic())
[][]{
[][][][]setHitObj(mCaster->mHitBody->getName());
[][][][]mCaster->mHitBody->addForce(getPlayerWeapon()->getForce()*getRayDirect(),NX_SMOOTH_IMPULSE);
[][][][]mCaster->mHitBody->setAutoDeletable(true);
[][]}
[][]setHitMaterial(mCaster->mHitBody->mEntity->getSubEntity(0)->getMaterialName());
[][]setPartPos(mCaster->mHitPos);
[][]setPartNrm(mCaster->mHitNormal);
[][]writeF("caster.log","HIT");
}

if I shoot at the blueprints it never writes to the caster.log.


nxOgre::blueprint<character> bp;
bp.setToDefault();
bp.setGravity(true);
bp.setSlopeLimit(35);
bp.setStep(0.10);
bp.setShapeAsBox(0.35,0.75,0.35);
bp.setMesh("");

aiCol = bp.create("AI"+Ogre::StringConverter::toString(_n++), Vector3( paths->getPosition().x,1.7,paths->getPosition().z), _pSc);
aiCol->mNode->attachObject(GCEntity);


I attach the GCEntity to the aiCol node, because I can't grab the entity from the blueprint.. so there's no way for me to trigger the animations.

betajaen

25-03-2007 23:14:37

Alright. Then the raycaster code is not reporting any NxActors without a userData as a body attached - There isn't a real way to determine what is what.

For now and a quick solution, you can use the NxRay class directly and raycast by "hand".

For a long term solution, NxOgre 0.9 will support raycasters and triggers for characters.

odyeiop

25-03-2007 23:22:22

err.. is there a quick way to do that? Or an example somewhere for that. This project is due tomorrow... :oops:

I didn't think it would be a problem hitting blueprints, so I hadn't tried it before.

I was going to use NxOgre::bodies for the enemies, but moving them is a little silly, and they are easy to push around, and they fall over (as funny as that looks =D).

If it comes down to it I'm not to worried, as the project looks great as it is and I can probably just finish it up a later point, but it'd be nice to have it done for tomorrow =)

odyeiop

25-03-2007 23:27:22

If in the bp.mesh() I were to put a box about the size of the bounding box, and just give it a translucent material, would that work?

betajaen

25-03-2007 23:48:07

Sadly not. Actually, looking at the NxOgre 0.6 code right now. You may be able to modify the character code:

I have not tried this code, I didn't even compile it. So if anything breaks, your on your own.


Character.h

Add this to the class definition to the public section

static const char* NxActorNameIdentifier;

Character.cpp

An at the top of Character.cpp underneath the #includes inside the namespace.

const char* character::NxActorNameIdentifier = "NxK";

Underneath this line:
mController->getActor()->setGroup(owner->findGroupIndex("default"));

Add:
mController->getActor()->setName(character::NxActorNameIdentifier);

raycaster.cpp

Append to the includes section
#include "nxOgre_character.h"
#include "nxOgre_body.h"


And modify this entire method:
bool rayCaster::cast(bool _autoNormalise) {

if (_autoNormalise)
mDirection = mDirection.normalisedCopy();

NxRay mRay(NxTools::convert(mOrigin),NxTools::convert(mDirection));
NxShape *hit = _owner->mScene->raycastClosestShape(mRay,NX_ALL_SHAPES,mRayCastHit,0xffffffff,mLength);

if (hit) {

if (mRayCastHit.shape->getName() == body::NxActorNameIdentifier) {
mHitBody = static_cast<body*>(mRayCastHit.shape->getActor().userData);
mDistance = mRayCastHit.distance;
mHitNormal = NxTools::convert(mRayCastHit.worldNormal);
mHitPos = NxTools::convert(mRayCastHit.worldImpact);
return true;
}
else if (mRayCastHit.shape->getName() == character::NxActorNameIdentifier) {
mHitBody = 0;
mHitNormal = NxTools::convert(mRayCastHit.worldNormal);
mHitPos = NxTools::convert(mRayCastHit.worldImpact);
return true;
}
else {
return false;
}
}
else {
return false;
}


}


Raycaster.h
In nxOgre_raycaster.h move "NxRaycastHit mRayCastHit;" to the public section.

Your code
Finally to get the character pointer, in your code add:

character* enemy = static_cast<character*>(mRayCaster->mRayCastHit.shape->getActor().userData);


Don't use mHitBody (as it will be a NULL pointer), but use the above code, after successfully raycasting. You could probably determine what type of NxActor is detected by if mHitBody is 0 or not.




Good Luck ;)

odyeiop

26-03-2007 00:05:34

Ah, thank you very much, I'll try that out ASAP and let you know how it goes! Will this still be able to detect nxOgre body's? Or will I have to make anything detectable into a blueprint?

betajaen

26-03-2007 00:13:05

It should do both. You should add some extra checking around your raycasting code to see what was actually caught. If mHitBody is zero then it's a character, and you should use the converting code above to get it. If it's not then it's a body and you can use mHitBody directly.

It's a nasty hack. But since you don't have a lot of time it doesn't matter to much. Besides I think everyone may laugh when your enemies just fall over and roll around when they die! :D

odyeiop

26-03-2007 00:14:18

I'll just say it was rigor mortis

odyeiop

26-03-2007 02:31:52

it all seems to compile fine, but "static const char* NxActorNameIdentifier;" isn't being recognized. I've added it to pretty much every part of nxOgre_Character.h and I keep getting

C:\Documents and Settings\Brendan\Desktop\Dev\Dev\NxOgre\source\nxOgre_raycaster.cpp(94): error C2065: 'NxActorNameIdentifier' : undeclared identifier
C:\Documents and Settings\Brendan\Desktop\Dev\Dev\NxOgre\source\nxOgre_raycaster.cpp(94): error C2039: 'NxActorNameIdentifier' : is not a member of 'nxOgre::character'
C:\Documents and Settings\Brendan\Desktop\Dev\Dev\NxOgre\source\nxOgre_character.cpp(33): error C2039: 'NxActorNameIdentifier' : is not a member of 'nxOgre::character'
C:\Documents and Settings\Brendan\Desktop\Dev\Dev\NxOgre\source\nxOgre_character.cpp(84): error C2039: 'NxActorNameIdentifier' : is not a member of 'nxOgre::character'
C:\Documents and Settings\Brendan\Desktop\The Corrupted\fscommand\SDK's\includes\nxOgre_character.h(126) : see declaration of 'nxOgre::character'



[EDIT : ]Ah, nevermind =) I think I figured out what happened.

odyeiop

27-03-2007 20:23:17

Well the presentation went quite well, I had to work around not being able to raycast to the blueprints though.


I did put in the code that you gave me, but it lagged quite awfully. I'm pretty sure it dropped my frames down to a bout 0.5 per second. I'll have to retry it for our second and final presentation on Thursday. Hopefully it was just me being stupid and missing something.

Once again thank you very much! Hopefully I can figure this out.

betajaen

27-03-2007 20:58:43

No problem. I'm puzzled why the FPS would drop like that though.

But Good Luck with your second presentation though ;)

jchmack

28-03-2007 15:19:24

For a long term solution, NxOgre 0.9 will support raycasters and triggers for characters.

YESSS!!! been waiting for this for a while:
http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=3228

:twisted:

betajaen

28-03-2007 15:36:32

Actually how the trigger implemented (or will be implemented) is quite crazy. I implemented a custom callback system for collisions, which you can define if the character should collide with it or not, but in that bit where you can define if it should or not - triggers can happen. ;)

But so far the classes for characters are:

- CharacterController (Holder and manager for characters)
- Character (Obvious)
- CharaterHitReport (What do to when it hits something)
- BaseCharacterHitReport (What it does by default when it hits something)
- CharacterMovementController (What to do when the character should move)

It's quite elaborate. :D