Compare commits

...

43 Commits

Author SHA1 Message Date
antc13 24486c314d Reworked the Exporter. 2016-01-13 14:03:58 +01:00
antc13 7b62dc19bf Spitting out Meshes & Animation Data to file. 2016-01-12 15:39:29 +01:00
antc13 0e90382fd1 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into MayaExporter 2016-01-11 13:09:09 +01:00
Jace dc7ed2e0ba Merge pull request #25 from teamfisk/Forward+
Forward+
2016-01-11 12:43:43 +01:00
Tleety f71bfca142 Fixed cullLights into CullLights 2016-01-11 10:23:22 +01:00
Tleety dbb44fb4e4 Changing cullLights to Culllights, need to do this in 2 commits since Git extensions is fucked. 2016-01-11 10:22:56 +01:00
antc13 1667358e0c We now export animations. 2016-01-08 16:47:04 +01:00
Tleety 6e6460a000 Commented out the bugged models 2016-01-08 16:15:18 +01:00
Tleety 9f871bbe7c Lights now use the absolute position instead of it's local position. 2016-01-08 14:31:44 +01:00
Tleety 2bd60be741 Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts:
#	resources/Schema/Types/Entity.xsd
2016-01-08 14:14:43 +01:00
Tleety dab4ba2164 Pointlights are now using the pointlight component and the Light renderqueue to draw. 2016-01-08 14:12:09 +01:00
Tleety 25a99a04c5 Added Visable bool and a better description to Pointlight component. 2016-01-08 14:11:35 +01:00
William Moberg 13ade6d7f2 Merge pull request #24 from teamfisk/HealthSystem
Fixed so the PlayerDeath event doesn't get spammed while the player i…
2016-01-08 11:54:11 +01:00
verysecrethero 592776e783 Fixed so the PlayerDeath event doesn't get spammed while the player is dead. Also made sure that any remaining healthDeltas are cleared when dead. 2016-01-08 11:37:51 +01:00
verysecrethero ff44dccb33 Merge pull request #23 from teamfisk/OrderedSystemPipeline
Ordered system pipeline approved
2016-01-08 10:32:58 +01:00
Tleety e7bb8954bf Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts:
#	include/Engine/Rendering/Renderer.h
#	resources/Schema/Components.xsd
#	resources/Schema/Entities/Test.xml
#	src/Engine/Rendering/Renderer.cpp
2016-01-06 11:35:55 +01:00
Tleety e510f2b88c Forward plus render pass now removed from Renderer.cpp to it's own class. 2016-01-06 11:32:42 +01:00
FakeShemp eb5fca898f Fix small bug with push_back order
Commited directly from GitHub. Blame it if something explodes.
2015-12-21 12:55:25 +01:00
antc13 c9db46564f Spitting out files WIP 2015-12-18 16:21:07 +01:00
Tleety eb69e03e82 Merge branch 'Forward+' of github.com:teamfisk/TacticalZ into Forward+ 2015-12-18 15:28:25 +01:00
Tleety d38f58165f Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts:
#	include/Engine/Rendering/Renderer.h
#	src/Engine/Rendering/RenderState.cpp
#	src/Engine/Rendering/Renderer.cpp
2015-12-18 15:27:47 +01:00
Tleety 069a6756b9 LightcullingPass for forward+ is now separate from Renderer.cpp. 2015-12-18 14:31:16 +01:00
viktorljung ef4cbfece8 Added PointLight Component in XML files 2015-12-18 13:20:55 +01:00
Tleety ab6af30a28 Base classes for decoupled forward+ renderer and a fix where if you had to many lights in a tile(200-300+) the list would fill up before the end of frustums. 2015-12-18 12:02:02 +01:00
viktorljung 3636ad45af Changed to correct branch 2015-12-18 11:29:11 +01:00
viktorljung 6cf7c12d34 Forward+ working 2015-12-18 11:09:54 +01:00
Teejoon 509a989d3b Merge branch 'MayaExporter' of github.com:teamfisk/TacticalZ into MayaExporter
Conflicts:
	tools/MayaExporter/MayaExporter/Menu.cpp
2015-12-18 10:07:44 +01:00
Teejoon bc4cc5db54 Changed how we get skeletons. Made so that we could get the bind pose for each skeleton in the scene 2015-12-18 10:03:00 +01:00
viktorljung 4a817613e3 Forward+ semi working 2015-12-17 17:55:44 +01:00
antc13 73708ec706 You can now add/remove animation clips. 2015-12-17 14:58:46 +01:00
viktorljung 6a3c14540d fixes 2015-12-17 10:38:13 +01:00
viktorljung 5602b32507 Forward+ Fixes 2015-12-16 13:36:38 +01:00
antc13 67017fcaf4 Stepping through the timeline. 2015-12-16 11:33:42 +01:00
antc13 498afb3a5e Merge branch 'MayaExporter' of https://github.com/teamfisk/TacticalZ into MayaExporter
# Conflicts:
#	tools/MayaExporter/MayaExporter/Menu.h
2015-12-15 15:41:18 +01:00
Tleety 1431bd1a11 DebugChanges 2015-12-15 15:39:23 +01:00
Tleety 1e370bac13 ForwardPlus base debug commit. 2015-12-15 15:28:37 +01:00
antc13 4e535c1102 File Writer WIP. Rework soon™ 2015-12-15 15:24:46 +01:00
FakeShemp 1689370356 Export the skeletons
Not really tested though
2015-12-15 11:49:59 +01:00
Tleety 7c714d1f98 Changed some error handling in the RenderState class. 2015-12-14 17:35:01 +01:00
antc13 60b3ce89b2 Skeleton/Joints WIP 2015-12-14 12:59:54 +01:00
antc13 a22d086e60 Tested some of the Material Code. Seems to work. The project should now be following the code standard properly (hopefully). 2015-12-10 11:18:34 +01:00
FakeShemp 74c1beed20 gitignore 2015-12-09 12:03:01 +01:00
FakeShemp c8cb0ee939 Grab all materials 2015-12-09 11:58:49 +01:00
45 changed files with 2359 additions and 496 deletions
+8
View File
@@ -4,3 +4,11 @@ bin/
lib/
# Because apparently nobody has any self control
*.orig
*.suo
*.sdf
tools/MayaExporter/MayaExporter/x64/Debug/
tools/MayaExporter/x64/Debug/
tools/MayaExporter/MayaExporter/Debug/
tools/MayaExporter/MayaExporter/GeneratedFiles/
+1 -1
Submodule assets updated: 673d4a4e4c...c8e631f449
+38
View File
@@ -0,0 +1,38 @@
#ifndef DrawFinalPass_h__
#define DrawFinalPass_h__
#include "IRenderer.h"
#include "DrawFinalPassState.h"
#include "LightCullingPass.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "Util/UnorderedMapVec2.h"
#include "Texture.h"
class DrawFinalPass
{
public:
DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass);
~DrawFinalPass() { }
void InitializeTextures();
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void Draw(RenderQueueCollection& rq);
//Getters
private:
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
Texture* m_WhiteTexture;
const IRenderer* m_Renderer;
const LightCullingPass* m_LightCullingPass;
ShaderProgram* m_ForwardPlusProgram;
};
#endif
@@ -0,0 +1,15 @@
#ifndef DrawFinalPassState_h__
#define DrawFinalPassState_h__
#include "Rendering/RenderState.h"
class DrawFinalPassState : public RenderState
{
public:
DrawFinalPassState();
~DrawFinalPassState();
private:
};
#endif
@@ -0,0 +1,78 @@
#ifndef LightCullingPass_h__
#define LightCullingPass_h__
#define TILE_SIZE 16
#define NUM_LIGHTS 1000
#include "IRenderer.h"
#include "LightCullingPassState.h"
#include "ShaderProgram.h"
class LightCullingPass
{
public:
LightCullingPass(IRenderer* renderer);
~LightCullingPass();
void GenerateNewFrustum();
void CullLights();
void FillLightList(RenderQueueCollection& rq);
GLuint FrustumSSBO() const { return m_FrustumSSBO; }
GLuint LightSSBO() const { return m_LightSSBO; }
GLuint LightGridSSBO() const { return m_LightGridSSBO; }
GLuint LightOffsetSSBO() const { return m_LightOffsetSSBO; }
GLuint LightIndexSSBO() const { return m_LightIndexSSBO; }
private:
void InitializeSSBOs();
void InitializeShaderPrograms();
const IRenderer* m_Renderer;
GLuint m_FrustumSSBO = 0;
GLuint m_LightSSBO = 0;
GLuint m_LightGridSSBO = 0;
GLuint m_LightOffsetSSBO = 0;
GLuint m_LightIndexSSBO = 0;
ShaderProgram* m_CalculateFrustumProgram;
ShaderProgram* m_LightCullProgram;
struct Plane {
glm::vec3 Normal;
float d;
};
struct Frustum {
Plane Planes[4];
};
Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution
//This should be a component
struct PointLight {
glm::vec4 Position = glm::vec4(0.f);
glm::vec4 Color = glm::vec4(1.f);
float Radius = 5.f;
float Intensity = 0.8f;
float Falloff = 0.3f;
float Padding = 1337;
};
std::vector<PointLight> m_PointLights;
struct LightGrid {
float Start;
float Amount;
glm::vec2 Padding;
};
LightGrid m_LightGrid[80*45]; //TODO: Renderer: Make this change with resolution
int m_LightOffset = 0;
float m_LightIndex[80*45*200]; //TODO: Renderer: Make this change with resolution
};
#endif
+4 -2
View File
@@ -1,6 +1,8 @@
#ifndef PickingPass_h__
#define PickingPass_h__
#include "IRenderer.h"
#include "PickingPassState.h"
#include "FrameBuffer.h"
@@ -9,6 +11,8 @@
#include "../Core/EventBroker.h"
#include "EPicking.h"
class PickingPass
{
public:
@@ -20,7 +24,6 @@ public:
void Draw(RenderQueueCollection& rq);
//Getters
const ShaderProgram& PickingProgram() const { return *m_PickingProgram; }
const std::unordered_map<glm::vec2, EntityID>& PickingColorsToEntity() const { return m_PickingColorsToEntity; }
@@ -28,7 +31,6 @@ public:
GLuint DepthBuffer() const { return m_DepthBuffer; }
const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; }
private:
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
+6 -5
View File
@@ -82,11 +82,12 @@ struct SpriteJob : RenderJob
struct PointLightJob : RenderJob
{
glm::vec3 Position;
glm::vec3 SpecularColor = glm::vec3(1, 1, 1);
glm::vec3 DiffuseColor = glm::vec3(1, 1, 1);
float Radius = 1.f;
float Intensity = 0.8f;
glm::vec4 Position;
glm::vec4 Color;
float Radius;
float Intensity;
float Falloff;
float padding = 123;
void CalculateHash() override
{
+4 -61
View File
@@ -13,19 +13,8 @@
#include "PickingPass.h"
#include "DrawScenePass.h"
#include "DebugCameraInputController.h"
#define TILE_SIZE 16
#define NUM_LIGHTS 3
enum lightType
{
Point,
Spot,
Directional,
Area
};
#include "LightCullingPass.h"
#include "DrawFinalPass.h"
#include "../Core/EventBroker.h"
#include "EPicking.h"
@@ -58,70 +47,24 @@ private:
DrawScenePass* m_DrawScenePass;
PickingPass* m_PickingPass;
LightCullingPass* m_LightCullingPass;
ImGuiRenderPass* m_ImGuiRenderPass;
DrawFinalPass* m_DrawFinalPass;
//----------------------Functions----------------------//
void InitializeWindow();
void InitializeShaders();
void InitializeTextures();
void InitializeSSBOs();
void InitializeRenderPasses();
//TODO: Renderer: Get InputUpdate out of renderer
void InputUpdate(double dt);
//void PickingPass(RenderQueueCollection& rq);
void DrawScreenQuad(GLuint textureToDraw);
//----------------------Forward+-----------------------//
void CalculateFrustum();
void CullLights();
//Frustum
struct Plane {
glm::vec3 Normal;
float d;
};
struct Frustum {
Plane Planes[4];
};
Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution
//Lights
void TEMPCreateLights();
//TODO: Renderer: Add Directionllights, spotlights and area lights to this as type.
struct PointLight {
glm::vec4 Position = glm::vec4(0.f);
glm::vec4 Color = glm::vec4(1.f);
float Radius = 5.f;
float Intensity = 0.8f;
float Falloff = 0.3f;
float Padding = 1337;
};
PointLight m_PointLights[NUM_LIGHTS];
struct LightGrid {
int Amount;
int Start;
glm::vec2 Padding;
};
LightGrid m_LightGrid[80*45];
int m_LightOffset = 0;
int m_LightIndex[80*45*200];
//-------------------------SSBO------------------------//
GLuint m_FrustumSSBO = 0;
GLuint m_LightSSBO = 1;
GLuint m_LightGridSSBO = 2;
GLuint m_LightOffsetSSBO = 3;
GLuint m_LightIndexSSBO = 4;
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
//--------------------ShaderPrograms-------------------//
ShaderProgram* m_BasicForwardProgram;
ShaderProgram* m_DrawScreenQuadProgram;
ShaderProgram* m_CalculateFrustumProgram;
ShaderProgram* m_LightCullProgram;
};
#endif
+1
View File
@@ -7,6 +7,7 @@
<xs:include schemaLocation="Components/RaptorCopter.xsd"/>
<xs:include schemaLocation="Components/Player.xsd"/>
<xs:include schemaLocation="Components/AABB.xsd"/>
<xs:include schemaLocation="Components/PointLight.xsd"/>
<xs:include schemaLocation="Components/Trigger.xsd"/>
<xs:include schemaLocation="Components/Health.xsd"/>
</xs:schema>
@@ -0,0 +1,7 @@
<c:PointLight>
<Color R="1" G="1" B="1" A="1"/>
<Radius>1.0</Radius>
<Intensity>0.8</Intensity>
<Falloff>0.3</Falloff>
<Visible>true</Visible>
</c:PointLight>
@@ -0,0 +1,20 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="PointLight">
<xs:annotation>
<xs:documentation>A pointlight that lights up geometry in a radius.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="Color" type="t:Color" minOccurs="0"/>
<xs:element name="Radius" type="t:double" minOccurs="0"/>
<xs:element name="Intensity" type="t:double" minOccurs="0"/>
<xs:element name="Falloff" type="t:double" minOccurs="0"/>
<xs:element name="Visible" type="t:bool" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+4 -4
View File
@@ -10,7 +10,7 @@
</c:Model>
</Components>
<Children>
<Entity>
<!--<Entity>
<Components>
<c:Transform>
<Position X="-1.5"/>
@@ -20,8 +20,8 @@
<Resource>Models/ScaleWidget.obj</Resource>
</c:Model>
</Components>
</Entity>
<Entity>
</Entity>-->
<!--<Entity>
<Components>
<c:Transform>
<Position X="1.5"/>
@@ -33,7 +33,7 @@
<c:Trigger>
</c:Trigger>
</Components>
</Entity>
</Entity>-->
<!--<Entity>
<Components>
<c:Player>
+1
View File
@@ -16,6 +16,7 @@
<xs:element ref="c:RaptorCopter" minOccurs="0"/>
<xs:element ref="c:Player" minOccurs="0"/>
<xs:element ref="c:Health" minOccurs="0"/>
<xs:element ref="c:PointLight" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
+154
View File
@@ -0,0 +1,154 @@
#version 430
//in uvec3 gl_NumWorkGroups; //contains the number of workgroups that have been dispatched to a compute shader
//in uvec3 gl_WorkGroupID; //contains the index of the workgroup currently being operated on by a compute shader
//in uvec3 gl_LocalInvocationID; //contains the index of work item currently being operated on by a compute shader
//in uvec3 gl_GlobalInvocationID; //contains the global index of work item currently being operated on by a compute shader
//in uint gl_LocalInvocationIndex; //contains the local linear index of work item currently being operated on by a compute shader
#define MAX_LIGHTS_PER_TILE 200
#define NUM_TILES 3600
#define TILE_SIZE 16
uniform mat4 V;
struct Plane {
vec3 Normal;
float d;
};
struct Frustum {
Plane Planes[4];
};
layout (std430, binding = 0) buffer FrustumBuffer
{
Frustum Data[];
} Frustums;
struct PointLight {
vec4 Position;
vec4 Color;
float Radius;
float Intensity;
float Falloff;
float Padding;
};
layout (std430, binding = 1) buffer LightBuffer
{
PointLight List[];
} PointLights;
struct LightGrid {
float Start;
float Amount;
vec2 Padding;
};
layout (std430, binding = 2) buffer LightGridBuffer
{
LightGrid Data[];
} LightGrids;
layout (std430, binding = 3) buffer LightOffsetBuffer
{
int LightOffset[];
};
layout (std430, binding = 4) buffer LightIndexBuffer
{
float LightIndex[];
};
shared int GroupLightCount;
shared int GroupLightIndexStartOffset;
shared int GroupLightIndex[MAX_LIGHTS_PER_TILE];
shared Frustum GroupFrustum;
int GroupIndex;
bool SphereInsidePlane(vec3 center, float radius, Plane plane)
{
return dot(plane.Normal, center) - plane.d > -radius;
}
bool SphereInsideFrustrum(vec3 center, float radius, Frustum frustum/*, float zNear, float zFar*/)
{
//Check depth here
//if ( sphere.c.z - sphere.r > zNear || sphere.c.z + sphere.r < zFar )
//{
// result = false;
//}
for (int i =0; i < 4; i++)
{
if(! SphereInsidePlane(center, radius, frustum.Planes[i]))
{
return false;
}
}
return true;
}
void AppendLight(int li)
{
int index;
index = atomicAdd(GroupLightCount, 1);
if( index < MAX_LIGHTS_PER_TILE )
{
GroupLightIndex[index] = int(li);
}
}
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main ()
{
GroupIndex = int(gl_WorkGroupID.x + (gl_WorkGroupID.y * 80));
if(gl_LocalInvocationIndex == 0)
{
GroupLightCount = 0;
GroupFrustum = Frustums.Data[GroupIndex];
}
barrier();
memoryBarrierShared();
for(int i = int(gl_LocalInvocationIndex); i < PointLights.List.length(); i += TILE_SIZE*TILE_SIZE)
{
PointLight light = PointLights.List[i];
//if pointlight
//Pos i view antagligen
if(SphereInsideFrustrum( vec3(V * light.Position), light.Radius, GroupFrustum))
{
//TODO: Fix transparent and opaque list, and depth test.
AppendLight( i );
}
//if conelight
//if directional
}
barrier();
memoryBarrierShared();
if(gl_LocalInvocationIndex == 0)
{
GroupLightIndexStartOffset = atomicAdd(LightOffset[0], GroupLightCount);
LightGrids.Data[GroupIndex].Start = GroupLightIndexStartOffset;
LightGrids.Data[GroupIndex].Amount = GroupLightCount;
}
barrier();
for (uint i = gl_LocalInvocationIndex; i < GroupLightCount; i += TILE_SIZE * TILE_SIZE )
{
LightIndex[GroupLightIndexStartOffset + i] = GroupLightIndex[i];
}
}
+132
View File
@@ -0,0 +1,132 @@
#version 430
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform vec4 Color;
uniform sampler2D texture0;
#define TILE_SIZE 16
struct PointLight {
vec4 Position;
vec4 Color;
float Radius;
float Intensity;
float Falloff;
float Padding;
};
layout (std430, binding = 1) buffer LightBuffer
{
PointLight List[];
} PointLights;
struct LightGrid {
float Start;
float Amount;
vec2 Padding;
};
layout (std430, binding = 2) buffer LightGridBuffer
{
LightGrid Data[];
} LightGrids;
layout (std430, binding = 4) buffer LightIndexBuffer
{
float LightIndex[];
};
in VertexData{
vec3 Position;
vec3 Normal;
vec2 TextureCoordinate;
vec4 DiffuseColor;
}Input;
out vec4 fragmentColor;
vec4 scene_ambient = vec4(0.3,0.3,0.3,1);
struct LightResult {
vec4 Diffuse;
vec4 Specular;
};
float CalcAttenuation(float radius, float dist) {
return 1.0 - smoothstep(radius * 0.3, radius, dist);
}
vec4 CalcSpecular(vec4 lightColor, vec4 viewVec, vec4 lightVec, vec4 normal) {
vec4 R = normalize( reflect(-lightVec, normal));
float RdotV = max( dot(R, viewVec), 0.0);
return lightColor * pow(RdotV, 90.0);
}
vec4 CalcDiffuse(vec4 lightColor, vec4 lightVec, vec4 normal) {
float power = max( dot(normal, lightVec), 0.0);
return lightColor * power;
}
LightResult CalcPointLight(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal)
{
vec4 L = lightPos - position;
float dist = length(L);
L = normalize(L);
float attenuation = CalcAttenuation(lightRadius, dist);
LightResult result;
result.Diffuse = CalcDiffuse(lightColor, L, normal) * attenuation * intensity;
result.Specular = CalcSpecular(lightColor, viewVec, L, normal) * attenuation * intensity;
return result;
}
void main()
{
vec4 texel = texture2D(texture0, Input.TextureCoordinate);
vec4 position = V * M * vec4(Input.Position, 1.0);
vec4 normal = V * vec4(Input.Normal, 0.0);
vec4 viewVec = normalize(-position);
vec2 tilePos;
tilePos.x = int(gl_FragCoord.x/16);
tilePos.y = int(gl_FragCoord.y/16);
LightResult totalLighting;
totalLighting.Diffuse = scene_ambient;
int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * 80));
int start = int(LightGrids.Data[currentTile].Start);
int amount = int(LightGrids.Data[currentTile].Amount);
//for(int i = 0; i < 3; i++)
for(int i = start; i < start + amount; i++)
{
int l = int(LightIndex[i]);
LightResult result = CalcPointLight(V * PointLights.List[l].Position, PointLights.List[l].Radius, PointLights.List[l].Color, PointLights.List[l].Intensity, viewVec, position, normal);
totalLighting.Diffuse += result.Diffuse;
totalLighting.Specular += result.Specular;
}
fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color;
//fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color;
//fragmentColor += vec4(0.0, LightGrids.Data[currentTile].Amount/3.0, 0, 1);
//fragmentColor = texel * Input.DiffuseColor * Color;
if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 )
{
//fragmentColor += vec4(0.5, 0, 0, 0);
} else {
//fragmentColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/3.0, 0, 0, 1);
}
}
+34
View File
@@ -0,0 +1,34 @@
#version 430
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec3 Tangent;
layout(location = 3) in vec3 BiTangent;
layout(location = 4) in vec2 TextureCoords;
layout(location = 5) in vec4 DiffuseVertexColor;
layout(location = 6) in vec4 SpecularVertexColor;
layout(location = 7) in vec4 BoneIndices1;
layout(location = 8) in vec4 BoneIndices2;
layout(location = 9) in vec4 BoneWeights1;
layout(location = 10) in vec4 BoneWeights2;
out VertexData{
vec3 Position;
vec3 Normal;
vec2 TextureCoordinate;
vec4 DiffuseColor;
}Output;
void main()
{
gl_Position = P*V*M * vec4(Position, 1.0);
Output.Position = Position;
Output.TextureCoordinate = TextureCoords;
Output.Normal = Normal;
Output.DiffuseColor = DiffuseVertexColor;
}
+27 -24
View File
@@ -16,7 +16,7 @@ struct Frustum {
layout (std430, binding = 0) buffer FrustumBuffer
{
Frustum Data[3600];
Frustum Data[];
} Frustums;
vec4 ConvertToView(vec4 ScreenCoords)
@@ -43,31 +43,34 @@ Plane ComputePlane( vec3 p0, vec3 p1, vec3 p2 )
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main ()
{
if(gl_GlobalInvocationID.x * TILE_SIZE < ScreenDimensions.x && gl_GlobalInvocationID.y * TILE_SIZE < ScreenDimensions.y) {
//Top-Left = 0 | Top-Right = 1
//Bottom-Left = 2 | Bottom-Right = 3
vec4 ScreenCoords[4];
ScreenCoords[0] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y + 1 ) * TILE_SIZE, -1.0, 1.0); // Z-axis might need to be 1
ScreenCoords[1] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0);
ScreenCoords[2] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0);
ScreenCoords[3] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0);
vec3 ViewVectors[4];
for(int i = 0; i < 4; i++) {
ViewVectors[i] = vec3(ConvertToView(ScreenCoords[i]));
}
vec3 EyePos = vec3(0,0,0);
Frustum f;
f.Planes[0] = ComputePlane(EyePos, ViewVectors[2], ViewVectors[0]);
f.Planes[1] = ComputePlane(EyePos, ViewVectors[1], ViewVectors[3]);
f.Planes[2] = ComputePlane(EyePos, ViewVectors[0], ViewVectors[1]);
f.Planes[3] = ComputePlane(EyePos, ViewVectors[3], ViewVectors[2]);
//Top-Left = 0 | Top-Right = 1
//Bottom-Left = 2 | Bottom-Right = 3
vec4 ScreenCoords[4];
ScreenCoords[0] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0);
ScreenCoords[1] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0);
ScreenCoords[2] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0);
ScreenCoords[3] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0);
Frustums.Data[gl_GlobalInvocationID.x + gl_GlobalInvocationID.y*80] = f;
vec3 ViewVectors[4];
for(int i = 0; i < 4; i++) {
ViewVectors[i] = vec3(ConvertToView(ScreenCoords[i]));
}
vec3 EyePos = vec3(0.0, 0.0 ,0.0);
Frustum f;
f.Planes[0] = ComputePlane(EyePos, ViewVectors[2], ViewVectors[0]); // left plane
f.Planes[1] = ComputePlane(EyePos, ViewVectors[1], ViewVectors[3]); // right plane
f.Planes[2] = ComputePlane(EyePos, ViewVectors[0], ViewVectors[1]); // top plane
f.Planes[3] = ComputePlane(EyePos, ViewVectors[3], ViewVectors[2]); // bottom plane
if ( gl_GlobalInvocationID.x < ScreenDimensions.x / TILE_SIZE && gl_GlobalInvocationID.y < ScreenDimensions.y / TILE_SIZE ) { // inside the screen
Frustums.Data[gl_GlobalInvocationID.x + gl_GlobalInvocationID.y*80] = f;
}
}
-35
View File
@@ -1,35 +0,0 @@
#version 430
//in uvec3 gl_NumWorkGroups;
//in uvec3 gl_WorkGroupID;
//in uvec3 gl_LocalInvocationID;
//in uvec3 gl_GlobalInvocationID;
//in uint gl_LocalInvocationIndex;
#define NUM_LIGHTS 3
#define MAX_LIGHTS_PER_TILE 200
#define NUM_TILES 3600
struct Plane {
vec3 Normal;
float d;
};
struct Frustum {
Plane Planes[4];
};
layout (std430, binding = 0) buffer FrustumBuffer
{
Frustum Data[3600];
} Frustums;
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main ()
{
if(1 == 1) {
}
}
+65
View File
@@ -0,0 +1,65 @@
#include "Rendering/DrawFinalPass.h"
DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass)
{
m_Renderer = renderer;
m_LightCullingPass = lightCullingPass;
InitializeTextures();
InitializeShaderPrograms();
}
void DrawFinalPass::InitializeTextures()
{
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
}
void DrawFinalPass::InitializeShaderPrograms()
{
m_ForwardPlusProgram = ResourceManager::Load<ShaderProgram>("#ForwardPlusProgram");
m_ForwardPlusProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/ForwardPlus.vert.glsl")));
m_ForwardPlusProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/ForwardPlus.frag.glsl")));
m_ForwardPlusProgram->Compile();
m_ForwardPlusProgram->Link();
}
void DrawFinalPass::Draw(RenderQueueCollection& rq)
{
GLERROR("DrawFinalPass::Draw: Pre");
DrawFinalPassState state;
m_ForwardPlusProgram->Bind();
GLuint shaderHandle = m_ForwardPlusProgram->GetHandle();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO());
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ViewMatrix()));
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix()));
//TODO: Render: Add code for more jobs than modeljobs.
for (auto &job : rq.Forward) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if(modelJob) {
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
if(modelJob->DiffuseTexture != nullptr) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture);
} else {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
}
glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
continue;
}
}
GLERROR("DrawFinalPass::Draw: END");
}
@@ -0,0 +1,17 @@
#include "Rendering/DrawFinalPassState.h"
DrawFinalPassState::DrawFinalPassState()
{
BindFramebuffer(0);
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
ClearColor(glm::vec4(200.f / 255, 0.f / 255, 200.f / 255, 0.f));
Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
DrawFinalPassState::~DrawFinalPassState()
{
}
+9 -6
View File
@@ -14,23 +14,21 @@ void DrawScenePass::InitializeTextures()
void DrawScenePass::InitializeShaderPrograms()
{
//Gör så att shaders är en resource, tex som texture classen. Konstruktorn måste vara privat.
m_BasicForwardProgram = ResourceManager::Load<ShaderProgram>("#BasicForwardProgram");
m_BasicForwardProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/BasicForward.vert.glsl")));
m_BasicForwardProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/BasicForward.frag.glsl")));
m_BasicForwardProgram->Compile();
m_BasicForwardProgram->Link();
}
void DrawScenePass::Draw(RenderQueueCollection& rq)
{
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLERROR("Renderer::Draw PickingPass");
GLERROR("DrawScenePass::Draw: Pre");
DrawScenePassState state;
m_BasicForwardProgram->Bind();
//TODO: Render: Add code for more jobs than modeljobs.
@@ -39,7 +37,6 @@ void DrawScenePass::Draw(RenderQueueCollection& rq)
if (modelJob) {
GLuint ShaderHandle = m_BasicForwardProgram->GetHandle();
m_BasicForwardProgram->Bind();
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ViewMatrix()));
@@ -61,6 +58,12 @@ void DrawScenePass::Draw(RenderQueueCollection& rq)
continue;
}
auto spriteJob = std::dynamic_pointer_cast<SpriteJob>(job);
if(spriteJob)
{
//Hello im a sprite, please draw me.
}
}
GLERROR("DrawScene Error");
GLERROR("DrawScenePass::Draw: End");
}
+126
View File
@@ -0,0 +1,126 @@
#include "Rendering/LightCullingPass.h"
LightCullingPass::LightCullingPass(IRenderer* renderer)
{
m_Renderer = renderer;
InitializeSSBOs();
InitializeShaderPrograms();
GenerateNewFrustum();
}
LightCullingPass::~LightCullingPass()
{
}
void LightCullingPass::GenerateNewFrustum()
{
GLERROR("CalculateFrustum Error: Pre");
m_CalculateFrustumProgram->Bind();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix()));
glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
glDispatchCompute(5, 3, 1); //TODO: Renderer: This needs change so resolution will be right.
GLERROR("CalculateFrustum Error: End");
}
void LightCullingPass::CullLights()
{
GLERROR("CullLights Error: Pre");
m_LightOffset = 0;
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
if (m_PointLights.size() > 0) {
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(PointLight) * m_PointLights.size(), &(m_PointLights[0]), GL_DYNAMIC_COPY);
} else {
GLfloat zero = 0.f;
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat), &zero , GL_DYNAMIC_COPY);
}
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
m_LightCullProgram->Bind();
glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(m_Renderer->Camera()->ViewMatrix()));
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO);
glDispatchCompute(m_Renderer->Resolution().Width / TILE_SIZE, m_Renderer->Resolution().Height / TILE_SIZE, 1);
GLERROR("CullLights Error: End");
}
void LightCullingPass::FillLightList(RenderQueueCollection& rq)
{
m_PointLights.clear();
for(auto &job : rq.Lights) {
auto pointLightjob = std::dynamic_pointer_cast<PointLightJob>(job);
if (pointLightjob) {
PointLight p;
p.Color = pointLightjob->Color;
p.Falloff = pointLightjob->Falloff;
p.Intensity = pointLightjob->Intensity;
p.Position = glm::vec4(glm::vec3(pointLightjob->Position), 1.f);
p.Radius = pointLightjob->Radius;
p.Padding = 123.f;
m_PointLights.push_back(p);
continue;
}
}
}
void LightCullingPass::InitializeSSBOs()
{
glGenBuffers(1, &m_FrustumSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_Frustums), &m_Frustums, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_FrustumSSBO");
glGenBuffers(1, &m_LightSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
if(m_PointLights.size() > 0) {
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(PointLight) * m_PointLights.size(), &(m_PointLights[0]), GL_DYNAMIC_COPY);
}
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightSSBO");
glGenBuffers(1, &m_LightGridSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightGrid), &m_LightGrid, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightGridSSBO");
glGenBuffers(1, &m_LightOffsetSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightOffsetSSBO");
glGenBuffers(1, &m_LightIndexSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightIndexSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightIndex), &m_LightIndex, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightIndexSSBO");
}
void LightCullingPass::InitializeShaderPrograms()
{
m_CalculateFrustumProgram = ResourceManager::Load<ShaderProgram>("#CalculateFrustumProgram");
m_CalculateFrustumProgram->AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/GridFrustum.comp.glsl")));
m_CalculateFrustumProgram->Compile();
m_CalculateFrustumProgram->Link();
m_LightCullProgram = ResourceManager::Load<ShaderProgram>("#LightCullProgram");
m_LightCullProgram->AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/CullLights.comp.glsl")));
m_LightCullProgram->Compile();
m_LightCullProgram->Link();
}
@@ -111,6 +111,34 @@ void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue)
void RenderQueueFactory::FillLights(World* world, RenderQueue* renderQueue)
{
auto pointLights = world->GetComponents("PointLight");
if(pointLights == nullptr) {
return;
}
for(auto& pointlightC : *pointLights) {
bool visible = pointlightC["Visible"];
if(!visible) {
continue;
}
auto transformC = world->GetComponent(pointlightC.EntityID, "Transform");
if(&transformC == nullptr) {
return;
}
glm::vec4 color = pointlightC["Color"];
float radius = (double)pointlightC["Radius"];
float intensity = (double)pointlightC["Intensity"];
float falloff = (double)pointlightC["Falloff"];
PointLightJob job;
job.Position = glm::vec4(AbsolutePosition(world, transformC.EntityID), 1.f);
job.Color = color;
job.Radius = radius;
job.Intensity = intensity;
job.Falloff = falloff;
renderQueue->Add(job);
}
}
+1
View File
@@ -3,6 +3,7 @@
bool RenderState::Enable(GLenum cap)
{
if (glIsEnabled(cap)) {
//LOG_WARNING("Trying to enable somthing that is already enabled.");
return false;
}
m_ResetFunctions.push_back(std::bind(glDisable, cap));
+9 -135
View File
@@ -4,20 +4,17 @@ void Renderer::Initialize()
{
InitializeWindow();
// Create default camera
m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(45.f), 0.01f, 5000.f);
m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10));
m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(90.0f), 0.01f, 5000.f);
m_DefaultCamera->SetPosition(glm::vec3(0, 1, 10));
if (m_Camera == nullptr) {
m_Camera = m_DefaultCamera;
}
m_DebugCameraInputController = std::make_shared<DebugCameraInputController<Renderer>>(m_EventBroker, -1);
TEMPCreateLights();
InitializeRenderPasses();
glfwSwapInterval(m_VSYNC);
InitializeShaders();
InitializeTextures();
InitializeSSBOs();
//CalculateFrustum();
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
@@ -75,49 +72,10 @@ void Renderer::InitializeShaders()
m_DrawScreenQuadProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl")));
m_DrawScreenQuadProgram->Compile();
m_DrawScreenQuadProgram->Link();
//m_CalculateFrustumProgram = ResourceManager::Load<ShaderProgram>("#CalculateFrustumProgram");
//m_CalculateFrustumProgram.AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/GridFrustum.comp.glsl")));
//m_CalculateFrustumProgram.Compile();
//m_CalculateFrustumProgram.Link();
//m_LightCullProgram = ResourceManager::Load<ShaderProgram>("#LightCullProgram");
//m_LightCullProgram.AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/cullLights.comp.glsl")));
//m_LightCullProgram.Compile();
//m_LightCullProgram.Link();
}
void Renderer::InputUpdate(double dt)
{
glm::vec3 m_Position = m_Camera->Position();
if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS)
{
m_Position = glm::vec3(0.f, 0.f, 5.f);
}
if (glfwGetKey(m_Window, GLFW_KEY_W) == GLFW_PRESS)
{
m_Position += m_Camera->Forward() * m_CameraMoveSpeed * (float)dt;
}
if (glfwGetKey(m_Window, GLFW_KEY_S) == GLFW_PRESS)
{
m_Position -= m_Camera->Forward() * m_CameraMoveSpeed * (float)dt;
}
if (glfwGetKey(m_Window, GLFW_KEY_D) == GLFW_PRESS)
{
m_Position += m_Camera->Right() * m_CameraMoveSpeed * (float)dt;
}
if (glfwGetKey(m_Window, GLFW_KEY_A) == GLFW_PRESS)
{
m_Position -= m_Camera->Right() * m_CameraMoveSpeed * (float)dt;
}
if (glfwGetKey(m_Window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
{
m_CameraMoveSpeed = 5.f;
}
else {
m_CameraMoveSpeed = 0.5f;
}
m_DebugCameraInputController->Update(dt);
m_Camera->SetOrientation(m_DebugCameraInputController->Orientation());
m_Camera->SetPosition(m_DebugCameraInputController->Position());
@@ -134,11 +92,12 @@ void Renderer::Draw(RenderQueueCollection& rq)
{
m_PickingPass->Draw(rq);
//DrawScreenQuad(m_PickingPass->PickingTexture());
//CullLights();
m_LightCullingPass->FillLightList(rq);
m_LightCullingPass->CullLights();
//m_DrawScenePass->Draw(rq);
m_DrawFinalPass->Draw(rq);
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f);
m_DrawScenePass->Draw(rq);
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
m_ImGuiRenderPass->Draw();
glfwSwapBuffers(m_Window);
@@ -183,95 +142,10 @@ void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filterin
GLERROR("Texture initialization failed");
}
void Renderer::InitializeSSBOs()
{
printf("Size: %i\n", sizeof(m_Frustums));
glGenBuffers(1, &m_FrustumSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_Frustums), &m_Frustums, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_FrustumSSBO");
glGenBuffers(1, &m_LightSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_PointLights), &m_PointLights, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightSSBO");
glGenBuffers(1, &m_LightGridSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightGrid), &m_LightGrid, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightGridSSBO");
glGenBuffers(1, &m_LightOffsetSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightOffsetSSBO");
glGenBuffers(1, &m_LightIndexSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightIndexSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightIndex), &m_LightIndex, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightIndexSSBO");
}
void Renderer::InitializeRenderPasses()
{
m_DrawScenePass = new DrawScenePass(this);
m_PickingPass = new PickingPass(this, m_EventBroker);
}
void Renderer::CalculateFrustum()
{
GLERROR("CalculateFrustum Error-1");
m_CalculateFrustumProgram->Bind();
GLERROR("CalculateFrustum Error1");
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
GLERROR("CalculateFrustum Error2");
glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix()));
GLERROR("CalculateFrustum Error3");
glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height);
GLERROR("CalculateFrustum Error4");
glDispatchCompute(5, 3, 1);
GLERROR("CalculateFrustum Error5");
}
void Renderer::TEMPCreateLights()
{
for (int i = 0; i < NUM_LIGHTS; i++) {
m_PointLights[i].Position = glm::vec4(i, 0.f, 0.f, 0.f);
m_PointLights[i].Color = glm::vec4(1.f, 0.5f, 0.f + i*0.1f, 1.f);
}
}
void Renderer::CullLights()
{
m_LightCullProgram->Bind();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO);
glDispatchCompute(m_Resolution.Width / TILE_SIZE, m_Resolution.Height / TILE_SIZE, 1);
GLERROR("CullLights Error");
}
m_LightCullingPass = new LightCullingPass(this);
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass);
}
+17 -10
View File
@@ -19,22 +19,29 @@ void HealthSystem::UpdateComponent(World *world, ComponentWrapper &health, doubl
for (size_t i = m_DeltaHealthVector.size(); i > 0; i--)
{
auto deltaHP = m_DeltaHealthVector[i - 1];
//if we have a healthchange for the current player, then apply it
if (std::get<0>(deltaHP) == player.EntityID) {
//if we have a healthchange for the current player and health is greater than 0, then apply it
if (std::get<0>(deltaHP) == player.EntityID && (double)health["Health"] > 0.0f) {
//get the deltaHP value from the tuple and make sure you dont get more than maxHealth
double newHealth = std::min((double)health["Health"] + (double)std::get<1>(deltaHP), maxHealth);
health["Health"] = newHealth;
m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + i - 1);
//check if health is <= 0
if ((double)health["Health"] <= 0.0f) {
//publish death event
Events::PlayerDeath e;
e.PlayerID = player.EntityID;
m_EventBroker->Publish(e);
//clear the remaining hpDeltas for the dead player
for (size_t j = m_DeltaHealthVector.size(); j > 0; j--)
{
if (std::get<0>(m_DeltaHealthVector[j - 1]) == player.EntityID)
m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + j - 1);
}
//break the loop if the player is dead
break;
}
}
}
//check if health is <= 0
if ((double)health["Health"] <= 0.0f) {
//publish death event
Events::PlayerDeath e;
e.PlayerID = player.EntityID;
m_EventBroker->Publish(e);
}
}
bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e)
+172
View File
@@ -0,0 +1,172 @@
#include "Export.h"
Export::Export()
{
}
bool Export::Meshes(std::string pathName, bool selectedOnly)
{
if (pathName.empty()) {
MGlobal::displayError(MString() + "Export::Meshes() got no pathName. Do not know where to write file");
return false;
}
meshes.clear();
if (selectedOnly) {
// Retrieving the objects we currently have selected
MSelectionList selected;
MGlobal::getActiveSelectionList(selected);
// Loop through or list of selection(s)
for (unsigned int i = 0; i < selected.length(); i++) {
MObject object;
selected.getDependNode(i, object);
if (object.hasFn(MFn::kMesh)) {
MFnDependencyNode thisNode(object);
GetMeshData(object);
}
}
} else {
// Loop through all nodes in the scene
MItDependencyNodes it(MFn::kMesh);
for (; !it.isDone(); it.next()) {
MObject node = it.thisNode();
MFnDependencyNode thisNode(node);
MPlugArray connections;
thisNode.findPlug("inMesh").connectedTo(connections, true, true);
bool next = false;
for (unsigned int i = 0; i < connections.length(); i++) {
if (connections[i].node().apiType() == MFn::kSkinClusterFilter) {
next = true;
break;
}
}
if (next)
continue;
GetMeshData(node);
}
}
MGlobal::displayInfo(MString() + "nrofmeshes: " + meshes.size());
WriteMeshData(pathName);
return true;
}
bool Export::Materials()
{
return true;
}
bool Export::Animations(std::string pathName, std::vector<AnimationInfo> animInfo)
{
if (MAnimControl::currentTime().unit() != MTime::kNTSCField) {
MGlobal::displayError(MString() + "Please change to 60 FPS under Preferences/Settings!");
return false;
}
if (pathName.empty()) {
MGlobal::displayError(MString() + "Export::Animations() got no pathName. Do not know where to write file");
return false;
}
MGlobal::displayInfo("HALLOOOO");
allBindPoses = m_SkeletonHandler.GetBindPoses();
for (auto clip : animInfo) {
MGlobal::displayInfo("preben");
if (!GetAnimationData(clip)) {
MGlobal::displayError(MString() + "Export::Animations() failed to export " + clip.Name.c_str());
return false;
}
}
MGlobal::displayInfo("ghihgihi");
WriteAnimData(pathName);
return true;
}
bool Export::GetMeshData(MObject object)
{
if (!object.hasFn(MFn::kMesh))
return false;
meshes.push_back(m_MeshHandler.GetMeshData(object));
return true;
}
bool Export::GetMaterialData()
{
// Traverse scene and return vector with all materials
std::vector<MaterialNode>* AllMaterials = m_MaterialHandler.DoIt();
// Access the colorR component of one material (example)
cout << AllMaterials->at(0).Color[0] << endl;
MGlobal::displayInfo(MString() + AllMaterials->at(0).Color[0]);
return true;
}
bool Export::GetAnimationData(AnimationInfo animInfo)
{
if (animInfo.Name.empty()) {
MGlobal::displayError(MString() + "A clip does not have a name");
return false;
}
if (animInfo.End - animInfo.Start <= 0) {
MGlobal::displayError(MString() + "A clip ends before it starts or contains 0 frames");
return false;
}
allAnimations.push_back(m_SkeletonHandler.GetAnimData(animInfo.Name, animInfo.Start, animInfo.End));
return true;
}
void Export::WriteMeshData(std::string pathName)
{
m_MeshFile.ASCIIFilePath(pathName +"_mesh.txt");
m_MeshFile.binaryFilePath(pathName + ".mesh");
m_MeshFile.OpenFiles();
for (auto aMesh : meshes) {
m_MeshFile.writeToFiles((OutputData*)&aMesh);
}
m_MeshFile.CloseFiles();
}
void Export::WriteAnimData(std::string pathName)
{
if (allBindPoses.size() > 0) {
m_AnimFile.ASCIIFilePath(pathName + "_anim.txt");
m_AnimFile.binaryFilePath(pathName + ".anim");
m_AnimFile.OpenFiles();
int size = allBindPoses.size();
m_AnimFile.writeToFiles(&size);
size = allAnimations.size();
m_AnimFile.writeToFiles(&size);
//print out all bind poses
for (auto aBindPose : allBindPoses) {
m_AnimFile.writeToFiles((OutputData*)&aBindPose);
}
for (auto aAnimation : allAnimations) {
m_AnimFile.writeToFiles((OutputData*)&aAnimation);
}
m_AnimFile.CloseFiles();
} else
MGlobal::displayInfo("Export::WriteAnimData() got called when allBindPoses contained no data, did not write nor created them");
}
Export::~Export()
{
/* delete m_MaterialHandler;
delete m_SkeletonHandler;
delete m_MeshHandler;*/
}
+54
View File
@@ -0,0 +1,54 @@
#ifndef Export_Export_h__
#define Export_Export_h__
#include <vector>
#include <string>
#include "MayaIncludes.h"
#include "Material.h"
#include "Mesh.h"
#include "Skeleton.h"
#include "WriteToFile.h"
class Export {
public:
Export();
~Export();
struct AnimationInfo {
std::string Name;
int Start;
int End;
};
bool Meshes(std::string pathName, bool selectedOnly = false);
bool Materials();
bool Animations(std::string pathName, std::vector<AnimationInfo> animInfo);
private:
bool GetMeshData(MObject object);
bool GetMaterialData();
bool GetAnimationData(AnimationInfo info);
void WriteMeshData(std::string pathName);
void WriteAnimData(std::string pathName);
Material m_MaterialHandler;
Skeleton m_SkeletonHandler;
MeshClass m_MeshHandler;
//File export
WriteToFile m_MeshFile;
WriteToFile m_AnimFile;
//Mesh Data
std::vector<Mesh> meshes;
//Animation Data
std::vector<BindPoseSkeletonNode> allBindPoses;
std::vector<Animation> allAnimations;
};
#endif
@@ -22,7 +22,7 @@ static const uint qt_meta_data_Menu[] = {
6, // revision
0, // classname
0, 0, // classinfo
7, 14, // methods
5, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
@@ -30,22 +30,19 @@ static const uint qt_meta_data_Menu[] = {
0, // signalCount
// slots: signature, parameters, type, tag, flags
14, 6, 5, 5, 0x08,
35, 5, 5, 5, 0x08,
59, 5, 5, 5, 0x08,
6, 5, 5, 5, 0x08,
30, 5, 5, 5, 0x08,
51, 5, 5, 5, 0x08,
75, 5, 5, 5, 0x08,
95, 5, 5, 5, 0x08,
116, 5, 5, 5, 0x08,
137, 5, 5, 5, 0x08,
91, 5, 5, 5, 0x08,
0 // eod
};
static const char qt_meta_stringdata_Menu[] = {
"Menu\0\0checked\0ExportSelected(bool)\0"
"ExportPathClicked(bool)\0ExportAll(bool)\0"
"CancelClicked(bool)\0Button1Clicked(bool)\0"
"Button2Clicked(bool)\0Button3Clicked(bool)\0"
"Menu\0\0ExportPathClicked(bool)\0"
"AddClipClicked(bool)\0RemoveClipClicked(bool)\0"
"ExportAll(bool)\0CancelClicked(bool)\0"
};
void Menu::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
@@ -54,13 +51,11 @@ void Menu::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void *
Q_ASSERT(staticMetaObject.cast(_o));
Menu *_t = static_cast<Menu *>(_o);
switch (_id) {
case 0: _t->ExportSelected((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 1: _t->ExportPathClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 2: _t->ExportAll((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 3: _t->CancelClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 4: _t->Button1Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 5: _t->Button2Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 6: _t->Button3Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 0: _t->ExportPathClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 1: _t->AddClipClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 2: _t->RemoveClipClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 3: _t->ExportAll((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 4: _t->CancelClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
default: ;
}
}
@@ -98,9 +93,9 @@ int Menu::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 7)
if (_id < 5)
qt_static_metacall(this, _c, _id, _a);
_id -= 7;
_id -= 5;
}
return _id;
}
@@ -0,0 +1,241 @@
#include "Material.h"
void Material::grabLambertProperties(MaterialNode& material_node, MFnDependencyNode& node)
{
material_node.Name = node.name().asChar();
if (findColorTexture(material_node, node)) {
material_node.Color.fill(1.0f);
}
else {
m_Plug = node.findPlug("colorR");
m_Plug.getValue(material_node.Color[0]);
m_Plug = node.findPlug("colorG");
m_Plug.getValue(material_node.Color[1]);
m_Plug = node.findPlug("colorB");
m_Plug.getValue(material_node.Color[2]);
float TempTransp[3];
m_Plug = node.findPlug("transparencyR");
m_Plug.getValue(TempTransp[0]);
m_Plug = node.findPlug("transparencyG");
m_Plug.getValue(TempTransp[1]);
m_Plug = node.findPlug("transparencyB");
m_Plug.getValue(TempTransp[2]);
MColor TranspNode(TempTransp[0], TempTransp[1], TempTransp[2]);
float DummyH, DummyS;
TranspNode.get(MColor::kHSV, DummyH, DummyS, material_node.Color[3]);
}
if (findIncandescenceTexture(material_node, node)) {
material_node.Incandescence.fill(1.0f);
}
else {
m_Plug = node.findPlug("incandescenceR");
m_Plug.getValue(material_node.Incandescence[0]);
m_Plug = node.findPlug("incandescenceG");
m_Plug.getValue(material_node.Incandescence[1]);
m_Plug = node.findPlug("incandescenceB");
m_Plug.getValue(material_node.Incandescence[2]);
}
findNormalTexture(material_node, node);
}
void Material::grabBlinnProperties(MaterialNode& material_node, MFnDependencyNode& node)
{
if (findSpecularTexture(material_node, node)) {
material_node.Specular.fill(1.0f);
}
else {
m_Plug = node.findPlug("specularColorR");
m_Plug.getValue(material_node.Specular[0]);
m_Plug = node.findPlug("specularColorG");
m_Plug.getValue(material_node.Specular[1]);
m_Plug = node.findPlug("specularColorB");
m_Plug.getValue(material_node.Specular[2]);
}
m_Plug = node.findPlug("reflectivity");
m_Plug.getValue(material_node.ReflectionFactor);
m_Plug = node.findPlug("eccentricity");
float TempEccent;
m_Plug.getValue(TempEccent);
// Blinn works differently from Phong which is used in-game.
// This is some magic numbers and math to make a conversion estimate between the two.
// There is no exact conversion between the two, so there are errors.
// Phong min/max is around Blinn 0.7/0.1
TempEccent = std::max(std::min(TempEccent, 0.7f), 0.1f);
material_node.SpecularExponent = std::max(std::min(((2.66f) + (427.0f) * exp((-14.8f) * TempEccent)), 100.0f), 2.0f);
}
void Material::grabPhongProperties(MaterialNode& material_node, MFnDependencyNode& node)
{
if (findSpecularTexture(material_node, node)) {
material_node.Specular.fill(1.0f);
}
else {
m_Plug = node.findPlug("specularColorR");
m_Plug.getValue(material_node.Specular[0]);
m_Plug = node.findPlug("specularColorG");
m_Plug.getValue(material_node.Specular[1]);
m_Plug = node.findPlug("specularColorB");
m_Plug.getValue(material_node.Specular[2]);
}
m_Plug = node.findPlug("reflectivity");
m_Plug.getValue(material_node.ReflectionFactor);
m_Plug = node.findPlug("cosinePower ");
m_Plug.getValue(material_node.SpecularExponent);
}
bool Material::findColorTexture(MaterialNode& material_node, MFnDependencyNode& node)
{
MPlugArray AllConnections;
m_Plug = node.findPlug("color", true);
m_Plug.connectedTo(AllConnections, true, false);
for (int i = 0; i < AllConnections.length(); i++) {
if (AllConnections[i].node().hasFn(MFn::kFileTexture)) {
MFnDependencyNode TextureNode(AllConnections[i].node());
std::string FullPath = TextureNode.findPlug("ftn").asString().asChar();
m_TexturePaths.push_back(FullPath);
material_node.ColorMapFile = FullPath.substr(FullPath.find_last_of("/"));
// Test
MGlobal::displayInfo(MString() + "Texture file: " + FullPath.c_str());
return true;
}
}
return false;
}
bool Material::findNormalTexture(MaterialNode& material_node, MFnDependencyNode& node)
{
MPlugArray AllConnections;
MPlugArray AllBumpConnections;
m_Plug = node.findPlug("normalCamera", true);
m_Plug.connectedTo(AllConnections, true, false);
for (int i = 0; i < AllConnections.length(); i++) {
if (AllConnections[i].node().apiType() == MFn::kBump) {
MFnDependencyNode BumpNode(AllConnections[i].node());
BumpNode.findPlug("bumpValue").connectedTo(AllBumpConnections, true, false);
for (int j = 0; j < AllBumpConnections.length(); j++) {
if (AllBumpConnections[j].node().hasFn(MFn::kFileTexture)) {
MFnDependencyNode TextureNode(AllBumpConnections[j].node());
std::string FullPath = TextureNode.findPlug("ftn").asString().asChar();
m_TexturePaths.push_back(FullPath);
material_node.NormalMapFile = FullPath.substr(FullPath.find_last_of("/"));
return true;
}
}
}
}
return false;
}
bool Material::findSpecularTexture(MaterialNode& material_node, MFnDependencyNode& node)
{
MPlugArray AllConnections;
m_Plug = node.findPlug("specularColor", true);
m_Plug.connectedTo(AllConnections, true, false);
for (int i = 0; i < AllConnections.length(); i++) {
if (AllConnections[i].node().hasFn(MFn::kFileTexture)) {
MFnDependencyNode TextureNode(AllConnections[i].node());
std::string FullPath = TextureNode.findPlug("ftn").asString().asChar();
m_TexturePaths.push_back(FullPath);
material_node.SpecularMapFile = FullPath.substr(FullPath.find_last_of("/"));
return true;
}
}
return false;
}
bool Material::findIncandescenceTexture(MaterialNode& material_node, MFnDependencyNode& node)
{
MPlugArray AllConnections;
m_Plug = node.findPlug("incandescence", true);
m_Plug.connectedTo(AllConnections, true, false);
for (int i = 0; i < AllConnections.length(); i++) {
if (AllConnections[i].node().hasFn(MFn::kFileTexture)) {
MFnDependencyNode TextureNode(AllConnections[i].node());
std::string FullPath = TextureNode.findPlug("ftn").asString().asChar();
m_TexturePaths.push_back(FullPath);
material_node.SpecularMapFile = FullPath.substr(FullPath.find_last_of("/"));
return true;
}
}
return false;
}
// Returns the absolute path for all textures. Use for copying texture files.
std::vector<std::string>* Material::TexturePaths()
{
return &m_TexturePaths;
}
// Traverse the DAG and grab all the materials
std::vector<MaterialNode>* Material::DoIt()
{
// All materials we care about inherit from Lambert
MItDependencyNodes matIt(MFn::kLambert);
while (!matIt.isDone()) {
MFnDependencyNode MaterialFnDN(matIt.thisNode());
MaterialNode MaterialStorage;
if (matIt.thisNode().hasFn(MFn::kPhong)) {
grabLambertProperties(MaterialStorage, MaterialFnDN);
grabPhongProperties(MaterialStorage, MaterialFnDN);
m_AllMaterials.push_back(MaterialStorage);
}
else if (matIt.thisNode().hasFn(MFn::kBlinn)) {
grabLambertProperties(MaterialStorage, MaterialFnDN);
grabBlinnProperties(MaterialStorage, MaterialFnDN);
m_AllMaterials.push_back(MaterialStorage);
}
else if (matIt.thisNode().hasFn(MFn::kLambert)) {
grabLambertProperties(MaterialStorage, MaterialFnDN);
MaterialStorage.Specular.fill(0.0f);
MaterialStorage.ReflectionFactor = 0.0f;
MaterialStorage.SpecularExponent = 0.0f;
m_AllMaterials.push_back(MaterialStorage);
}
matIt.next();
}
return &m_AllMaterials;
}
@@ -0,0 +1,47 @@
#ifndef Material_Material_h__
#define Material_Material_h__
#include <vector>
#include <array>
#include <algorithm>
#include <cmath>
#include "MayaIncludes.h"
struct MaterialNode
{
std::string Name;
std::array<float, 4> Color;
std::array<float, 3> Incandescence;
std::array<float, 3> Specular;
float ReflectionFactor;
float SpecularExponent;
std::string ColorMapFile;
std::string SpecularMapFile;
std::string NormalMapFile;
std::string IncandescenceMapFile;
};
class Material
{
public:
Material() {};
~Material() {};
std::vector<MaterialNode>* DoIt();
std::vector<std::string>* TexturePaths();
private:
MPlug m_Plug;
std::vector<MaterialNode> m_AllMaterials;
std::vector<std::string> m_TexturePaths;
bool findColorTexture(MaterialNode& material_node, MFnDependencyNode& node);
bool findNormalTexture(MaterialNode& material_node, MFnDependencyNode& node);
bool findSpecularTexture(MaterialNode& material_node, MFnDependencyNode& node);
bool findIncandescenceTexture(MaterialNode& material_node, MFnDependencyNode& node);
void grabLambertProperties(MaterialNode& material_node, MFnDependencyNode& node);
void grabBlinnProperties(MaterialNode& material_node, MFnDependencyNode& node);
void grabPhongProperties(MaterialNode& material_node, MFnDependencyNode& node);
};
#endif // Material_Material_h__
@@ -140,6 +140,7 @@
</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<Optimization>Disabled</Optimization>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -152,6 +153,8 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Export.cpp" />
<ClCompile Include="Material.cpp" />
<ClCompile Include="Menu.cpp" />
<ClCompile Include="GeneratedFiles\Debug\moc_Menu.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -172,6 +175,9 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="Main.cpp" />
<ClCompile Include="Mesh.cpp" />
<ClCompile Include="Skeleton.cpp" />
<ClCompile Include="WriteToFile.cpp" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="MayaExporter.ui">
@@ -194,6 +200,11 @@
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Export.h" />
<ClInclude Include="Mesh.h" />
<ClInclude Include="OutputData.h" />
<ClInclude Include="Skeleton.h" />
<ClInclude Include="WriteToFile.h" />
<CustomBuild Include="Menu.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing Menu.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
@@ -213,6 +224,7 @@
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<ClInclude Include="GeneratedFiles\ui_MayaExporter.h" />
<ClInclude Include="Material.h" />
<ClInclude Include="MayaIncludes.h" />
</ItemGroup>
<ItemGroup>
@@ -50,6 +50,21 @@
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Material.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Mesh.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Skeleton.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WriteToFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Export.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="leeeeel.qrc">
@@ -69,5 +84,23 @@
<ClInclude Include="GeneratedFiles\ui_MayaExporter.h">
<Filter>Generated Files</Filter>
</ClInclude>
<ClInclude Include="Material.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mesh.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Skeleton.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WriteToFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="OutputData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Export.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -30,6 +30,18 @@
#include <maya/MItDependencyNodes.h>
#include <maya/MFnNurbsCurve.h>
#include <maya/MCommandMessage.h>
#include <maya/MPlug.h>
#include <maya/MAnimControl.h>
#include <maya/MTime.h>
#include <maya/MDataHandle.h>
#include <maya/MTransformationMatrix.h>
#include <maya/MFnMatrixData.h>
#include <maya/MItMeshFaceVertex.h>
#include <maya/MFnSkinCluster.h>
#include <maya/MDagPathArray.h>
#include <maya/MItGeometry.h>
#include <maya/MItMeshVertex.h>
#include <maya/MFnWeightGeometryFilter.h>
// Wrappers
@@ -58,5 +70,6 @@
#pragma comment(lib,"Foundation.lib")
#pragma comment(lib,"OpenMaya.lib")
#pragma comment(lib,"OpenMayaUI.lib")
#pragma comment (lib, "OpenMayaAnim.lib")
#endif
+145 -165
View File
@@ -10,223 +10,200 @@ Menu::Menu()
Menu::Menu(QDialog* dialog)
{
// Save the dialog pointer. Needed when the application gets destroyed
dialogPointer = dialog;
m_DialogPointer = dialog;
// Create QpushButtons & give them names
exportSelectedButton = new QPushButton("&Export Selected", this);
browseButton = new QPushButton("&...", this);
exportAllButton = new QPushButton("&Export All", this);
cancelButton = new QPushButton("&Cancel", this);
m_BrowseButton = new QPushButton("&...", this);
m_ExportAllButton = new QPushButton("&Export", this);
m_CancelButton = new QPushButton("&Cancel", this);
m_AddClipsButton = new QPushButton("&Add Clips", this);
m_RemoveClipsButton = new QPushButton("&Remove Latest Clip", this);
// Option box and checkboxes
QGroupBox *optionsBox = new QGroupBox(tr("Options"));
exportAnimationsButton = new QCheckBox(tr("&Export Animations"));
copyTexturesButton = new QCheckBox(tr("&Copy Textures"));
button3 = new QCheckBox(tr("option3"));
m_ExportSelectedButton = new QCheckBox(tr("&Export Selected"));
m_ExportAnimationsButton = new QCheckBox(tr("&Export Animations"));
m_CopyTexturesButton = new QCheckBox(tr("&Copy Textures"));
m_Button3 = new QCheckBox(tr("Test Materials"));
exportAnimationsButton->setChecked(true);
copyTexturesButton->setChecked(true);
m_ExportAnimationsButton->setChecked(true);
m_CopyTexturesButton->setChecked(true);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(exportAnimationsButton);
vbox->addWidget(copyTexturesButton);
vbox->addWidget(button3);
vbox->addWidget(m_ExportSelectedButton);
vbox->addWidget(m_ExportAnimationsButton);
vbox->addWidget(m_CopyTexturesButton);
vbox->addWidget(m_Button3);
vbox->addStretch(1);
optionsBox->setLayout(vbox);
// Connect the buttons with signals & functions
connect(exportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(ExportSelected(bool)));
connect(browseButton, SIGNAL(clicked(bool)), this, SLOT(ExportPathClicked(bool)));
connect(exportAllButton, SIGNAL(clicked(bool)), this, SLOT(ExportAll(bool)));
connect(cancelButton, SIGNAL(clicked(bool)), this, SLOT(CancelClicked(bool)));
connect(m_BrowseButton, SIGNAL(clicked(bool)), this, SLOT(ExportPathClicked(bool)));
connect(m_ExportAllButton, SIGNAL(clicked(bool)), this, SLOT(ExportAll(bool)));
connect(m_CancelButton, SIGNAL(clicked(bool)), this, SLOT(CancelClicked(bool)));
connect(m_AddClipsButton, SIGNAL(clicked(bool)), this, SLOT(AddClipClicked(bool)));
connect(m_RemoveClipsButton, SIGNAL(clicked(bool)), this, SLOT(RemoveClipClicked(bool)));
connect(exportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(Button1Clicked(bool)));
connect(copyTexturesButton, SIGNAL(clicked(bool)), this, SLOT(Button2Clicked(bool)));
connect(button3, SIGNAL(clicked(bool)), this, SLOT(Button3Clicked(bool)));
connect(m_ExportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(NULL));
connect(m_ExportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(NULL));
connect(m_CopyTexturesButton, SIGNAL(clicked(bool)), this, SLOT(NULL));
connect(m_Button3, SIGNAL(clicked(bool)), this, SLOT(NULL));
// Creating several layouts, adding widgets & adding them to one layout in the end
QHBoxLayout* topLayout = new QHBoxLayout;
QVBoxLayout* midLayout = new QVBoxLayout;
QHBoxLayout* botLayout = new QHBoxLayout;
QVBoxLayout* baseLayout = new QVBoxLayout;
QHBoxLayout* clipButtonLayout = new QHBoxLayout;
QHBoxLayout* startEndLabelLayout = new QHBoxLayout;
m_ClipLayout = new QVBoxLayout;
exportPath = new QLineEdit;
fileDialog = new QFileDialog;
m_ExportPath = new QLineEdit;
m_FileDialog = new QFileDialog;
QString tmpPath("C:/Users/Nickelodion/Desktop/Baljj");
m_ExportPath->setText(tmpPath);
QLabel* exportLabel = new QLabel;
exportLabel->setText("Export Path:");
QLabel* nameLabel = new QLabel;
nameLabel->setText("Name:");
QLabel* startLabel = new QLabel;
startLabel->setText("Start:");
QLabel* endLabel = new QLabel;
endLabel->setText("End:");
//exportLabel->setText("Export Path:");
midLayout->addWidget(optionsBox);
topLayout->addWidget(exportLabel);
topLayout->addWidget(exportPath);
topLayout->addWidget(browseButton);
topLayout->addWidget(m_ExportPath);
topLayout->addWidget(m_BrowseButton);
botLayout->addWidget(exportSelectedButton);
botLayout->addWidget(exportAllButton);
botLayout->addWidget(cancelButton);
botLayout->addWidget(m_ExportAllButton);
botLayout->addWidget(m_CancelButton);
startEndLabelLayout->addWidget(nameLabel);
startEndLabelLayout->addWidget(startLabel);
startEndLabelLayout->addWidget(endLabel);
clipButtonLayout->addWidget(m_AddClipsButton);
clipButtonLayout->addWidget(m_RemoveClipsButton);
baseLayout->addLayout(topLayout);
baseLayout->addLayout(midLayout);
baseLayout->addSpacing(10);
baseLayout->addLayout(botLayout);
baseLayout->addSpacing(10);
baseLayout->addLayout(clipButtonLayout);
baseLayout->addLayout(startEndLabelLayout);
baseLayout->addLayout(m_ClipLayout);
baseLayout->addStretch();
// Set the layout for our window
dialog->setLayout(baseLayout);
}
void Menu::ExportSelected(bool checked)
{
// Retrieving the objects we currently have selected
MSelectionList selected;
MGlobal::getActiveSelectionList(selected);
// Loop through or list of selection(s)
for (unsigned int i = 0; i < selected.length();i++)
{
MObject object;
selected.getDependNode(i, object);
MFnDependencyNode thisNode(object);
cout << thisNode.name().asChar() << endl;
GetMeshData(object);
for (unsigned int i = 0; i < 3; i++) {
this->AddClipClicked(true);
}
if (exportPath->text().isEmpty())
cout << "Please select a folder." << endl;
else
cout << exportPath->text().toLocal8Bit().constData() << endl;
}
void Menu::ExportPathClicked(bool)
{
// Opens up a file dialog. Save/Changes the name in the exportPath
fileDialog->setFileMode(QFileDialog::Directory);
fileDialog->setOption(QFileDialog::ShowDirsOnly);
QString fileName = fileDialog->getExistingDirectory(this, "Select", "/home", QFileDialog::ShowDirsOnly);
exportPath->setText(fileName);
m_FileDialog->setFileMode(QFileDialog::Directory);
m_FileDialog->setOption(QFileDialog::ShowDirsOnly);
QString fileName = m_FileDialog->getExistingDirectory(this, "Select", "/home", QFileDialog::ShowDirsOnly);
m_ExportPath->setText(fileName);
}
void Menu::AddClipClicked(bool)
{
QHBoxLayout* tempLayout = new QHBoxLayout;
QLineEdit* nameLineEdit = new QLineEdit;
QLineEdit* startLineEdit = new QLineEdit;
QLineEdit* endLineEdit = new QLineEdit;
m_AnimationClipName.push_back(nameLineEdit);
m_StartFrameLines.push_back(startLineEdit);
m_EndFrameLines.push_back(endLineEdit);
tempLayout->addWidget(nameLineEdit);
tempLayout->addWidget(startLineEdit);
tempLayout->addWidget(endLineEdit);
m_ClipLayout->addLayout(tempLayout);
//m_ClipLayout->update();
layouts.push_back(tempLayout);
}
void Menu::RemoveClipClicked(bool)
{
if (m_StartFrameLines.size() > 0) {
QLayoutItem* tempWidget;// = m_ClipLayout->itemAt(0);
for (unsigned int i = 0; i < layouts.size(); i++) {
while ((tempWidget = layouts[layouts.size() - 1]->takeAt(0)) != 0) {
delete tempWidget->widget();
delete tempWidget;
}
}
m_ClipLayout->removeItem(tempWidget);
m_ClipLayout->update();
layouts.pop_back();
m_StartFrameLines.pop_back();
m_EndFrameLines.pop_back();
m_AnimationClipName.pop_back();
}
}
void Menu::ExportAll(bool)
{
MDagPath path;
// Loop through all nodes in the scene
MItDependencyNodes it(MFn::kInvalid);
for (;!it.isDone();it.next())
{
MObject node = it.thisNode();
if (node.hasFn(MFn::kMesh))
{
MFnDependencyNode thisNode(node);
if (m_ExportPath->text().isEmpty()) {
MGlobal::displayError(MString() + "Please select a folder.");
return;
}
cout << thisNode.name().asChar() << endl;
GetMeshData(node);
}
}
if (exportPath->text().isEmpty())
cout << "Please select a folder." << endl;
else
cout << exportPath->text().toLocal8Bit().constData() << endl;
//Export meshes
if (!m_Export.Meshes(m_ExportPath->text().toLocal8Bit().constData(), m_ExportSelectedButton->isChecked())) {
MGlobal::displayError(MString() + "Could not export mesh");
return;
}
std::vector<Export::AnimationInfo> animations;
MGlobal::displayInfo(MString() + "yeeehaa");
for (unsigned int i = 0; i < m_AnimationClipName.size(); i++) {
Export::AnimationInfo thisClip;
MGlobal::displayInfo(MString() + "qwqw");
thisClip.Name = std::string(m_AnimationClipName[i]->text().toLocal8Bit().constData());
MGlobal::displayInfo(MString() + "shizzzz");
thisClip.Start = m_StartFrameLines[i]->text().toInt();
MGlobal::displayInfo(MString() + "dsdsfg");
thisClip.End = m_EndFrameLines[i]->text().toInt();
MGlobal::displayInfo(MString() + "aaaaaaaaaaaaaaaaaaaa");
animations.push_back(thisClip);
}
MGlobal::displayInfo(MString() + "asdf");
if (m_ExportAnimationsButton->isChecked()) {
//Export Animations
if (!m_Export.Animations(m_ExportPath->text().toLocal8Bit().constData(), animations)) {
MGlobal::displayError(MString() + "Could not export animations");
return;
}
}
}
void Menu::CancelClicked(bool)
{
dialogPointer->close();
}
void Menu::Button1Clicked(bool)
{
if(exportAnimationsButton->isChecked())
cout << "1 checked!" << endl;
else
cout << "1 unchecked!" << endl;
}
void Menu::Button2Clicked(bool)
{
if (copyTexturesButton->isChecked())
cout << "2 checked!" << endl;
else
cout << "2 unchecked!" << endl;
}
void Menu::Button3Clicked(bool)
{
if (button3->isChecked())
cout << "3 checked!" << endl;
else
cout << "3 unchecked!" << endl;
}
void Menu::GetMeshData(MObject object)
{
// In here, we retrieve triangulated polygons from the mesh
MFnMesh mesh(object);
map<UINT, vector<UINT>> vertexToIndex;
vector<VertexLayout> verticesData;
vector<UINT>indexArray;
MIntArray intdexOffsetVertexCount, vertices, triangleList;
MPointArray dummy;
UINT vertexIndex;
MVector normal;
MPoint pos;
float2 UV;
VertexLayout thisVertex;
for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next())
{
vector<UINT> localVertexToGlobalIndex;
meshPolyIter.getVertices(vertices);
meshPolyIter.getTriangles(dummy, triangleList);
UINT indexOffset = verticesData.size();
for (UINT i = 0; i < vertices.length(); i++)
{
vertexIndex = meshPolyIter.vertexIndex(i);
pos = meshPolyIter.point(i);
pos.get(thisVertex.pos);
meshPolyIter.getNormal(i, normal);
thisVertex.normal[0] = normal[0];
thisVertex.normal[1] = normal[1];
thisVertex.normal[2] = normal[2];
meshPolyIter.getUV(i, UV);
thisVertex.uv[0] = UV[0];
thisVertex.uv[1] = UV[1];
verticesData.push_back(thisVertex);
localVertexToGlobalIndex.push_back(vertexIndex);
cout << "Pos: " << thisVertex.pos[0] << "/" << thisVertex.pos[1] << "/" << thisVertex.pos[2] << endl;
cout << "Normals: " << thisVertex.normal[0] << "/" << thisVertex.normal[1] << "/" << thisVertex.normal[2] << endl;
cout << "UV: " << thisVertex.uv[0] << "/" << thisVertex.uv[1] << endl;
}
for (UINT i = 0; i < triangleList.length(); i++)
{
UINT k = 0;
while (localVertexToGlobalIndex[k] != triangleList[i])
k++;
indexArray.push_back(indexOffset + k);
}
}
}
void Menu::exportMaterial(MObject object)
{
MItDependencyNodes matIt(MFn::kLambert);
m_DialogPointer->close();
}
Menu::~Menu()
@@ -235,5 +212,8 @@ Menu::~Menu()
//delete browseButton;
//delete exportPath;
//delete fileDialog;
fileDialog->~QFileDialog();
m_FileDialog->~QFileDialog();
//delete m_Export;
//delete MaterialHandler;
}
+27 -28
View File
@@ -1,10 +1,9 @@
#ifndef BUTTONS_H
#define BUTTONS_H
#ifndef Menu_Menu_h__
#define Menu_Menu_h__
#include <map>
#include <vector>
#include "MayaIncludes.h"
// Qt
#pragma comment(lib, "QtCore4")
#pragma comment(lib, "QtGui4")
@@ -30,13 +29,11 @@
#include <QtGui/qfiledialog.h>
#include <QtGui/qlineedit.h>
#include <QtGui/qgroupbox.h>
#include <QtGui/qlayoutitem.h>
#include <QtGui/qtabwidget.h>
struct VertexLayout
{
float pos[3];
float normal[3];
float uv[2];
};
#include "MayaIncludes.h"
#include "Export.h"
class Menu : public QWidget
{
@@ -45,35 +42,37 @@ public:
Menu(QDialog* dialog);
~Menu();
void GetMeshData(MObject object);
void exportMaterial(MObject object);
private slots:
void ExportSelected(bool checked);
void ExportPathClicked(bool);
void AddClipClicked(bool);
void RemoveClipClicked(bool);
void ExportAll(bool);
void CancelClicked(bool);
void Button1Clicked(bool);
void Button2Clicked(bool);
void Button3Clicked(bool);
private:
Menu();
QPushButton* exportSelectedButton;
QPushButton* browseButton;
QPushButton* exportAllButton;
QPushButton* cancelButton;
std::vector<QLineEdit*> m_AnimationClipName;
std:: vector<QLineEdit*> m_StartFrameLines;
std::vector<QLineEdit*> m_EndFrameLines;
std::vector<QHBoxLayout*> layouts;
QVBoxLayout* m_ClipLayout;
QCheckBox* exportAnimationsButton;
QCheckBox* copyTexturesButton;
QCheckBox* button3;
QPushButton* m_BrowseButton = nullptr;
QPushButton* m_ExportAllButton = nullptr;
QPushButton* m_CancelButton = nullptr;
QPushButton* m_AddClipsButton = nullptr;
QPushButton* m_RemoveClipsButton = nullptr;
QLineEdit* exportPath;
QFileDialog* fileDialog;
QDialog* dialogPointer;
QCheckBox* m_ExportSelectedButton = nullptr;
QCheckBox* m_ExportAnimationsButton = nullptr;
QCheckBox* m_CopyTexturesButton = nullptr;
QCheckBox* m_Button3 = nullptr;
QLineEdit* m_ExportPath = nullptr;
QFileDialog* m_FileDialog = nullptr;
QDialog* m_DialogPointer = nullptr;
Export m_Export;
};
#endif
+190
View File
@@ -0,0 +1,190 @@
#pragma once
#include "Mesh.h"
using namespace std;
MeshClass::MeshClass()
{
}
std::map<int, MeshClass::WeightInfo> MeshClass::GetWeightData()
{
map<int, WeightInfo> weightMap;
MItDependencyNodes it(MFn::kSkinClusterFilter);
while (!it.isDone()) {
MObject object = it.item();
MFnSkinCluster skinCluster(object);
MDagPathArray influences;
unsigned int nrOfInfluences = skinCluster.influenceObjects(influences);
unsigned int index;
index = skinCluster.indexForOutputConnection(0);
MDagPath skinPath;
skinCluster.getPathAtIndex(index, skinPath);
MItGeometry geomIter(skinPath);
//for (unsigned int i = 0; i < nrOfInfluences; i++) {
// MGlobal::displayInfo(MString() + " Influence object name: " + influences[i].partialPathName().asChar());
//}
WeightInfo weightInfo;
while (!geomIter.isDone()) {
MObject comp = geomIter.component();
MFloatArray weights;
unsigned int influenceCount;
skinCluster.getWeights(skinPath, comp, weights, influenceCount);
MFnDependencyNode test(comp);
unsigned int nrOfWeights = 0;
for (unsigned int j = 0; j < weights.length() && nrOfWeights != 4; j++) {
if (weights[j] > 0.00001) {
weightInfo.BoneWeights[nrOfWeights] = weights[j];
weightInfo.BoneIndices[nrOfWeights] = j;
nrOfWeights++;
}
}
float totalWeight = 0.0f;
for (unsigned int i = 0; i < 4; i++) {
totalWeight += weightInfo.BoneWeights[i];
}
for (unsigned int i = 0; i < 4; i++) {
weightInfo.BoneWeights[i] /= totalWeight;
}
weightMap[geomIter.index()] = weightInfo;
for (unsigned int k = 0; k!=nrOfWeights; k++) {
//MGlobal::displayInfo(MString() + "influence: " + weightInfo.BoneIndices[k] + " weight: " + weightInfo.BoneWeights[k]);
}
geomIter.next();
}
it.next();
}
return weightMap;
}
Mesh MeshClass::GetMeshData(MObject object)
{
Mesh newMesh;
std::vector<VertexLayout>& vertexList = newMesh.Vertices;
std::vector<int>& indexList = newMesh.Indices;
// In here, we retrieve triangulated polygons from the mesh
MFnMesh mesh(object);
map<unsigned int, vector<unsigned int>> vertexToIndex;;
MIntArray intdexOffsetVertexCount, vertices, triangleList;
MPointArray dummy;
unsigned int vertexIndex;
MVector normal;
MPoint pos;
float2 UV;
double biTangent[3];
double biNormal[3];
VertexLayout thisVertex;
MFloatVectorArray biTangents;
MFloatVectorArray biNormals;
std::map<int, WeightInfo> vertexWeights = GetWeightData();
mesh.getTangents(biTangents, MSpace::kObject, NULL);
mesh.getBinormals(biNormals, MSpace::kObject, NULL);
MItMeshFaceVertex faceVert(object);
int intDummy = 0;
for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next()) {
vector<unsigned int> localVertexToGlobalIndex;
unsigned int indexOffset = vertexList.size();
meshPolyIter.getVertices(vertices);
meshPolyIter.getTriangles(dummy, triangleList);
//MGlobal::displayInfo("Befor Second Loop");
for (unsigned int i = 0; i < vertices.length(); i++) {
vertexIndex = meshPolyIter.vertexIndex(i);
faceVert.setIndex(meshPolyIter.index(), i, intDummy, intDummy);
//MGlobal::displayInfo("In Second Loop");
faceVert.position().get(thisVertex.Pos);
faceVert.getNormal(normal);
thisVertex.Normal[0] = normal[0];
thisVertex.Normal[1] = normal[1];
thisVertex.Normal[2] = normal[2];
MFloatVector biTangent = biTangents[faceVert.tangentId()];
//MVector tmp = faceVert.getTangent(MSpace::kObject, NULL);
//tmp.get(biTangent);
thisVertex.BiTangent[0] = biTangent[0];
thisVertex.BiTangent[1] = biTangent[1];
thisVertex.BiTangent[2] = biTangent[2];
MFloatVector biNormal = biNormals[faceVert.tangentId()];
//faceVert.getBinormal().get(biNormal);
thisVertex.BiNormal[0] = biNormal[0];
thisVertex.BiNormal[1] = biNormal[1];
thisVertex.BiNormal[2] = biNormal[2];
faceVert.getUV(UV);
thisVertex.Uv[0] = UV[0];
thisVertex.Uv[1] = UV[1];
thisVertex.BoneIndices[0] = vertexWeights[faceVert.vertId()].BoneIndices[0];
thisVertex.BoneIndices[1] = vertexWeights[faceVert.vertId()].BoneIndices[1];
thisVertex.BoneIndices[2] = vertexWeights[faceVert.vertId()].BoneIndices[2];
thisVertex.BoneIndices[3] = vertexWeights[faceVert.vertId()].BoneIndices[3];
thisVertex.BoneWeights[0] = vertexWeights[faceVert.vertId()].BoneWeights[0];
thisVertex.BoneWeights[1] = vertexWeights[faceVert.vertId()].BoneWeights[1];
thisVertex.BoneWeights[2] = vertexWeights[faceVert.vertId()].BoneWeights[2];
thisVertex.BoneWeights[3] = vertexWeights[faceVert.vertId()].BoneWeights[3];
std::vector<VertexLayout>::iterator it = std::find(vertexList.begin(), vertexList.end(), thisVertex);
if (it != vertexList.end()) {
localVertexToGlobalIndex.push_back(vertexIndex);
} else {
localVertexToGlobalIndex.push_back(vertexIndex);
vertexList.push_back(thisVertex);
}
//cout << "Pos: " << thisVertex.Pos[0] << "/" << thisVertex.Pos[1] << "/" << thisVertex.Pos[2] << endl;
//cout << "Normals: " << thisVertex.Normal[0] << "/" << thisVertex.Normal[1] << "/" << thisVertex.Normal[2] << endl;
//cout << "Bi-Normals: " << thisVertex.BiNormal[0] << "/" << thisVertex.BiNormal[1] << "/" << thisVertex.BiNormal[2] << endl;
//cout << "Bi-Tangents: " << thisVertex.BiTangent[0] << "/" << thisVertex.BiTangent[1] << "/" << thisVertex.BiTangent[2] << endl;
//cout << "UV: " << thisVertex.Uv[0] << "/" << thisVertex.Uv[1] << endl;
}
for (unsigned int i = 0; i < triangleList.length(); i++) {
unsigned int k = 0;
if (localVertexToGlobalIndex.size() > 0) {
while (localVertexToGlobalIndex[k] != triangleList[i] && k < localVertexToGlobalIndex.size()) {
k++;
}
indexList.push_back(indexOffset + k);
}
}
}
newMesh.NumIndices = newMesh.Indices.size();
newMesh.NumVertices = newMesh.Vertices.size();
return newMesh;
}
MeshClass::~MeshClass()
{
}
+110
View File
@@ -0,0 +1,110 @@
#ifndef Mesh_Mesh_h__
#define Mesh_Mesh_h__
#include <map>
#include <vector>
#include "OutputData.h"
#include "MayaIncludes.h"
class VertexLayout : public OutputData
{
public:
float Pos[3];
float Normal[3];
float BiNormal[3];
float BiTangent[3];
float Uv[2];
float BoneIndices[4];
float BoneWeights[4];
virtual void WriteBinary(std::ostream& out)
{
out.write((char*)&Pos, sizeof(float) * 3);
out.write((char*)&Normal, sizeof(float) * 3);
out.write((char*)&BiNormal, sizeof(float) * 3);
out.write((char*)&BiTangent, sizeof(float) * 3);
out.write((char*)&Uv, sizeof(float) * 2);
out.write((char*)&BoneIndices, sizeof(float) * 4);
out.write((char*)&BoneWeights, sizeof(float) * 4);
}
virtual void WriteASCII(std::ostream& out) const
{
out << Pos[0] << " " << Pos[1] << " " << Pos[2] << endl;
out << Normal[0] << " " << Normal[1] << " " << Normal[2] << endl;
out << BiNormal[0] << " " << BiNormal[1] << " " << BiNormal[2] << endl;
out << BiTangent[0] << " " << BiTangent[1] << " " << BiTangent[2] << endl;
out << Uv[0] << " " << Uv[1] << endl;
out << BoneIndices[0] << " " << BoneIndices[1] << " " << BoneIndices[2] << " " << BoneIndices[3] << endl;
out << BoneWeights[0] << " " << BoneWeights[1] << " " << BoneWeights[2] << " " << BoneWeights[3] << endl;
}
bool operator==(const VertexLayout& right)
{
return
this->Pos[0] == right.Pos[0] && this->Pos[1] == right.Pos[1] && this->Pos[2] == right.Pos[2] &&
this->Normal[0] == right.Normal[0] && this->Normal[1] == right.Normal[1] && this->Normal[2] == right.Normal[2] &&
this->BiNormal[0] == right.BiNormal[0] && this->BiNormal[1] == right.BiNormal[1] && this->BiNormal[2] == right.BiNormal[2] &&
this->BiTangent[0] == right.BiTangent[0] && this->BiTangent[1] == right.BiTangent[1] && this->BiTangent[2] == right.BiTangent[2] &&
this->Uv[0] == right.Uv[0] && this->Uv[1] == right.Uv[1] &&
this->BoneIndices[0] == right.BoneIndices[0] && this->BoneIndices[1] == right.BoneIndices[1] && this->BoneIndices[2] == right.BoneIndices[2] && this->BoneIndices[3] == right.BoneIndices[3] &&
this->BoneWeights[0] == right.BoneWeights[0] && this->BoneWeights[1] == right.BoneWeights[1] && this->BoneWeights[2] == right.BoneWeights[2] && this->BoneWeights[3] == right.BoneWeights[3]
;
}
};
class Mesh : public OutputData {
public:
int NumVertices;
int NumIndices;
std::vector<VertexLayout> Vertices;
std::vector<int> Indices;
virtual void WriteBinary(std::ostream& out)
{
out.write((char*)&NumVertices, sizeof(int));
out.write((char*)&NumIndices, sizeof(int));
for (auto aVertex : Vertices) {
aVertex.WriteBinary(out);
}
for (auto aIndex : Indices) {
out.write((char*)&aIndex, sizeof(int));
}
}
virtual void WriteASCII(std::ostream& out) const
{
out << "New Mesh _ not in binary" << endl;
out << "Number of vertices: " << NumVertices << endl;
out << "number of indices: " << NumIndices << endl;
int vertexNumber = 0;
for (auto aVertex : Vertices) {
out << "New vertex number: " << vertexNumber << "_ not in binary" << endl;
aVertex.WriteASCII(out);
vertexNumber++;
}
for (int i = 0; i < NumIndices; i += 3) {
out << Indices[i] << " " << Indices[i+1] << " " << Indices[i + 2] << endl;
}
}
};
class MeshClass
{
public:
MeshClass();
Mesh GetMeshData(MObject Object);
~MeshClass();
private:
struct WeightInfo {
float BoneIndices[4] = { 0 };
float BoneWeights[4] = { 0 };
};
std::map<int, WeightInfo> GetWeightData();
};
#endif
@@ -0,0 +1,23 @@
#ifndef OutputData_OutputData_h__
#define OutputData_OutputData_h__
#include <fstream>
//template <typename T>
class OutputData
{
public://std::ostream& out, const OutputData& obj
//OutputData(T& object)
// : m_Object(object)
//{};
friend std::ostream& operator<<(std::ostream& out, const OutputData& obj)
{
obj.WriteASCII(out);
return out;
};
virtual void WriteBinary(std::ostream& out) = 0;
virtual void WriteASCII(std::ostream& out) const = 0;
//T& m_Object = nullptr;
};
#endif
@@ -0,0 +1,251 @@
#include "Skeleton.h"
//std::vector<SkeletonNode> Skeleton::DoIt()
//{
// std::vector<SkeletonNode> m_AllSkeletons;
//
// MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint);
// SkeletonNode SkeletonStorage;
//
// while (!jointIt.isDone()) {
// MFnTransform TransformNode(jointIt.currentItem());
// Joint NewJoint;
//
// if (MFnDependencyNode(TransformNode.parent(0)).name() == "world") {
// if (SkeletonStorage.Joints.size() != 0) {
// m_AllSkeletons.push_back(SkeletonStorage);
//
// SkeletonStorage.Joints.clear();
// SkeletonStorage.Name.clear();
// }
//
// SkeletonStorage.Name = TransformNode.name().asChar();
//
// //NewJoint.ParentIndex = -1; // This joint is root
// }
//
// //NewJoint.Name = TransformNode.name().asChar();
//
// MMatrix Matrix = TransformNode.transformationMatrix();
//
// //double tmp[3];
// //((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp);
// //NewJoint.Rotation[0] = tmp[0];
// //NewJoint.Rotation[1] = tmp[1];
// //NewJoint.Rotation[2] = tmp[2];
// //((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform);
// //NewJoint.Scale[0] = tmp[0];
// //NewJoint.Scale[1] = tmp[1];
// //NewJoint.Scale[2] = tmp[2];
// //((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp);
// //NewJoint.Translation[0] = tmp[0];
// //NewJoint.Translation[1] = tmp[1];
// //NewJoint.Translation[2] = tmp[2];
//
// for (int i = 0; i < 4; i++) {
// for (int j = 0; j < 4; j++) {
// NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j];
// }
// }
//
// SkeletonStorage.Joints.push_back(NewJoint);
//
// jointIt.next();
// }
//
// m_AllSkeletons.push_back(SkeletonStorage);
//
// return m_AllSkeletons;
//}
std::string attr[9] = { "scaleX", "scaleY", "scaleZ", "translateX", "translateY", "translateZ", "rotateX", "rotateY", "rotateZ" };
Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int endFrame)
{
std::vector<MObject> animatedJoints;
std::vector<MObject> m_Hierarchy;
Animation returnData;
double oneDivSixty = 1 / 60.0;
returnData.Name = animationName;
returnData.Duration = (endFrame - startFrame) * oneDivSixty;
MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint);
while (!jointIt.isDone())
{
m_Hierarchy.push_back(jointIt.item());
MFnDependencyNode depNode(jointIt.item());
for (int i = 0; i < 9; i++)
{
MStatus tmp;
MPlug plug = depNode.findPlug(attr[i].c_str(), &tmp);
MPlugArray connections;
plug.connectedTo(connections, true, false, 0);
for (int j = 0; j != connections.length(); j++) {
MObject connected = connections[j].node();
if (connected.hasFn(MFn::kAnimCurve)) {
MFnAnimCurve jointAnim(connected);
unsigned int startKeyFrameIndex = jointAnim.findClosest(MTime(startFrame, MTime::kNTSCField), &tmp);
if (tmp == MStatus::kFailure)
MGlobal::displayInfo(MString() + "Fail :c");
if (startFrame * oneDivSixty <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame * oneDivSixty) {
animatedJoints.push_back(jointIt.item());
i = 9;
break;
}
unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField));
MGlobal::displayInfo(MString() + startKeyFrameIndex + " " + endKeyFrameIndex);
if (startFrame * oneDivSixty <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame * oneDivSixty || endKeyFrameIndex - startKeyFrameIndex > 0) {
animatedJoints.push_back(jointIt.item());
i = 9;
break;
}
MFnTransform MayaJoint(jointIt.item());
MPlug BindPose = MayaJoint.findPlug("bindPose");
MDataHandle DataHandle;
BindPose.getValue(DataHandle);
MFnMatrixData MartixFn(DataHandle.data());
MMatrix BindPoseMatrix = MartixFn.matrix();
if (BindPoseMatrix != MayaJoint.transformationMatrix())
{
MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya");
}
}
}
}
jointIt.next();
}
int currentFrame = startFrame;
while (currentFrame != endFrame) {
Animation::Keyframe thisKeyFrame;
thisKeyFrame.Index = currentFrame - startFrame;
thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty;
MAnimControl::setCurrentTime(MTime(currentFrame, MTime::kNTSCField));
MTime time = MAnimControl::currentTime();
for (auto aJoint : animatedJoints){
MFnTransform thisJoint(aJoint);
Animation::Keyframe::JointProperty joint;
auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), thisJoint.object());
if (it != m_Hierarchy.end()) {
joint.ID = it - m_Hierarchy.begin();
}
else {
MGlobal::displayError(MString() + "Could not find joint ID for: " + thisJoint.name());
}
MMatrix Matrix = thisJoint.transformationMatrix();
double tmp[4];
thisJoint.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]);
joint.Rotation[0] = tmp[0];
joint.Rotation[1] = tmp[1];
joint.Rotation[2] = tmp[2];
joint.Rotation[3] = tmp[3];
thisJoint.getTranslation(MSpace::kPreTransform).get(tmp);
joint.Position[0] = tmp[0];
joint.Position[1] = tmp[1];
joint.Position[2] = tmp[2];
thisJoint.getScale(tmp);
joint.Scale[0] = tmp[0];
joint.Scale[1] = tmp[1];
joint.Scale[2] = tmp[2];
thisKeyFrame.JointProperties.push_back(joint);
}
returnData.Keyframes.push_back(thisKeyFrame);
currentFrame++;
}
returnData.NumKeyFrames = returnData.Keyframes.size();
returnData.NumberOfJoints = animatedJoints.size();
return returnData;
}
std::vector<BindPoseSkeletonNode> Skeleton::GetBindPoses()
{
std::vector<BindPoseSkeletonNode> m_AllSkeletons;
std::vector<MObject> m_Hierarchy;
MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint);
BindPoseSkeletonNode SkeletonStorage;
while (!jointIt.isDone()) {
MFnTransform MayaJoint(jointIt.currentItem());
BindPoseSkeletonNode::BindPoseJoint NewJoint;
if (MFnDependencyNode(MayaJoint.parent(0)).name() == "world") {
if (SkeletonStorage.Joints.size() != 0) {
m_AllSkeletons.push_back(SkeletonStorage);
SkeletonStorage.Joints.clear();
SkeletonStorage.Name.clear();
}
SkeletonStorage.Name = std::string(MayaJoint.name().asChar());
NewJoint.ParentID = -1; // This joint is root
}
else {
auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), MayaJoint.parent(0));
if (it != m_Hierarchy.end()) {
NewJoint.ParentID = it - m_Hierarchy.begin();
}
else {
MGlobal::displayError(MString() + "Could not find joint parent for: " + MayaJoint.name());
}
}
m_Hierarchy.push_back(MayaJoint.object());
MPlug BindPose = MayaJoint.findPlug("bindPose");
MDataHandle DataHandle;
BindPose.getValue(DataHandle);
MFnMatrixData MartixFn(DataHandle.data());
MMatrix Matrix = MartixFn.matrix();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j];
}
}
NewJoint.Name = MayaJoint.name().asChar();
//double tmp[3];
//((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp);
//NewJoint.Rotation[0] = tmp[0];
//NewJoint.Rotation[1] = tmp[1];
//NewJoint.Rotation[2] = tmp[2];
//((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform);
//NewJoint.Scale[0] = tmp[0];
//NewJoint.Scale[1] = tmp[1];
//NewJoint.Scale[2] = tmp[2];
//((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp);
//NewJoint.Translation[0] = tmp[0];
//NewJoint.Translation[1] = tmp[1];
//NewJoint.Translation[2] = tmp[2];
SkeletonStorage.Joints.push_back(NewJoint);
jointIt.next();
}
m_AllSkeletons.push_back(SkeletonStorage);
return m_AllSkeletons;
}
+119
View File
@@ -0,0 +1,119 @@
#ifndef Skeleton_Skeleton_h__
#define Skeleton_Skeleton_h__
#include <vector>
#include <array>
#include <algorithm>
#include "MayaIncludes.h"
#include "OutputData.h"
class Animation : public OutputData {
public:
struct Keyframe
{
struct JointProperty
{
int ID;
float Position[3];
float Rotation[4];
float Scale[3];
};
int Index;
double Time;
std::vector<JointProperty> JointProperties;
};
std::string Name;
double Duration;
int NumKeyFrames;
int NumberOfJoints;
std::vector<Keyframe> Keyframes;
virtual void WriteBinary(std::ostream& out)
{
out.write(Name.c_str(), Name.size() + 1);
out.write((char*)&Duration, sizeof(double));
out.write((char*)&NumKeyFrames, sizeof(int));
out.write((char*)&NumberOfJoints, sizeof(int));
for (auto aKeyframe : Keyframes) {
out.write((char*)&aKeyframe.Index, sizeof(int));
out.write((char*)&aKeyframe.Time, sizeof(double));
for (auto aJoint : aKeyframe.JointProperties) {
out.write((char*)&aJoint.ID, sizeof(int));
out.write((char*)aJoint.Position, sizeof(float) * 3);
out.write((char*)aJoint.Rotation, sizeof(float) * 4);
out.write((char*)aJoint.Scale, sizeof(float) * 3);
}
}
}
virtual void WriteASCII(std::ostream& out) const
{
out << "Animation Name: " << Name << endl;
out << "Duration: " << Duration << endl;
out << "Number of KeyFrames: " << NumKeyFrames << endl;
out << "Number of Joints: " << NumberOfJoints << endl;
for (auto aKeyframe : Keyframes) {
out << "Frame: " << aKeyframe.Index << endl;
out << "Time: " << aKeyframe.Time << endl;
for (auto aJoint : aKeyframe.JointProperties) {
out << "Joint ID: " << aJoint.ID << endl;
out << aJoint.Position[0] << " " << aJoint.Position[1] << " " << aJoint.Position[2] << endl;
out << aJoint.Rotation[0] << " " << aJoint.Rotation[1] << " " << aJoint.Rotation[2] << " " << aJoint.Rotation[3] << endl;
out << aJoint.Scale[0] << " " << aJoint.Scale[1] << " " << aJoint.Scale[2] << endl;
}
}
}
};
class BindPoseSkeletonNode : public OutputData {
public:
struct BindPoseJoint
{
int ParentID;
std::string Name;
float OffsetMatrix[4][4];
};
std::string Name;
std::vector<BindPoseJoint> Joints;
virtual void WriteBinary(std::ostream& out)
{
out.write(Name.c_str(), Name.size() + 1);
for (auto Joint:Joints)
{
out.write(Joint.Name.c_str(), Joint.Name.size() + 1);
out.write((char*)&Joint.OffsetMatrix, sizeof(float) * 4 * 4);
out.write((char*)&Joint.ParentID, sizeof(int));
}
}
virtual void WriteASCII(std::ostream& out) const
{
out << "Bind Pose: " << Name << endl;
for (auto Joint : Joints)
{
out << Joint.Name << endl;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++){
out << Joint.OffsetMatrix[i][j] << " ";
}
out << endl;
}
out << Joint.ParentID << endl;
}
};
};
class Skeleton {
public:
//std::vector<SkeletonNode> DoIt();
Animation GetAnimData(std::string animationName, int startFrame, int endFrame);
std::vector<BindPoseSkeletonNode> GetBindPoses();
private:
};
#endif //Skeleton_Skeleton_h__
@@ -0,0 +1,38 @@
#include "WriteToFile.h"
WriteToFile::~WriteToFile()
{
CloseFiles();
}
bool WriteToFile::binaryFilePath(string filePathAndFileName)
{
binFileName = filePathAndFileName;
ofstream binFile(filePathAndFileName, ofstream::binary);
if (!binFile)
return false;
return true;
}
bool WriteToFile::ASCIIFilePath(string filePathAndFileName)
{
ASCIIFileName = filePathAndFileName;
ofstream ASCIIFile(filePathAndFileName);
if (!ASCIIFile)
return false;
return true;
}
void WriteToFile::OpenFiles()
{
if (binFile)
binFile.open(binFileName, ofstream::binary);
if (ASCIIFile)
ASCIIFile.open(ASCIIFileName);
}
void WriteToFile::CloseFiles()
{
binFile.close();
ASCIIFile.close();
}
@@ -0,0 +1,63 @@
#ifndef WriteToFile_WriteToFile_h__
#define WriteToFile_WriteToFile_h__
#include "MayaIncludes.h"
#include "OutputData.h"
#include <fstream>
#include <string>
using namespace std;
class WriteToFile
{
public:
~WriteToFile();
bool binaryFilePath(string filePathAndFileName);
bool ASCIIFilePath(string filePathAndFileName);
void writeToFiles(OutputData* toWrite, unsigned int numOfElementToWrite = 1, unsigned int startIndex = 0)
{
MGlobal::displayInfo("WriteToFile::writeToFiles(OutputData*)");
if (ASCIIFile.is_open())
{
for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++)
ASCIIFile << toWrite[i] << endl;
}
if (binFile.is_open())
{
for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++)
toWrite[i].WriteBinary(binFile);
}
}
template <typename T>
void writeToFiles(T* toWrite, unsigned int numOfElementToWrite = 1, unsigned int startIndex = 0)
{
MGlobal::displayInfo("WriteToFile::writeToFiles(T*) - Template T");
if (ASCIIFile.is_open()) {
for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++)
ASCIIFile << toWrite[i] << endl;
}
if (binFile.is_open()) {
for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++)
binFile.write((char*)toWrite, sizeof(T));
}
}
void OpenFiles();
void CloseFiles();
private:
string binFileName;
string ASCIIFileName;
ofstream binFile;
ofstream ASCIIFile;
};
#endif