Hi All
I know this is a long shot but any help would be great.
Does anyone still use or have used Nuclear Basic/ Fusion that can help?
I still really like the language and still use it. But need help in hardware skinning for animated entities I cant seem to send the bone information over to the shader.
These are the commands I've found that might help but can't figure out how to use them.
GetSurfaceBoneOffsetMatrix( Surf, mat, boneind )
GetSurfaceBoneCount(Surf)
GetSurfaceBone(Surf,boneind)
GetEntMatrix( handle, inmat, global=False )
SetShaderMatrixArray(handle, pname$, mat,[cnt=1] )
Here is the shader I am using
float Script : STANDARDSGLOBAL <
string UIWidget = "none";
string ScriptClass = "object";
string ScriptOrder = "standard";
string ScriptOutput = "color";
string Script = "Technique=Technique?Skinned;";
> = 1.0;
float4x4 wvp : WorldViewProjection < string UIWidget = "None"; > ;
float4x4 worldI : WorldInverse < string UIWidget = "None"; > ;
float4x4 worldIT : WorldInverseTranspose < string UIWidget = "None"; > ;
float4x4 viewInv : ViewInverse < string UIWidget = "None"; > ;
float4x4 world : World;
// array for bones matrices
uniform float4x3 bonesMatrixArray[60];
extern int NumVertInfluences = 3;//<--- Normally set dynamically.
// ambeint light
float4 ambientLight = float4(1,0,0,1);
texture diffuseTexture : TEXTURE_0;
sampler diffuseSampler : register(s0) = sampler_state
{
Texture = <diffuseTexture>;
};
// Vertex shader input data structure
struct VSINPUT
{
float4 Position : POSITION;
float4 BlendWeights : BLENDWEIGHT;
float4 BlendIndices : BLENDINDICES;
float3 Normal : NORMAL;
float3 texCoords : TEXCOORD0;
};
// Vertex shader output data structure
struct VSOUTPUT
{
float4 Position : POSITION;
float3 Normal : COLOR0;
float2 texCoords : TEXCOORD0;
};
// skinning vertex shader
VSOUTPUT VSMain(VSINPUT Input)
{
// Output object
VSOUTPUT Output;
// Clear vertex position and normal
Output.Normal = float3(0.0f, 0.0f, 0.0f);
Output.Position = float4(0.0f, 0.0f, 0.0f, 0.0f);
// extract bones indicies and weights from vertex
float lastWeight = 0.0f;
float4 blendPos = Input.Position;
// This next code segment computes formula (3).
for (int i = 0; i < NumVertInfluences; ++i)
{
blendPos += float4(mul(bonesMatrixArray[Input.BlendIndices[i]], Input.Position).xyz, 1.0)*Input.BlendWeights[i];//Input.BlendWeights[i] * mul(Input.Position, bonesMatrixArray[Input.BlendIndices[i]]);
}
Output.Position = mul(blendPos, wvp);
// transform normal
float3 norm = Input.Normal;
for (i = 0; i < NumVertInfluences; ++i)
{
norm += mul((float3x3)bonesMatrixArray[Input.BlendIndices[i]], Input.Normal) *
Input.BlendWeights[i];
}
Output.Normal = normalize(norm);
Output.texCoords = Input.texCoords;
// return result
return Output;
}
// skinning simple pixel shader
float4 PSMain(float2 texCoords : TEXCOORD0) : COLOR0
{
// just return diffuse color
return ambientLight * tex2D(diffuseSampler, texCoords);
}
// skinning tchnique
technique Skinned
{
pass p1
{
VertexShader = compile vs_3_0 VSMain();
PixelShader = compile ps_3_0 PSMain();
}
}
Here is the nuclearbasix code.
Global wwidth = 1680
Global wheight = 1050
Global wdepth = 32
Global wmode = 0
Global wparent = 0
Global wflags = 3
Global wnd = MakeWindowDX(wwidth, wheight, wdepth, wmode, wparent, wflags )
If Not wnd Then DebugError("Please update your DirectX")
mm = MakeMenu()
file = MakeMenuItem(mm, "File", 0)
open = MakeMenuItem(file, "Open...", 0)
about = MakeMenuItem(mm, "About", 0)
about2 = MakeMenuItem(about, "About...", 0)
SetWindowMenu(wnd, mm)
Global FPS = 60
Global Tween = True
Global VSync = True
Set3DTargetFPS(FPS)
Set3DTweening(Tween)
Set3DVSync(VSync)
Const TYPE_PLAYER = 1
Const TYPE_LEVEL = 2
Const TYPE_OBJ = 3
SetCollisions(TYPE_PLAYER, TYPE_LEVEL)
SetCollisions(TYPE_PLAYER, TYPE_OBJ)
SetCollisions(TYPE_OBJ, TYPE_LEVEL)
SetCollisions(TYPE_OBJ, TYPE_OBJ)
Global cam
Global player
Global vp
Global aspectratio# = 1.85
cam = GetDefaultCamera()
SetCameraRange(cam, .1, 50000)
PositionEnt cam,0,2,10
;SetCameraAspectRange(cam, aspectratio#)
Ground = MakePlane(1000,1000)
DefaultText=LoadTexture("Media\Textures\DefaultDiffuse.png")
ScaleTexture DefaultText,0.01,0.01
SetEntTexture(Ground,DefaultText)
//Load test player
New_Player = LoadAnimEnt("Media\Test Player\Main_Ref.b3d")
shader = LoadShader("Media\Shaders\SkinningTest - Copy.fx",4EntShader(new_player,shader)
SetEntAnimTweenFrames( New_Player, 10)
PlayEntAnim(New_Player)
SetEntCurrentTrack(New_Player,idle_none)
vp = GetDefaultViewport()
CollisionEnt( Cam, TYPE_PLAYER )
Global Cube, Cube2, Cube3, Cube4
Cube = MakeCube(4)
Cube2 = MakeCube(4)
PositionEnt(Cube, -4, 0, 12)
PositionEnt(Cube2, 4, 0, 12)
AddEntBoxShape( Cube, GetEntScaleX#(Cube)/2, GetEntScaleY#(Cube)/2, GetEntScaleZ#(Cube)/2 )
AddEntBoxShape( Cube2, GetEntScaleX#(Cube2)/2, GetEntScaleY#(Cube2)/2, GetEntScaleZ#(Cube2)/2 )
CollisionEnt( Cube, TYPE_OBJ )
CollisionEnt( Cube2, TYPE_OBJ )
View_Side = 1
View_Mode =1
Type Bone
Field ID,RealID
Field Ent
Field Name$
Field Main.NukeMatrix
Field Offset.NukeMatrix
Field BonePtrs.NukeMatrix
Field Surf,Test
Field VertCount
Field VertID.NukeVec4[10000]
Field VertWeight.NukeVec4
EndType
Global skip = False
Global BONECOUNT = 0
Function CollectBones(Ent)
For S=0 To GetMeshSurfaceCount(Ent)-1
Surf = GetMeshSurface(Ent,S);
If GetSurfaceBoneCount(Surf)>0
For I=1 To GetSurfaceBoneCount(Surf)
B.Bone = New Bone
BONECOUNT=BONECOUNT+1
B\Ent = GetSurfaceBone(Surf,I)
B\ID = BONECOUNT
B\RealID = I;
B\Name = GetEntName(B\Ent)
B\Offset = New NukeMatrix
B\BonePtrs = New NukeMatrix
B\Main = New NukeMatrix
GetEntMatrix(B\Ent,B\BonePtrs\GetPtr())
GetSurfaceBoneOffsetMatrix(Surf,B\Offset\GetPtr(),I)
Next
EndIf
Next
If BONECOUNT = 0
Get_Child(Ent,0)
EndIf
EndFunction
Global offsetTemp.NukeMatrix = New NukeMatrix
CollectBones(new_player)
While Not KeyHit(1)
PointEntAtEnt cam,new_player
If Do3DTweening() //if it's time to update the scene
//
Anim = idle_none
Print "BONE_COUNT:"+BONECOUNT
Print GetEntChildCount(new_player)
GetEntMatrix(new_player,offsetTemp\GetPtr())
For B.Bone = Each Bone
xx = 0
yy = 0
ConvertViewportCoordFrom3D(GetDefaultViewport(),xx,yy,GetEntPosX(B\Ent),GetEntPosY(B\Ent),GetEntPosZ(B\Ent))
MatrixMultiply(offsetTemp\GetPtr(),B\BonePtrs\GetPtr(),B\Offset\GetPtr())
Next
SetShaderMatrixArray(shader,"bonesMatrixArray",offsetTemp\GetPtr(),BONECOUNT)
mxs = MouseX(wnd)
mys = MouseY(wnd)
;If mx<0 Then mx=wwidth
SetMousePos Get3DWidth()/2,Get3DHeight()/2 ,wnd
MouseSpeed# = MouseXSpeed(mxs,wnd)
MouseSpeed_Y# = MouseYSpeed(mys,wnd)
If Anim=idle_none And Free_look =0
If Float(MouseSpeed)>1
Anim =TurnR_Anim
EndIf
If Float(MouseSpeed)<-1
Anim = TurnL_Anim
EndIf
EndIf
If Not KeyDown(29) Or KeyDown(157)
Free_look = 0
TurnEnt Cam,0,-MouseSpeed/10,0
//RotateEnt(Player_Free_Look,0,0,0)
If Not KeyDown(42)
If KeyDown(17) Or KeyDown(200) Then MoveEnt(cam, 0, 0, 0.1) //:Anim = Walking_Anim
If KeyDown(31) Or KeyDown(208) Then MoveEnt(cam, 0, 0, -0.05) //:Anim = WalkingB_Anim
If KeyDown(30) Or KeyDown(203) Then MoveEnt(cam, -0.05, 0, 0.0) //:Anim = Right_Anim
If KeyDown(32) Or KeyDown(205) Then MoveEnt(cam, 0.05, 0, 0.0) //:Anim = Left_Anim
Else
If KeyDown(17) Or KeyDown(200) Then MoveEnt(cam, 0, 0, 0.3) //:Anim = Run_Anim
EndIf
Else If KeyDown(29) Or KeyDown(157)
TurnEnt cam,0,-MouseSpeed/10,0
Free_look = 1
EndIf
If GetMenuItemHitCount(open)>0 Then
MakeDialogOpenBox2(wnd, "*.b3d;*.x", "./", "Open...")
Else If GetMenuItemHitCount(about2)>0
Notice2("About...", wnd, 1, 0, "About...")
EndIf
If KeyHit(56) Then View_Side=1-(View_Side+1)
If KeyHit(47)
View_Mode =1-View_Mode
EndIf
If View_Mode = 1
PlayEntAnim(new_player)
Else
StopEntAnim(new_player)
EndIf
SetAnimTrackSpeeds(5)
SetEntCurrentTrack(New_Player,Anim)
EndIf
Sync
Wend
Can anyone help? Please
what is it that you are trying to achieve?? Far as i know, NB already does hardware skinning by default, as well as NF (i have used NF)..Im not sure what is it that you want to do. All it takes to animate (and its hardware skinning) is
//load first animated character model
character = LoadAnimEnt("AnimatedEntity.b3d")
//set animation speed
SetEntAnimSpeed character, 0.2
//play animation (call it once only)
PlayEntAnim character
Its already hardware skinned..
When I add my shader for example a shadow shader (but ever shader has the same effect) any animated entity wont animate any more due to i need to calculate the bone matrix which is needed but I can't figure out how to send them to the shader.
The first post is me trying to figure out how to read the bone info and send it to the shader.
I can use SetMeshSoftwareBones but it starts to become slow the more entities that I use.
??