зеркало из https://github.com/microsoft/cocos2d-x.git
Merge remote-tracking branch 'upstream/develop' into node-string-tag
This commit is contained in:
Коммит
08d0cde490
|
@ -1 +1 @@
|
|||
8b81e323ab3dd59b3a8ced55fa0406d09d6fa1c4
|
||||
50f1022c672a57d837362191d33d09f6bf69986b
|
|
@ -141,7 +141,7 @@ include_directories(
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/cocos/base
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cocos/physics
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cocos/editor-support
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cocos/math/kazmath/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cocos/math/kazmath
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/extensions
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/external
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/external/tinyxml2
|
||||
|
|
|
@ -7,11 +7,6 @@ import os, os.path
|
|||
import shutil
|
||||
from optparse import OptionParser
|
||||
|
||||
CPP_SAMPLES = ['testcpp']
|
||||
LUA_SAMPLES = []
|
||||
JSB_SAMPLES = []
|
||||
ALL_SAMPLES = CPP_SAMPLES + LUA_SAMPLES + JSB_SAMPLES
|
||||
|
||||
def get_num_of_cpu():
|
||||
''' The build process can be accelerated by running multiple concurrent job processes using the -j-option.
|
||||
'''
|
||||
|
@ -72,34 +67,6 @@ def select_toolchain_version():
|
|||
print "Couldn't find the gcc toolchain."
|
||||
exit(1)
|
||||
|
||||
def caculate_built_samples(args):
|
||||
''' Compute the sampels to be built
|
||||
'cpp' for short of all cpp tests
|
||||
'lua' for short of all lua tests
|
||||
'jsb' for short of all javascript tests
|
||||
'''
|
||||
|
||||
if 'all' in args:
|
||||
return ALL_SAMPLES
|
||||
|
||||
targets = []
|
||||
if 'cpp' in args:
|
||||
targets += CPP_SAMPLES
|
||||
args.remove('cpp')
|
||||
if 'lua' in args:
|
||||
targets += LUA_SAMPLES
|
||||
args.remove('lua')
|
||||
if 'jsb' in args:
|
||||
targets += JSB_SAMPLES
|
||||
args.remove('jsb')
|
||||
|
||||
targets += args
|
||||
|
||||
# remove duplicate elements, for example
|
||||
# python android-build.py cpp hellocpp
|
||||
targets = set(targets)
|
||||
return list(targets)
|
||||
|
||||
def do_build(cocos_root, ndk_root, app_android_root, ndk_build_param,sdk_root,android_platform,build_mode):
|
||||
|
||||
ndk_path = os.path.join(ndk_root, "ndk-build")
|
||||
|
@ -157,33 +124,11 @@ def copy_resources(target, app_android_root):
|
|||
if os.path.isdir(resources_dir):
|
||||
copy_files(resources_dir, assets_dir)
|
||||
|
||||
# jsb samples should copy javascript files and resources(shared with cocos2d-html5)
|
||||
if target in JSB_SAMPLES:
|
||||
resources_dir = os.path.join(app_android_root, "../../../cocos/scripting/javascript/script")
|
||||
copy_files(resources_dir, assets_dir)
|
||||
|
||||
if target == "testjavascript":
|
||||
resources_dir = os.path.join(app_android_root, "../tests/")
|
||||
|
||||
copy_files(resources_dir, assets_dir)
|
||||
|
||||
|
||||
# lua samples should copy lua script
|
||||
if target in LUA_SAMPLES:
|
||||
resources_dir = os.path.join(app_android_root, "../../../cocos/scripting/lua/script")
|
||||
copy_files(resources_dir, assets_dir)
|
||||
|
||||
# TestLua shared resources with TestCpp
|
||||
if target == "testlua":
|
||||
resources_dir = os.path.join(app_android_root, "../../test-cpp/Resources")
|
||||
copy_files(resources_dir, assets_dir)
|
||||
|
||||
def build_samples(target,ndk_build_param,android_platform,build_mode):
|
||||
|
||||
ndk_root = check_environment_variables()
|
||||
sdk_root = None
|
||||
select_toolchain_version()
|
||||
build_targets = caculate_built_samples(target)
|
||||
|
||||
current_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
cocos_root = os.path.join(current_dir, "..")
|
||||
|
@ -201,20 +146,10 @@ def build_samples(target,ndk_build_param,android_platform,build_mode):
|
|||
elif build_mode != 'release':
|
||||
build_mode = 'debug'
|
||||
|
||||
app_android_root = ''
|
||||
for target in build_targets:
|
||||
if target == 'testcpp':
|
||||
app_android_root = os.path.join(cocos_root, 'tests/proj.android')
|
||||
elif target == 'testlua':
|
||||
app_android_root = os.path.join(cocos_root, 'tests/test-lua/proj.android')
|
||||
elif target == 'testjavascript':
|
||||
app_android_root = os.path.join(cocos_root, 'tests/test-javascript/proj.android')
|
||||
else:
|
||||
print 'unknown target: %s' % target
|
||||
continue
|
||||
app_android_root = os.path.join(cocos_root, 'tests/proj.android')
|
||||
|
||||
copy_resources(target, app_android_root)
|
||||
do_build(cocos_root, ndk_root, app_android_root, ndk_build_param,sdk_root,android_platform,build_mode)
|
||||
copy_resources(target, app_android_root)
|
||||
do_build(cocos_root, ndk_root, app_android_root, ndk_build_param,sdk_root,android_platform,build_mode)
|
||||
|
||||
# -------------- main --------------
|
||||
if __name__ == '__main__':
|
||||
|
@ -223,26 +158,15 @@ if __name__ == '__main__':
|
|||
usage = """
|
||||
This script is mainy used for building tests built-in with cocos2d-x.
|
||||
|
||||
Usage: %prog [options] target
|
||||
Usage: %prog [options] [testcpp]
|
||||
|
||||
Valid targets are: [testcpp|testlua|testjavascript]. You can combine them arbitrarily with a whitespace among two valid targets.
|
||||
|
||||
You can use [all|cpp|lua|jsb], to build all the tests, or all the c++ tests, or all the Lua tests, or all the JavaScript tests respectevely.
|
||||
|
||||
cpp = ['testcpp']
|
||||
lua = ['testlua']
|
||||
jsb = ['testjavascript']
|
||||
all = cpp + lua + jsb // be careful with the all target, it may took a very long time to compile all the projects, do it under your own risk.
|
||||
|
||||
If you are new to cocos2d-x, I recommend you start with testcpp, testlua or testjavascript.
|
||||
If you are new to cocos2d-x, I recommend you start with testcpp.
|
||||
|
||||
You can combine these targets like this:
|
||||
|
||||
//1. to build simplegame and assetsmanager
|
||||
python android-build.py -p 10 testcpp testlua
|
||||
python android-build.py -p 10
|
||||
|
||||
//2. to build testlua and all the jsb tests
|
||||
python android-build.py -p 19 testlua jsb
|
||||
|
||||
Note: You should install ant to generate apk while building the andriod tests. But it is optional. You can generate apk with eclipse.
|
||||
"""
|
||||
|
@ -256,7 +180,7 @@ if __name__ == '__main__':
|
|||
help='The build mode for java project,debug[default] or release. Get more information,please refer to http://developer.android.com/tools/building/building-cmdline.html')
|
||||
(opts, args) = parser.parse_args()
|
||||
|
||||
if len(args) == 0:
|
||||
if len(args) == 1 and cmp(args[0], 'testcpp') != 0:
|
||||
parser.print_help()
|
||||
else:
|
||||
try:
|
||||
|
|
|
@ -1 +1 @@
|
|||
8fad051dc33d390c01df304fee2a78e22785136f
|
||||
e8eaf27db3b5c75d371db6c73f434cea5c0f970d
|
|
@ -1 +1 @@
|
|||
9da17496043155938cbd8973b01514f220e7192b
|
||||
d70aa2f168a737e7a152028e2156e3099e01c3aa
|
|
@ -142,19 +142,20 @@ renderer/CCRenderMaterial.cpp \
|
|||
../base/CCValue.cpp \
|
||||
../base/etc1.cpp \
|
||||
../base/s3tc.cpp \
|
||||
../math/kazmath/src/aabb.c \
|
||||
../math/kazmath/src/mat3.c \
|
||||
../math/kazmath/src/mat4.c \
|
||||
../math/kazmath/src/neon_matrix_impl.c \
|
||||
../math/kazmath/src/plane.c \
|
||||
../math/kazmath/src/quaternion.c \
|
||||
../math/kazmath/src/ray2.c \
|
||||
../math/kazmath/src/utility.c \
|
||||
../math/kazmath/src/vec2.c \
|
||||
../math/kazmath/src/vec3.c \
|
||||
../math/kazmath/src/vec4.c \
|
||||
../math/kazmath/src/GL/mat4stack.c \
|
||||
../math/kazmath/src/GL/matrix.c \
|
||||
../math/kazmath/kazmath/aabb.c \
|
||||
../math/kazmath/kazmath/mat3.c \
|
||||
../math/kazmath/kazmath/mat4.c \
|
||||
../math/kazmath/kazmath/neon_matrix_impl.c \
|
||||
../math/kazmath/kazmath/plane.c \
|
||||
../math/kazmath/kazmath/quaternion.c \
|
||||
../math/kazmath/kazmath/ray2.c \
|
||||
../math/kazmath/kazmath/ray3.c \
|
||||
../math/kazmath/kazmath/utility.c \
|
||||
../math/kazmath/kazmath/vec2.c \
|
||||
../math/kazmath/kazmath/vec3.c \
|
||||
../math/kazmath/kazmath/vec4.c \
|
||||
../math/kazmath/kazmath/GL/mat4stack.c \
|
||||
../math/kazmath/kazmath/GL/matrix.c \
|
||||
../physics/CCPhysicsBody.cpp \
|
||||
../physics/CCPhysicsContact.cpp \
|
||||
../physics/CCPhysicsJoint.cpp \
|
||||
|
@ -173,7 +174,7 @@ renderer/CCRenderMaterial.cpp \
|
|||
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \
|
||||
$(LOCAL_PATH)/renderer \
|
||||
$(LOCAL_PATH)/../math/kazmath/include \
|
||||
$(LOCAL_PATH)/../math/kazmath \
|
||||
platform/android \
|
||||
$(LOCAL_PATH)/../physics \
|
||||
$(LOCAL_PATH)/../base \
|
||||
|
@ -183,7 +184,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \
|
|||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
|
||||
$(LOCAL_PATH)/renderer \
|
||||
$(LOCAL_PATH)/../math/kazmath/include \
|
||||
$(LOCAL_PATH)/../math/kazmath \
|
||||
$(LOCAL_PATH)/platform/android \
|
||||
$(LOCAL_PATH)/../physics \
|
||||
$(LOCAL_PATH)/../base \
|
||||
|
|
|
@ -88,7 +88,7 @@ extern const char* cocos2dVersion(void);
|
|||
const char *Director::EVENT_PROJECTION_CHANGED = "director_projection_changed";
|
||||
const char *Director::EVENT_AFTER_DRAW = "director_after_draw";
|
||||
const char *Director::EVENT_AFTER_VISIT = "director_after_visit";
|
||||
const char *Director::EVENT_AFTER_UPDATE = "director_after_udpate";
|
||||
const char *Director::EVENT_AFTER_UPDATE = "director_after_update";
|
||||
|
||||
Director* Director::getInstance()
|
||||
{
|
||||
|
|
|
@ -205,8 +205,20 @@ bool DrawNode::init()
|
|||
return true;
|
||||
}
|
||||
|
||||
void DrawNode::render()
|
||||
void DrawNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
|
||||
{
|
||||
_customCommand.init(_globalZOrder);
|
||||
_customCommand.func = CC_CALLBACK_0(DrawNode::onDraw, this, transform, transformUpdated);
|
||||
renderer->addCommand(&_customCommand);
|
||||
}
|
||||
|
||||
void DrawNode::onDraw(const kmMat4 &transform, bool transformUpdated)
|
||||
{
|
||||
getShaderProgram()->use();
|
||||
getShaderProgram()->setUniformsForBuiltins(transform);
|
||||
|
||||
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
|
||||
|
||||
if (_dirty)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
|
@ -220,40 +232,25 @@ void DrawNode::render()
|
|||
else
|
||||
{
|
||||
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
|
||||
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
// vertex
|
||||
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, vertices));
|
||||
|
||||
|
||||
// color
|
||||
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, colors));
|
||||
|
||||
|
||||
// texcood
|
||||
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, texCoords));
|
||||
}
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, _bufferCount);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
|
||||
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_bufferCount);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
}
|
||||
|
||||
void DrawNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
|
||||
{
|
||||
_customCommand.init(_globalZOrder);
|
||||
_customCommand.func = CC_CALLBACK_0(DrawNode::onDraw, this);
|
||||
renderer->addCommand(&_customCommand);
|
||||
}
|
||||
|
||||
void DrawNode::onDraw()
|
||||
{
|
||||
CC_NODE_DRAW_SETUP();
|
||||
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
void DrawNode::drawDot(const Point &pos, float radius, const Color4F &color)
|
||||
{
|
||||
unsigned int vertex_count = 2*3;
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
*/
|
||||
void setBlendFunc(const BlendFunc &blendFunc);
|
||||
|
||||
void onDraw();
|
||||
void onDraw(const kmMat4 &transform, bool transformUpdated);
|
||||
|
||||
// Overrides
|
||||
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
|
||||
|
@ -100,7 +100,6 @@ protected:
|
|||
virtual bool init();
|
||||
|
||||
void ensureCapacity(int count);
|
||||
void render();
|
||||
|
||||
GLuint _vao;
|
||||
GLuint _vbo;
|
||||
|
|
|
@ -102,10 +102,10 @@ static void lazy_init( void )
|
|||
s_shader = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_U_COLOR);
|
||||
s_shader->retain();
|
||||
|
||||
s_colorLocation = glGetUniformLocation( s_shader->getProgram(), "u_color");
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
s_pointSizeLocation = glGetUniformLocation( s_shader->getProgram(), "u_pointSize");
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
s_colorLocation = s_shader->getUniformLocation("u_color");
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
s_pointSizeLocation = s_shader->getUniformLocation("u_pointSize");
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
s_initialized = true;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,11 @@ void EventListenerTouchOneByOne::setSwallowTouches(bool needSwallow)
|
|||
_needSwallow = needSwallow;
|
||||
}
|
||||
|
||||
bool EventListenerTouchOneByOne::isSwallowTouches()
|
||||
{
|
||||
return _needSwallow;
|
||||
}
|
||||
|
||||
EventListenerTouchOneByOne* EventListenerTouchOneByOne::create()
|
||||
{
|
||||
auto ret = new EventListenerTouchOneByOne();
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
virtual ~EventListenerTouchOneByOne();
|
||||
|
||||
void setSwallowTouches(bool needSwallow);
|
||||
bool isSwallowTouches();
|
||||
|
||||
/// Overrides
|
||||
virtual EventListenerTouchOneByOne* clone() override;
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
#include "ccUTF8.h"
|
||||
#include "CCDirector.h"
|
||||
|
||||
#define PAGE_WIDTH 1024
|
||||
#define PAGE_HEIGHT 1024
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
const int FontAtlas::CacheTextureWidth = 1024;
|
||||
const int FontAtlas::CacheTextureHeight = 1024;
|
||||
|
||||
FontAtlas::FontAtlas(Font &theFont) :
|
||||
_font(&theFont),
|
||||
_currentPageData(nullptr)
|
||||
|
@ -44,28 +44,26 @@ _currentPageData(nullptr)
|
|||
{
|
||||
_currentPageLineHeight = _font->getFontMaxHeight();
|
||||
_commonLineHeight = _currentPageLineHeight * 0.8f;
|
||||
Texture2D * tex = new Texture2D;
|
||||
auto texture = new Texture2D;
|
||||
_currentPage = 0;
|
||||
_currentPageOrigX = 0;
|
||||
_currentPageOrigY = 0;
|
||||
_letterPadding = 0;
|
||||
|
||||
_makeDistanceMap = fontTTf->isDistanceFieldEnabled();
|
||||
if(_makeDistanceMap)
|
||||
if(fontTTf->isDistanceFieldEnabled())
|
||||
{
|
||||
_commonLineHeight += 2 * FontFreeType::DistanceMapSpread;
|
||||
_letterPadding += 2 * FontFreeType::DistanceMapSpread;
|
||||
}
|
||||
_currentPageDataSize = (PAGE_WIDTH * PAGE_HEIGHT * 1);
|
||||
_currentPageDataSize = CacheTextureWidth * CacheTextureHeight;
|
||||
if(fontTTf->getOutlineSize() > 0)
|
||||
{
|
||||
_currentPageDataSize *= 2;
|
||||
}
|
||||
|
||||
_currentPageData = new unsigned char[_currentPageDataSize];
|
||||
memset(_currentPageData, 0, _currentPageDataSize);
|
||||
addTexture(*tex,0);
|
||||
tex->release();
|
||||
}
|
||||
else
|
||||
{
|
||||
_makeDistanceMap = false;
|
||||
addTexture(texture,0);
|
||||
texture->release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,29 +110,75 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
|
|||
return false;
|
||||
|
||||
FontFreeType* fontTTf = (FontFreeType*)_font;
|
||||
|
||||
std::unordered_map<unsigned short, FontLetterDefinition> fontDefs;
|
||||
int length = cc_wcslen(utf16String);
|
||||
|
||||
float offsetAdjust = _letterPadding / 2;
|
||||
//find out new letter
|
||||
float offsetAdjust = _letterPadding / 2;
|
||||
int bitmapWidth;
|
||||
int bitmapHeight;
|
||||
Rect tempRect;
|
||||
FontLetterDefinition tempDef;
|
||||
|
||||
auto contentSize = Size(CacheTextureWidth,CacheTextureHeight);
|
||||
auto scaleFactor = CC_CONTENT_SCALE_FACTOR();
|
||||
auto pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8;
|
||||
|
||||
bool existNewLetter = false;
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
auto outIterator = _fontLetterDefinitions.find(utf16String[i]);
|
||||
|
||||
|
||||
if (outIterator == _fontLetterDefinitions.end())
|
||||
{
|
||||
auto outIterator2 = fontDefs.find(utf16String[i]);
|
||||
if(outIterator2 != fontDefs.end())
|
||||
continue;
|
||||
existNewLetter = true;
|
||||
|
||||
Rect tempRect;
|
||||
|
||||
FontLetterDefinition tempDef;
|
||||
|
||||
if (!fontTTf->getBBOXFotChar(utf16String[i], tempRect,tempDef.xAdvance))
|
||||
auto bitmap = fontTTf->getGlyphBitmap(utf16String[i],bitmapWidth,bitmapHeight,tempRect,tempDef.xAdvance);
|
||||
if (bitmap)
|
||||
{
|
||||
tempDef.validDefinition = false;
|
||||
tempDef.validDefinition = true;
|
||||
tempDef.letteCharUTF16 = utf16String[i];
|
||||
tempDef.width = tempRect.size.width + _letterPadding;
|
||||
tempDef.height = tempRect.size.height + _letterPadding;
|
||||
tempDef.offsetX = tempRect.origin.x + offsetAdjust;
|
||||
tempDef.offsetY = _commonLineHeight + tempRect.origin.y - offsetAdjust;
|
||||
|
||||
if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
|
||||
{
|
||||
_currentPageOrigY += _currentPageLineHeight;
|
||||
_currentPageOrigX = 0;
|
||||
if(_currentPageOrigY + _currentPageLineHeight >= CacheTextureHeight)
|
||||
{
|
||||
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
|
||||
_currentPageOrigY = 0;
|
||||
|
||||
delete []_currentPageData;
|
||||
_currentPageData = new unsigned char[_currentPageDataSize];
|
||||
if(_currentPageData == nullptr)
|
||||
return false;
|
||||
memset(_currentPageData, 0, _currentPageDataSize);
|
||||
_currentPage++;
|
||||
auto tex = new Texture2D;
|
||||
addTexture(tex,_currentPage);
|
||||
tex->release();
|
||||
}
|
||||
}
|
||||
fontTTf->renderCharAt(_currentPageData,_currentPageOrigX,_currentPageOrigY,bitmap,bitmapWidth,bitmapHeight);
|
||||
|
||||
tempDef.U = _currentPageOrigX;
|
||||
tempDef.V = _currentPageOrigY;
|
||||
tempDef.textureID = _currentPage;
|
||||
_currentPageOrigX += tempDef.width + 1;
|
||||
// take from pixels to points
|
||||
tempDef.width = tempDef.width / scaleFactor;
|
||||
tempDef.height = tempDef.height / scaleFactor;
|
||||
tempDef.U = tempDef.U / scaleFactor;
|
||||
tempDef.V = tempDef.V / scaleFactor;
|
||||
}
|
||||
else{
|
||||
if(tempDef.xAdvance)
|
||||
tempDef.validDefinition = true;
|
||||
else
|
||||
tempDef.validDefinition = false;
|
||||
|
||||
tempDef.letteCharUTF16 = utf16String[i];
|
||||
tempDef.width = 0;
|
||||
tempDef.height = 0;
|
||||
|
@ -143,84 +187,29 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
|
|||
tempDef.offsetX = 0;
|
||||
tempDef.offsetY = 0;
|
||||
tempDef.textureID = 0;
|
||||
tempDef.xAdvance = 0;
|
||||
_currentPageOrigX += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempDef.validDefinition = true;
|
||||
tempDef.letteCharUTF16 = utf16String[i];
|
||||
tempDef.width = tempRect.size.width + _letterPadding;
|
||||
tempDef.height = tempRect.size.height + _letterPadding;
|
||||
tempDef.offsetX = tempRect.origin.x + offsetAdjust;
|
||||
tempDef.offsetY = _commonLineHeight + tempRect.origin.y - offsetAdjust;
|
||||
}
|
||||
fontDefs[utf16String[i]] = tempDef;
|
||||
|
||||
_fontLetterDefinitions[tempDef.letteCharUTF16] = tempDef;
|
||||
}
|
||||
}
|
||||
|
||||
Size _pageContentSize = Size(PAGE_WIDTH,PAGE_HEIGHT);
|
||||
float scaleFactor = CC_CONTENT_SCALE_FACTOR();
|
||||
float glyphWidth;
|
||||
Texture2D::PixelFormat pixelFormat = Texture2D::PixelFormat::A8;
|
||||
|
||||
|
||||
for(auto it = fontDefs.begin(); it != fontDefs.end(); it++)
|
||||
if(existNewLetter)
|
||||
{
|
||||
if(it->second.validDefinition)
|
||||
{
|
||||
glyphWidth = it->second.width;
|
||||
|
||||
if (_currentPageOrigX + glyphWidth > PAGE_WIDTH)
|
||||
{
|
||||
_currentPageOrigY += _currentPageLineHeight;
|
||||
_currentPageOrigX = 0;
|
||||
if(_currentPageOrigY + _currentPageLineHeight >= PAGE_HEIGHT)
|
||||
{
|
||||
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, PAGE_WIDTH, PAGE_HEIGHT, _pageContentSize );
|
||||
_currentPageOrigY = 0;
|
||||
|
||||
delete []_currentPageData;
|
||||
_currentPageData = new unsigned char[_currentPageDataSize];
|
||||
if(_currentPageData == nullptr)
|
||||
return false;
|
||||
memset(_currentPageData, 0, _currentPageDataSize);
|
||||
_currentPage++;
|
||||
Texture2D* tex = new Texture2D;
|
||||
addTexture(*tex,_currentPage);
|
||||
tex->release();
|
||||
}
|
||||
}
|
||||
fontTTf->renderCharAt(it->second.letteCharUTF16,_currentPageOrigX,_currentPageOrigY,_currentPageData,PAGE_WIDTH);
|
||||
|
||||
it->second.U = _currentPageOrigX;
|
||||
it->second.V = _currentPageOrigY;
|
||||
it->second.textureID = _currentPage;
|
||||
// take from pixels to points
|
||||
it->second.width = it->second.width / scaleFactor;
|
||||
it->second.height = it->second.height / scaleFactor;
|
||||
it->second.U = it->second.U / scaleFactor;
|
||||
it->second.V = it->second.V / scaleFactor;
|
||||
}
|
||||
else
|
||||
glyphWidth = 0;
|
||||
|
||||
_fontLetterDefinitions[it->second.letteCharUTF16] = it->second;
|
||||
_currentPageOrigX += glyphWidth + 1;
|
||||
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
|
||||
}
|
||||
if(fontDefs.size() > 0)
|
||||
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, PAGE_WIDTH, PAGE_HEIGHT, _pageContentSize );
|
||||
return true;
|
||||
}
|
||||
|
||||
void FontAtlas::addTexture(Texture2D &texture, int slot)
|
||||
void FontAtlas::addTexture(Texture2D *texture, int slot)
|
||||
{
|
||||
texture.retain();
|
||||
_atlasTextures[slot] = &texture;
|
||||
texture->retain();
|
||||
_atlasTextures[slot] = texture;
|
||||
}
|
||||
|
||||
Texture2D & FontAtlas::getTexture(int slot)
|
||||
Texture2D* FontAtlas::getTexture(int slot)
|
||||
{
|
||||
return *(_atlasTextures[slot]);
|
||||
return _atlasTextures[slot];
|
||||
}
|
||||
|
||||
float FontAtlas::getCommonLineHeight() const
|
||||
|
|
|
@ -52,6 +52,8 @@ struct FontLetterDefinition
|
|||
class CC_DLL FontAtlas : public Ref
|
||||
{
|
||||
public:
|
||||
static const int CacheTextureWidth;
|
||||
static const int CacheTextureHeight;
|
||||
/**
|
||||
* @js ctor
|
||||
*/
|
||||
|
@ -68,11 +70,11 @@ public:
|
|||
bool prepareLetterDefinitions(unsigned short *utf16String);
|
||||
|
||||
inline const std::unordered_map<int, Texture2D*>& getTextures() const{ return _atlasTextures;}
|
||||
void addTexture(Texture2D &texture, int slot);
|
||||
void addTexture(Texture2D *texture, int slot);
|
||||
float getCommonLineHeight() const;
|
||||
void setCommonLineHeight(float newHeight);
|
||||
|
||||
Texture2D& getTexture(int slot);
|
||||
Texture2D* getTexture(int slot);
|
||||
const Font* getFont() const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -35,17 +35,32 @@ NS_CC_BEGIN
|
|||
|
||||
std::unordered_map<std::string, FontAtlas *> FontAtlasCache::_atlasMap;
|
||||
|
||||
FontAtlas * FontAtlasCache::getFontAtlasTTF(const std::string& fontFileName, int size, GlyphCollection glyphs, const char *customGlyphs, bool useDistanceField)
|
||||
{
|
||||
std::string atlasName = generateFontName(fontFileName, size, glyphs, useDistanceField);
|
||||
FontAtlas * FontAtlasCache::getFontAtlasTTF(const TTFConfig & config)
|
||||
{
|
||||
bool useDistanceField = config.distanceFieldEnabled;
|
||||
if(config.outlineSize > 0)
|
||||
{
|
||||
useDistanceField = false;
|
||||
}
|
||||
int fontSize = config.fontSize;
|
||||
if (useDistanceField)
|
||||
{
|
||||
fontSize = Label::DefultFontSize;
|
||||
}
|
||||
|
||||
std::string atlasName = generateFontName(config.fontFilePath, fontSize, GlyphCollection::DYNAMIC, useDistanceField);
|
||||
atlasName.append("_outline_");
|
||||
std::stringstream ss;
|
||||
ss << config.outlineSize;
|
||||
atlasName.append(ss.str());
|
||||
|
||||
FontAtlas *tempAtlas = _atlasMap[atlasName];
|
||||
|
||||
|
||||
if ( !tempAtlas )
|
||||
{
|
||||
FontFreeType *font = FontFreeType::create(fontFileName, size, glyphs, customGlyphs);
|
||||
FontFreeType *font = FontFreeType::create(config.fontFilePath, fontSize, config.glyphs, config.customGlyphs,useDistanceField,config.outlineSize);
|
||||
if (font)
|
||||
{
|
||||
font->setDistanceFieldEnabled(useDistanceField);
|
||||
tempAtlas = font->createFontAtlas();
|
||||
if (tempAtlas)
|
||||
_atlasMap[atlasName] = tempAtlas;
|
||||
|
|
|
@ -37,7 +37,7 @@ NS_CC_BEGIN
|
|||
class CC_DLL FontAtlasCache
|
||||
{
|
||||
public:
|
||||
static FontAtlas * getFontAtlasTTF(const std::string& fontFileName, int size, GlyphCollection glyphs, const char *customGlyphs = 0, bool useDistanceField = false);
|
||||
static FontAtlas * getFontAtlasTTF(const TTFConfig & config);
|
||||
static FontAtlas * getFontAtlasFNT(const std::string& fontFileName, const Point& imageOffset = Point::ZERO);
|
||||
|
||||
static FontAtlas * getFontAtlasCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
|
||||
|
|
|
@ -158,7 +158,7 @@ FontAtlas * FontCharMap::createFontAtlas()
|
|||
}
|
||||
}
|
||||
|
||||
tempAtlas->addTexture(*_texture,0);
|
||||
tempAtlas->addTexture(_texture,0);
|
||||
|
||||
return tempAtlas;
|
||||
}
|
||||
|
|
|
@ -816,7 +816,7 @@ FontAtlas * FontFNT::createFontAtlas()
|
|||
return 0;
|
||||
|
||||
// add the texture
|
||||
tempAtlas->addTexture(*tempTexture, 0);
|
||||
tempAtlas->addTexture(tempTexture, 0);
|
||||
|
||||
// done
|
||||
return tempAtlas;
|
||||
|
|
|
@ -30,6 +30,7 @@ THE SOFTWARE.
|
|||
#include "CCFontFreeType.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
#include "edtaa3func.h"
|
||||
#include FT_BBOX_H
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -38,9 +39,9 @@ FT_Library FontFreeType::_FTlibrary;
|
|||
bool FontFreeType::_FTInitialized = false;
|
||||
const int FontFreeType::DistanceMapSpread = 3;
|
||||
|
||||
FontFreeType * FontFreeType::create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs)
|
||||
FontFreeType * FontFreeType::create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs,bool distanceFieldEnabled /* = false */,int outline /* = 0 */)
|
||||
{
|
||||
FontFreeType *tempFont = new FontFreeType();
|
||||
FontFreeType *tempFont = new FontFreeType(distanceFieldEnabled,outline);
|
||||
|
||||
if (!tempFont)
|
||||
return nullptr;
|
||||
|
@ -84,10 +85,21 @@ FT_Library FontFreeType::getFTLibrary()
|
|||
return _FTlibrary;
|
||||
}
|
||||
|
||||
FontFreeType::FontFreeType()
|
||||
FontFreeType::FontFreeType(bool distanceFieldEnabled /* = false */,int outline /* = 0 */)
|
||||
: _fontRef(nullptr)
|
||||
,_distanceFieldEnabled(false)
|
||||
,_distanceFieldEnabled(distanceFieldEnabled)
|
||||
,_outlineSize(outline)
|
||||
,_stroker(nullptr)
|
||||
{
|
||||
if (_outlineSize > 0)
|
||||
{
|
||||
FT_Stroker_New(FontFreeType::getFTLibrary(), &_stroker);
|
||||
FT_Stroker_Set(_stroker,
|
||||
(int)(_outlineSize * 64),
|
||||
FT_STROKER_LINECAP_ROUND,
|
||||
FT_STROKER_LINEJOIN_ROUND,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
bool FontFreeType::createFontObject(const std::string &fontName, int fontSize)
|
||||
|
@ -125,6 +137,10 @@ bool FontFreeType::createFontObject(const std::string &fontName, int fontSize)
|
|||
|
||||
FontFreeType::~FontFreeType()
|
||||
{
|
||||
if (_stroker)
|
||||
{
|
||||
FT_Stroker_Done(_stroker);
|
||||
}
|
||||
if (_fontRef)
|
||||
{
|
||||
FT_Done_Face(_fontRef);
|
||||
|
@ -144,41 +160,6 @@ FontAtlas * FontFreeType::createFontAtlas()
|
|||
return atlas;
|
||||
}
|
||||
|
||||
bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect, int &xAdvance) const
|
||||
{
|
||||
if (!_fontRef)
|
||||
return false;
|
||||
|
||||
// get the ID to the char we need
|
||||
int glyph_index = FT_Get_Char_Index(_fontRef, theChar);
|
||||
|
||||
if (!glyph_index)
|
||||
return false;
|
||||
|
||||
// load glyph infos
|
||||
if (_distanceFieldEnabled)
|
||||
{
|
||||
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// store result in the passed rectangle
|
||||
outRect.origin.x = _fontRef->glyph->metrics.horiBearingX >> 6;
|
||||
outRect.origin.y = - (_fontRef->glyph->metrics.horiBearingY >> 6);
|
||||
outRect.size.width = (_fontRef->glyph->metrics.width >> 6);
|
||||
outRect.size.height = (_fontRef->glyph->metrics.height >> 6);
|
||||
|
||||
xAdvance = (static_cast<int>(_fontRef->glyph->metrics.horiAdvance >> 6));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int * FontFreeType::getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const
|
||||
{
|
||||
if (!text)
|
||||
|
@ -239,27 +220,162 @@ int FontFreeType::getFontMaxHeight() const
|
|||
return (static_cast<int>(_fontRef->size->metrics.height >> 6));
|
||||
}
|
||||
|
||||
unsigned char * FontFreeType::getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight) const
|
||||
unsigned char* FontFreeType::getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight, Rect &outRect,int &xAdvance)
|
||||
{
|
||||
if (!_fontRef)
|
||||
return 0;
|
||||
|
||||
if (_distanceFieldEnabled)
|
||||
bool invalidChar = true;
|
||||
unsigned char * ret = nullptr;
|
||||
|
||||
do
|
||||
{
|
||||
if (FT_Load_Char(_fontRef,theChar,FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
|
||||
return 0;
|
||||
if (!_fontRef)
|
||||
break;
|
||||
|
||||
auto glyphIndex = FT_Get_Char_Index(_fontRef, theChar);
|
||||
if(!glyphIndex)
|
||||
break;
|
||||
|
||||
if (_distanceFieldEnabled)
|
||||
{
|
||||
if (FT_Load_Glyph(_fontRef,glyphIndex,FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FT_Load_Glyph(_fontRef,glyphIndex,FT_LOAD_RENDER))
|
||||
break;
|
||||
}
|
||||
|
||||
outRect.origin.x = _fontRef->glyph->metrics.horiBearingX >> 6;
|
||||
outRect.origin.y = - (_fontRef->glyph->metrics.horiBearingY >> 6);
|
||||
outRect.size.width = (_fontRef->glyph->metrics.width >> 6);
|
||||
outRect.size.height = (_fontRef->glyph->metrics.height >> 6);
|
||||
|
||||
xAdvance = (static_cast<int>(_fontRef->glyph->metrics.horiAdvance >> 6));
|
||||
|
||||
outWidth = _fontRef->glyph->bitmap.width;
|
||||
outHeight = _fontRef->glyph->bitmap.rows;
|
||||
ret = _fontRef->glyph->bitmap.buffer;
|
||||
|
||||
if (_outlineSize > 0)
|
||||
{
|
||||
auto copyBitmap = new unsigned char[outWidth * outHeight];
|
||||
memcpy(copyBitmap,ret,outWidth * outHeight * sizeof(unsigned char));
|
||||
|
||||
int bitmapWidth;
|
||||
int bitmapHeight;
|
||||
FT_BBox bbox;
|
||||
auto outlineBitmap = getGlyphBitmapWithOutline(theChar,bbox);
|
||||
if(outlineBitmap == nullptr)
|
||||
{
|
||||
ret = nullptr;
|
||||
delete [] copyBitmap;
|
||||
break;
|
||||
}
|
||||
|
||||
bitmapWidth = (bbox.xMax - bbox.xMin)>>6;
|
||||
bitmapHeight = (bbox.yMax - bbox.yMin)>>6;
|
||||
|
||||
int index;
|
||||
auto blendImage = new unsigned char[bitmapWidth * bitmapHeight * 2];
|
||||
memset(blendImage, 0, bitmapWidth * bitmapHeight * 2);
|
||||
for (int x = 0; x < bitmapWidth; ++x)
|
||||
{
|
||||
for (int y = 0; y < bitmapHeight; ++y)
|
||||
{
|
||||
index = x + ( y * bitmapWidth );
|
||||
blendImage[2 * index] = outlineBitmap[index];
|
||||
}
|
||||
}
|
||||
|
||||
int maxX = outWidth + _outlineSize;
|
||||
int maxY = outHeight + _outlineSize;
|
||||
for (int x = _outlineSize; x < maxX; ++x)
|
||||
{
|
||||
for (int y = _outlineSize; y < maxY; ++y)
|
||||
{
|
||||
index = x + ( y * bitmapWidth );
|
||||
|
||||
blendImage[2 * index + 1] = copyBitmap[outWidth * (y - _outlineSize) + x - _outlineSize];
|
||||
}
|
||||
}
|
||||
|
||||
outRect.origin.x = bbox.xMin >> 6;
|
||||
outRect.origin.y = - (bbox.yMax >> 6);
|
||||
|
||||
xAdvance += bitmapWidth - outRect.size.width;
|
||||
|
||||
outRect.size.width = bitmapWidth;
|
||||
outRect.size.height = bitmapHeight;
|
||||
outWidth = bitmapWidth;
|
||||
outHeight = bitmapHeight;
|
||||
|
||||
delete [] outlineBitmap;
|
||||
delete [] copyBitmap;
|
||||
ret = blendImage;
|
||||
}
|
||||
|
||||
invalidChar = false;
|
||||
} while (0);
|
||||
|
||||
if (invalidChar)
|
||||
{
|
||||
outRect.size.width = 0;
|
||||
outRect.size.height = 0;
|
||||
xAdvance = 0;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FT_Load_Char(_fontRef,theChar,FT_LOAD_RENDER))
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
outWidth = _fontRef->glyph->bitmap.width;
|
||||
outHeight = _fontRef->glyph->bitmap.rows;
|
||||
|
||||
// return the pointer to the bitmap
|
||||
return _fontRef->glyph->bitmap.buffer;
|
||||
}
|
||||
|
||||
unsigned char * FontFreeType::getGlyphBitmapWithOutline(unsigned short theChar, FT_BBox &bbox)
|
||||
{
|
||||
unsigned char* ret = nullptr;
|
||||
|
||||
FT_UInt gindex = FT_Get_Char_Index(_fontRef, theChar);
|
||||
if (FT_Load_Glyph(_fontRef, gindex, FT_LOAD_NO_BITMAP) == 0)
|
||||
{
|
||||
if (_fontRef->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
|
||||
{
|
||||
FT_Glyph glyph;
|
||||
if (FT_Get_Glyph(_fontRef->glyph, &glyph) == 0)
|
||||
{
|
||||
FT_Glyph_StrokeBorder(&glyph, _stroker, 0, 1);
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
|
||||
{
|
||||
FT_Outline *outline = &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;
|
||||
FT_Glyph_Get_CBox(glyph,FT_GLYPH_BBOX_GRIDFIT,&bbox);
|
||||
int width = (bbox.xMax - bbox.xMin)>>6;
|
||||
int rows = (bbox.yMax - bbox.yMin)>>6;
|
||||
|
||||
FT_Bitmap bmp;
|
||||
bmp.buffer = new unsigned char[width * rows];
|
||||
memset(bmp.buffer, 0, width * rows);
|
||||
bmp.width = width;
|
||||
bmp.rows = rows;
|
||||
bmp.pitch = width;
|
||||
bmp.pixel_mode = FT_PIXEL_MODE_GRAY;
|
||||
bmp.num_grays = 256;
|
||||
|
||||
FT_Raster_Params params;
|
||||
memset(¶ms, 0, sizeof (params));
|
||||
params.source = outline;
|
||||
params.target = &bmp;
|
||||
params.flags = FT_RASTER_FLAG_AA;
|
||||
FT_Outline_Translate(outline,-bbox.xMin,-bbox.yMin);
|
||||
FT_Outline_Render(_FTlibrary, outline, ¶ms);
|
||||
|
||||
ret = bmp.buffer;
|
||||
}
|
||||
FT_Done_Glyph(glyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned char * makeDistanceMap( unsigned char *img, unsigned int width, unsigned int height)
|
||||
|
@ -343,47 +459,33 @@ unsigned char * makeDistanceMap( unsigned char *img, unsigned int width, unsigne
|
|||
return out;
|
||||
}
|
||||
|
||||
void FontFreeType::setDistanceFieldEnabled(bool distanceFieldEnabled)
|
||||
void FontFreeType::renderCharAt(unsigned char *dest,int posX, int posY, unsigned char* bitmap,int bitmapWidth,int bitmapHeight)
|
||||
{
|
||||
_distanceFieldEnabled = distanceFieldEnabled;
|
||||
}
|
||||
|
||||
bool FontFreeType::renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize)
|
||||
{
|
||||
unsigned char *sourceBitmap = 0;
|
||||
int sourceWidth = 0;
|
||||
int sourceHeight = 0;
|
||||
|
||||
sourceBitmap = getGlyphBitmap(charToRender, sourceWidth, sourceHeight);
|
||||
|
||||
if (!sourceBitmap)
|
||||
return false;
|
||||
int iX = posX;
|
||||
int iY = posY;
|
||||
|
||||
if (_distanceFieldEnabled)
|
||||
{
|
||||
unsigned char * out = makeDistanceMap(sourceBitmap,sourceWidth,sourceHeight);
|
||||
auto distanceMap = makeDistanceMap(bitmap,bitmapWidth,bitmapHeight);
|
||||
|
||||
int iX = posX;
|
||||
int iY = posY;
|
||||
bitmapWidth += 2 * DistanceMapSpread;
|
||||
bitmapHeight += 2 * DistanceMapSpread;
|
||||
|
||||
sourceWidth += 2 * DistanceMapSpread;
|
||||
sourceHeight += 2 * DistanceMapSpread;
|
||||
|
||||
for (int y = 0; y < sourceHeight; ++y)
|
||||
for (int y = 0; y < bitmapHeight; ++y)
|
||||
{
|
||||
int bitmap_y = y * sourceWidth;
|
||||
int bitmap_y = y * bitmapWidth;
|
||||
|
||||
for (int x = 0; x < sourceWidth; ++x)
|
||||
for (int x = 0; x < bitmapWidth; ++x)
|
||||
{
|
||||
/* Dual channel 16-bit output (more complicated, but good precision and range) */
|
||||
/*int index = (iX + ( iY * destSize )) * 3;
|
||||
int index2 = (bitmap_y + x)*3;
|
||||
destMemory[index] = out[index2];
|
||||
destMemory[index + 1] = out[index2 + 1];
|
||||
destMemory[index + 2] = out[index2 + 2];*/
|
||||
dest[index] = out[index2];
|
||||
dest[index + 1] = out[index2 + 1];
|
||||
dest[index + 2] = out[index2 + 2];*/
|
||||
|
||||
//Single channel 8-bit output
|
||||
destMemory[iX + ( iY * destSize )] = out[bitmap_y + x];
|
||||
dest[iX + ( iY * FontAtlas::CacheTextureWidth )] = distanceMap[bitmap_y + x];
|
||||
|
||||
iX += 1;
|
||||
}
|
||||
|
@ -391,33 +493,50 @@ bool FontFreeType::renderCharAt(unsigned short int charToRender, int posX, int p
|
|||
iX = posX;
|
||||
iY += 1;
|
||||
}
|
||||
free(out);
|
||||
return true;
|
||||
free(distanceMap);
|
||||
}
|
||||
|
||||
int iX = posX;
|
||||
int iY = posY;
|
||||
|
||||
for (int y = 0; y < sourceHeight; ++y)
|
||||
else if(_outlineSize > 0)
|
||||
{
|
||||
int bitmap_y = y * sourceWidth;
|
||||
|
||||
for (int x = 0; x < sourceWidth; ++x)
|
||||
unsigned char tempChar;
|
||||
for (int y = 0; y < bitmapHeight; ++y)
|
||||
{
|
||||
unsigned char cTemp = sourceBitmap[bitmap_y + x];
|
||||
int bitmap_y = y * bitmapWidth;
|
||||
|
||||
// the final pixel
|
||||
destMemory[(iX + ( iY * destSize ) )] = cTemp;
|
||||
for (int x = 0; x < bitmapWidth; ++x)
|
||||
{
|
||||
tempChar = bitmap[(bitmap_y + x) * 2];
|
||||
dest[(iX + ( iY * FontAtlas::CacheTextureWidth ) ) * 2] = tempChar;
|
||||
tempChar = bitmap[(bitmap_y + x) * 2 + 1];
|
||||
dest[(iX + ( iY * FontAtlas::CacheTextureWidth ) ) * 2 + 1] = tempChar;
|
||||
|
||||
iX += 1;
|
||||
iX += 1;
|
||||
}
|
||||
|
||||
iX = posX;
|
||||
iY += 1;
|
||||
}
|
||||
|
||||
iX = posX;
|
||||
iY += 1;
|
||||
delete [] bitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int y = 0; y < bitmapHeight; ++y)
|
||||
{
|
||||
int bitmap_y = y * bitmapWidth;
|
||||
|
||||
//everything good
|
||||
return true;
|
||||
for (int x = 0; x < bitmapWidth; ++x)
|
||||
{
|
||||
unsigned char cTemp = bitmap[bitmap_y + x];
|
||||
|
||||
// the final pixel
|
||||
dest[(iX + ( iY * FontAtlas::CacheTextureWidth ) )] = cTemp;
|
||||
|
||||
iX += 1;
|
||||
}
|
||||
|
||||
iX = posX;
|
||||
iY += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_CC_END
|
|
@ -33,6 +33,7 @@
|
|||
#include <ft2build.h>
|
||||
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_STROKER_H
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -41,25 +42,24 @@ class CC_DLL FontFreeType : public Font
|
|||
public:
|
||||
static const int DistanceMapSpread;
|
||||
|
||||
static FontFreeType * create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs);
|
||||
static FontFreeType * create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs,bool distanceFieldEnabled = false,int outline = 0);
|
||||
|
||||
static void shutdownFreeType();
|
||||
|
||||
void setDistanceFieldEnabled(bool distanceFieldEnabled);
|
||||
bool isDistanceFieldEnabled() const { return _distanceFieldEnabled;}
|
||||
bool renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize);
|
||||
int getOutlineSize() const { return _outlineSize; }
|
||||
void renderCharAt(unsigned char *dest,int posX, int posY, unsigned char* bitmap,int bitmapWidth,int bitmapHeight);
|
||||
|
||||
virtual FontAtlas * createFontAtlas() override;
|
||||
virtual int * getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const override;
|
||||
|
||||
unsigned char * getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight) const override;
|
||||
virtual int getFontMaxHeight() const override;
|
||||
unsigned char * getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight, Rect &outRect,int &xAdvance);
|
||||
|
||||
bool getBBOXFotChar(unsigned short theChar, Rect &outRect,int &xAdvance) const;
|
||||
virtual int getFontMaxHeight() const override;
|
||||
|
||||
protected:
|
||||
|
||||
FontFreeType();
|
||||
FontFreeType(bool distanceFieldEnabled = false,int outline = 0);
|
||||
virtual ~FontFreeType();
|
||||
bool createFontObject(const std::string &fontName, int fontSize);
|
||||
|
||||
|
@ -69,13 +69,16 @@ private:
|
|||
FT_Library getFTLibrary();
|
||||
|
||||
int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const;
|
||||
unsigned char * getGlyphBitmapWithOutline(unsigned short theChar, FT_BBox &bbox);
|
||||
|
||||
static FT_Library _FTlibrary;
|
||||
static bool _FTInitialized;
|
||||
FT_Face _fontRef;
|
||||
FT_Stroker _stroker;
|
||||
std::string _fontName;
|
||||
Data _ttfData;
|
||||
bool _distanceFieldEnabled;
|
||||
int _outlineSize;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -59,8 +59,7 @@ const char* GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR = "ShaderPositi
|
|||
|
||||
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL = "ShaderLabelNormol";
|
||||
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW = "ShaderLabelGlow";
|
||||
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE = "ShaderLabelOutline";
|
||||
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW = "ShaderLabelShadow";
|
||||
const char* GLProgram::SHADER_NAME_LABEL_OUTLINE = "ShaderLabelOutline";
|
||||
|
||||
|
||||
// uniform names
|
||||
|
@ -113,7 +112,7 @@ GLProgram::~GLProgram()
|
|||
}
|
||||
}
|
||||
|
||||
bool GLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
|
||||
bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
|
||||
{
|
||||
_program = glCreateProgram();
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
@ -154,12 +153,13 @@ bool GLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, co
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GLProgram::initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename)
|
||||
bool GLProgram::initWithFilenames(const std::string &vShaderFilename, const std::string &fShaderFilename)
|
||||
{
|
||||
std::string vertexSource = FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(vShaderFilename).c_str());
|
||||
std::string fragmentSource = FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(fShaderFilename).c_str());
|
||||
auto fileUtils = FileUtils::getInstance();
|
||||
std::string vertexSource = fileUtils->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(vShaderFilename));
|
||||
std::string fragmentSource = fileUtils->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(fShaderFilename));
|
||||
|
||||
return initWithVertexShaderByteArray(vertexSource.c_str(), fragmentSource.c_str());
|
||||
return initWithByteArrays(vertexSource.c_str(), fragmentSource.c_str());
|
||||
}
|
||||
|
||||
std::string GLProgram::getDescription() const
|
||||
|
@ -224,7 +224,17 @@ bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source
|
|||
return (status == GL_TRUE);
|
||||
}
|
||||
|
||||
void GLProgram::addAttribute(const char* attributeName, GLuint index)
|
||||
GLint GLProgram::getAttribLocation(const char* attributeName) const
|
||||
{
|
||||
return glGetAttribLocation(_program, attributeName);
|
||||
}
|
||||
|
||||
GLint GLProgram::getUniformLocation(const char* attributeName) const
|
||||
{
|
||||
return glGetUniformLocation(_program, attributeName);
|
||||
}
|
||||
|
||||
void GLProgram::bindAttribLocation(const char* attributeName, GLuint index) const
|
||||
{
|
||||
glBindAttribLocation(_program, index, attributeName);
|
||||
}
|
||||
|
|
|
@ -92,8 +92,7 @@ public:
|
|||
|
||||
static const char* SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL;
|
||||
static const char* SHADER_NAME_LABEL_DISTANCEFIELD_GLOW;
|
||||
static const char* SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE;
|
||||
static const char* SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW;
|
||||
static const char* SHADER_NAME_LABEL_OUTLINE;
|
||||
|
||||
// uniform names
|
||||
static const char* UNIFORM_NAME_P_MATRIX;
|
||||
|
@ -123,14 +122,22 @@ public:
|
|||
* @js initWithString
|
||||
* @lua initWithString
|
||||
*/
|
||||
bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray);
|
||||
bool initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray);
|
||||
/** Initializes the GLProgram with a vertex and fragment with contents of filenames
|
||||
* @js init
|
||||
* @lua init
|
||||
*/
|
||||
bool initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename);
|
||||
/** It will add a new attribute to the shader */
|
||||
void addAttribute(const char* attributeName, GLuint index);
|
||||
bool initWithFilenames(const std::string& vShaderFilename, const std::string& fShaderFilename);
|
||||
|
||||
/** It will add a new attribute to the shader by calling glBindAttribLocation */
|
||||
void bindAttribLocation(const char* attributeName, GLuint index) const;
|
||||
|
||||
/** calls glGetAttribLocation */
|
||||
GLint getAttribLocation(const char* attributeName) const;
|
||||
|
||||
/** calls glGetUniformLocation() */
|
||||
GLint getUniformLocation(const char* attributeName) const;
|
||||
|
||||
/** links the glProgram */
|
||||
bool link();
|
||||
/** it will call glUseProgram() */
|
||||
|
@ -235,6 +242,13 @@ public:
|
|||
|
||||
inline const GLuint getProgram() const { return _program; }
|
||||
|
||||
// DEPRECATED
|
||||
CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
|
||||
{ return initWithByteArrays(vShaderByteArray, fShaderByteArray); }
|
||||
CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderFilename(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
|
||||
{ return initWithFilenames(vShaderByteArray, fShaderByteArray); }
|
||||
CC_DEPRECATED_ATTRIBUTE void addAttribute(const char* attributeName, GLuint index) const { return bindAttribLocation(attributeName, index); }
|
||||
|
||||
private:
|
||||
bool updateUniformLocation(GLint location, const GLvoid* data, unsigned int bytes);
|
||||
virtual std::string getDescription() const;
|
||||
|
|
|
@ -34,10 +34,10 @@
|
|||
#include "renderer/CCRenderer.h"
|
||||
#include "CCFont.h"
|
||||
|
||||
#define DISTANCEFIELD_ATLAS_FONTSIZE 50
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
const int Label::DefultFontSize = 50;
|
||||
|
||||
Label* Label::create()
|
||||
{
|
||||
Label *ret = new Label();
|
||||
|
@ -56,11 +56,9 @@ Label* Label::createWithTTF(const TTFConfig& ttfConfig, const std::string& text,
|
|||
|
||||
if (!ret)
|
||||
return nullptr;
|
||||
|
||||
|
||||
if (ret->setTTFConfig(ttfConfig))
|
||||
{
|
||||
if(ttfConfig.distanceFieldEnabled)
|
||||
ret->setFontScale(1.0f * ttfConfig.fontSize / DISTANCEFIELD_ATLAS_FONTSIZE);
|
||||
ret->setMaxLineWidth(lineSize);
|
||||
ret->setString(text);
|
||||
ret->autorelease();
|
||||
|
@ -203,6 +201,7 @@ Label::Label(FontAtlas *atlas, TextHAlignment alignment, bool useDistanceField,b
|
|||
, _fontScale(1.0f)
|
||||
, _uniformEffectColor(0)
|
||||
,_currNumLines(-1)
|
||||
,_fontConfig(TTFConfig(""))
|
||||
{
|
||||
_cascadeColorEnabled = true;
|
||||
_batchNodes.push_back(this);
|
||||
|
@ -213,7 +212,7 @@ Label::~Label()
|
|||
delete [] _currentUTF16String;
|
||||
delete [] _originalUTF16String;
|
||||
delete [] _horizontalKernings;
|
||||
|
||||
|
||||
if (_fontAtlas)
|
||||
FontAtlasCache::releaseFontAtlas(_fontAtlas);
|
||||
|
||||
|
@ -225,25 +224,49 @@ bool Label::init()
|
|||
bool ret = true;
|
||||
if(_fontAtlas)
|
||||
{
|
||||
ret = SpriteBatchNode::initWithTexture(_fontAtlas->getTexture(0), 30);
|
||||
if (_reusedLetter == nullptr)
|
||||
{
|
||||
_reusedLetter = Sprite::createWithTexture(&_fontAtlas->getTexture(0));
|
||||
_reusedLetter = Sprite::createWithTexture(_fontAtlas->getTexture(0));
|
||||
_reusedLetter->setOpacityModifyRGB(_isOpacityModifyRGB);
|
||||
_reusedLetter->retain();
|
||||
_reusedLetter->setAnchorPoint(Point::ANCHOR_TOP_LEFT);
|
||||
_reusedLetter->setBatchNode(this);
|
||||
}
|
||||
ret = SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), 30);
|
||||
}
|
||||
if (_useDistanceField)
|
||||
setLabelEffect(LabelEffect::NORMAL,Color3B::BLACK);
|
||||
else if(_useA8Shader)
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_A8_COLOR));
|
||||
else
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
|
||||
_currLabelEffect = LabelEffect::NORMAL;
|
||||
initProgram();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Label::initProgram()
|
||||
{
|
||||
switch (_currLabelEffect)
|
||||
{
|
||||
case cocos2d::LabelEffect::NORMAL:
|
||||
case cocos2d::LabelEffect::SHADOW:
|
||||
if (_useDistanceField)
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL));
|
||||
else if (_useA8Shader)
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_A8_COLOR));
|
||||
else
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
|
||||
|
||||
break;
|
||||
case cocos2d::LabelEffect::OUTLINE:
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_OUTLINE));
|
||||
break;
|
||||
case cocos2d::LabelEffect::GLOW:
|
||||
if (_useDistanceField)
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
_uniformEffectColor = glGetUniformLocation(_shaderProgram->getProgram(), "v_effectColor");
|
||||
}
|
||||
|
||||
bool Label::initWithFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled /* = false */, bool useA8Shader /* = false */)
|
||||
{
|
||||
FontAtlas *oldAtlas = _fontAtlas;
|
||||
|
@ -287,16 +310,32 @@ bool Label::initWithFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled /* = fa
|
|||
|
||||
bool Label::setTTFConfig(const TTFConfig& ttfConfig)
|
||||
{
|
||||
FontAtlas *newAtlas = nullptr;
|
||||
if(ttfConfig.distanceFieldEnabled)
|
||||
newAtlas = FontAtlasCache::getFontAtlasTTF(ttfConfig.fontFilePath, DISTANCEFIELD_ATLAS_FONTSIZE, ttfConfig.glyphs, ttfConfig.customGlyphs,true);
|
||||
else
|
||||
newAtlas = FontAtlasCache::getFontAtlasTTF(ttfConfig.fontFilePath, ttfConfig.fontSize, ttfConfig.glyphs, ttfConfig.customGlyphs,false);
|
||||
FontAtlas *newAtlas = FontAtlasCache::getFontAtlasTTF(ttfConfig);
|
||||
|
||||
if (!newAtlas)
|
||||
return false;
|
||||
|
||||
return initWithFontAtlas(newAtlas,ttfConfig.distanceFieldEnabled,true);
|
||||
if (initWithFontAtlas(newAtlas,ttfConfig.distanceFieldEnabled,true))
|
||||
{
|
||||
_fontConfig = ttfConfig;
|
||||
if (ttfConfig.outlineSize > 0)
|
||||
{
|
||||
_fontConfig.distanceFieldEnabled = false;
|
||||
_useDistanceField = false;
|
||||
_useA8Shader = false;
|
||||
_currLabelEffect = LabelEffect::OUTLINE;
|
||||
initProgram();
|
||||
}
|
||||
else if(ttfConfig.distanceFieldEnabled)
|
||||
{
|
||||
this->setFontScale(1.0f * ttfConfig.fontSize / DefultFontSize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Label::setBMFontFilePath(const std::string& bmfontFilePath, const Point& imageOffset /* = Point::ZERO */)
|
||||
|
@ -313,14 +352,14 @@ void Label::setString(const std::string& text)
|
|||
{
|
||||
if (!_fontAtlas || _commonLineHeight <= 0)
|
||||
return ;
|
||||
|
||||
|
||||
unsigned short* utf16String = cc_utf8_to_utf16(text.c_str());
|
||||
if(!utf16String)
|
||||
return ;
|
||||
_originalUTF8String = text;
|
||||
setCurrentString(utf16String);
|
||||
setOriginalString(utf16String);
|
||||
|
||||
|
||||
// align text
|
||||
alignText();
|
||||
}
|
||||
|
@ -332,7 +371,7 @@ void Label::setAlignment(TextHAlignment alignment)
|
|||
{
|
||||
// store
|
||||
_alignment = alignment;
|
||||
|
||||
|
||||
if (_currentUTF16String)
|
||||
{
|
||||
// reset the string
|
||||
|
@ -350,7 +389,7 @@ void Label::setMaxLineWidth(float width)
|
|||
{
|
||||
// store
|
||||
_maxLineWidth = width;
|
||||
|
||||
|
||||
if (_currentUTF16String)
|
||||
{
|
||||
// reset the string
|
||||
|
@ -368,7 +407,7 @@ void Label::setLineBreakWithoutSpace(bool breakWithoutSpace)
|
|||
{
|
||||
// store
|
||||
_lineBreakWithoutSpaces = breakWithoutSpace;
|
||||
|
||||
|
||||
// need to align text again
|
||||
if(_currentUTF16String)
|
||||
{
|
||||
|
@ -456,10 +495,10 @@ void Label::alignText()
|
|||
LabelTextFormatter::createStringSprites(this);
|
||||
if(_maxLineWidth > 0 && _contentSize.width > _maxLineWidth && LabelTextFormatter::multilineText(this) )
|
||||
LabelTextFormatter::createStringSprites(this);
|
||||
|
||||
|
||||
if(_currNumLines > 1 && _alignment != TextHAlignment::LEFT)
|
||||
LabelTextFormatter::alignText(this);
|
||||
|
||||
|
||||
int strLen = cc_wcslen(_currentUTF16String);
|
||||
Rect uvRect;
|
||||
Sprite* letterSprite;
|
||||
|
@ -484,7 +523,7 @@ void Label::alignText()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int index;
|
||||
for (int ctr = 0; ctr < strLen; ++ctr)
|
||||
{
|
||||
|
@ -507,10 +546,10 @@ bool Label::computeHorizontalKernings(unsigned short int *stringToRender)
|
|||
delete [] _horizontalKernings;
|
||||
_horizontalKernings = 0;
|
||||
}
|
||||
|
||||
|
||||
int letterCount = 0;
|
||||
_horizontalKernings = _fontAtlas->getFont()->getHorizontalKerningForTextUTF16(stringToRender, letterCount);
|
||||
|
||||
|
||||
if(!_horizontalKernings)
|
||||
return false;
|
||||
else
|
||||
|
@ -523,13 +562,13 @@ bool Label::setOriginalString(unsigned short *stringToSet)
|
|||
{
|
||||
delete [] _originalUTF16String;
|
||||
}
|
||||
|
||||
|
||||
int newStringLenght = cc_wcslen(stringToSet);
|
||||
_originalUTF16String = new unsigned short int [newStringLenght + 1];
|
||||
memset(_originalUTF16String, 0, (newStringLenght + 1) * 2);
|
||||
memcpy(_originalUTF16String, stringToSet, (newStringLenght * 2));
|
||||
_originalUTF16String[newStringLenght] = 0;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -540,7 +579,7 @@ bool Label::setCurrentString(unsigned short *stringToSet)
|
|||
{
|
||||
delete [] _currentUTF16String;
|
||||
}
|
||||
|
||||
|
||||
_currentUTF16String = stringToSet;
|
||||
computeStringNumLines();
|
||||
// compute the advances
|
||||
|
@ -551,19 +590,19 @@ void Label::resetCurrentString()
|
|||
{
|
||||
if ((!_currentUTF16String) && (!_originalUTF16String))
|
||||
return;
|
||||
|
||||
|
||||
// set the new string
|
||||
if (_currentUTF16String)
|
||||
{
|
||||
delete [] _currentUTF16String;
|
||||
_currentUTF16String = 0;
|
||||
}
|
||||
|
||||
|
||||
int stringLenght = cc_wcslen(_originalUTF16String);
|
||||
_currentUTF16String = new unsigned short int [stringLenght + 1];
|
||||
memcpy(_currentUTF16String, _originalUTF16String, stringLenght * 2);
|
||||
_currentUTF16String[stringLenght] = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Label::updateSpriteWithLetterDefinition(const FontLetterDefinition &theDefinition, Texture2D *theTexture)
|
||||
|
@ -603,7 +642,7 @@ bool Label::recordPlaceholderInfo(int spriteIndex)
|
|||
}
|
||||
|
||||
_lettersInfo[spriteIndex].def.validDefinition = false;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -614,31 +653,68 @@ void Label::addChild(Node * child, int zOrder/* =0 */, int tag/* =0 */)
|
|||
|
||||
void Label::setLabelEffect(LabelEffect effect,const Color3B& effectColor)
|
||||
{
|
||||
if(_useDistanceField == false)
|
||||
return;
|
||||
|
||||
_currLabelEffect = effect;
|
||||
_effectColor = effectColor;
|
||||
|
||||
switch (_currLabelEffect)
|
||||
switch (effect)
|
||||
{
|
||||
case cocos2d::LabelEffect::NORMAL:
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL));
|
||||
case cocos2d::LabelEffect::NORMAL:
|
||||
disableEffect();
|
||||
break;
|
||||
case cocos2d::LabelEffect::OUTLINE:
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE));
|
||||
enableOutline(Color4B(effectColor));
|
||||
break;
|
||||
case cocos2d::LabelEffect::SHADOW:
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW));
|
||||
enableShadow(effectColor);
|
||||
break;
|
||||
case cocos2d::LabelEffect::GLOW:
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW));
|
||||
enableGlow(effectColor);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_uniformEffectColor = glGetUniformLocation(_shaderProgram->getProgram(), "v_effectColor");
|
||||
void Label::enableGlow(const Color3B& glowColor)
|
||||
{
|
||||
if(_useDistanceField == false)
|
||||
return;
|
||||
_currLabelEffect = LabelEffect::GLOW;
|
||||
_effectColor = glowColor;
|
||||
initProgram();
|
||||
}
|
||||
|
||||
void Label::enableOutline(const Color4B& outlineColor,int outlineSize /* = 1 */)
|
||||
{
|
||||
_outlineColor = outlineColor;
|
||||
if (outlineSize > 0)
|
||||
{
|
||||
_currLabelEffect = LabelEffect::OUTLINE;
|
||||
if (_fontConfig.outlineSize != outlineSize)
|
||||
{
|
||||
_fontConfig.outlineSize = outlineSize;
|
||||
setTTFConfig(_fontConfig);
|
||||
}
|
||||
initProgram();
|
||||
}
|
||||
}
|
||||
|
||||
void Label::enableShadow(const Color3B& shadowColor /* = Color3B::BLACK */,const Size &offset /* = Size(2 ,-2)*/, float opacity /* = 0.75f */, int blurRadius /* = 0 */)
|
||||
{
|
||||
_shadowOpacity = opacity;
|
||||
_effectColor = shadowColor;
|
||||
_shadowOffset = offset;
|
||||
//todo:support blur for shadow
|
||||
_shadowBlurRadius = 0;
|
||||
_currLabelEffect = LabelEffect::SHADOW;
|
||||
}
|
||||
|
||||
void Label::disableEffect()
|
||||
{
|
||||
if (_currLabelEffect == LabelEffect::OUTLINE)
|
||||
{
|
||||
_fontConfig.outlineSize = 0;
|
||||
setTTFConfig(_fontConfig);
|
||||
}
|
||||
_currLabelEffect = LabelEffect::NORMAL;
|
||||
initProgram();
|
||||
}
|
||||
|
||||
void Label::setFontScale(float fontScale)
|
||||
|
@ -647,7 +723,7 @@ void Label::setFontScale(float fontScale)
|
|||
Node::setScale(_fontScale);
|
||||
}
|
||||
|
||||
void Label::onDraw()
|
||||
void Label::onDraw(const kmMat4& transform, bool transformUpdated)
|
||||
{
|
||||
CC_PROFILER_START("Label - draw");
|
||||
|
||||
|
@ -657,32 +733,83 @@ void Label::onDraw()
|
|||
return;
|
||||
}
|
||||
|
||||
CC_NODE_DRAW_SETUP();
|
||||
_shaderProgram->use();
|
||||
GL::blendFunc( _blendFunc.src, _blendFunc.dst );
|
||||
bool trans = false;
|
||||
|
||||
if (_useDistanceField && _currLabelEffect != LabelEffect::NORMAL)
|
||||
if (_currLabelEffect == LabelEffect::OUTLINE)
|
||||
{
|
||||
_shaderProgram->setUniformLocationWith4f(_uniformEffectColor, _outlineColor.r/255.0f,_outlineColor.g/255.0f,_outlineColor.b/255.0f,_outlineColor.a/255.0f);
|
||||
}
|
||||
else if (_currLabelEffect == LabelEffect::GLOW)
|
||||
{
|
||||
_shaderProgram->setUniformLocationWith3f(_uniformEffectColor, _effectColor.r/255.0f,_effectColor.g/255.0f,_effectColor.b/255.0f);
|
||||
}
|
||||
|
||||
for(const auto &child: _children)
|
||||
else if(_currLabelEffect == LabelEffect::SHADOW && _shadowBlurRadius <= 0)
|
||||
{
|
||||
child->updateTransform();
|
||||
trans = true;
|
||||
drawShadowWithoutBlur();
|
||||
}
|
||||
|
||||
GL::blendFunc( _blendFunc.src, _blendFunc.dst );
|
||||
_shaderProgram->setUniformsForBuiltins(transform);
|
||||
|
||||
for(const auto &child: _children)
|
||||
{
|
||||
if(child->getTag() >= 0)
|
||||
child->updateTransform();
|
||||
}
|
||||
|
||||
for (const auto& batchNode:_batchNodes)
|
||||
{
|
||||
batchNode->getTextureAtlas()->drawQuads();
|
||||
}
|
||||
|
||||
if (trans)
|
||||
{
|
||||
kmGLPopMatrix();
|
||||
}
|
||||
|
||||
CC_PROFILER_STOP("Label - draw");
|
||||
}
|
||||
|
||||
void Label::drawShadowWithoutBlur()
|
||||
{
|
||||
_position.x += _shadowOffset.width;
|
||||
_position.y += _shadowOffset.height;
|
||||
_transformDirty = _inverseDirty = true;
|
||||
Color3B oldColor = _realColor;
|
||||
GLubyte oldOPacity = _displayedOpacity;
|
||||
_displayedOpacity = _shadowOpacity * _displayedOpacity;
|
||||
setColor(_effectColor);
|
||||
|
||||
_modelViewTransform = transform(_parentTransform);
|
||||
kmGLPushMatrix();
|
||||
kmGLLoadMatrix(&_modelViewTransform);
|
||||
|
||||
_shaderProgram->setUniformsForBuiltins(_modelViewTransform);
|
||||
for(const auto &child: _children)
|
||||
{
|
||||
child->updateTransform();
|
||||
}
|
||||
for (const auto& batchNode:_batchNodes)
|
||||
{
|
||||
batchNode->getTextureAtlas()->drawQuads();
|
||||
}
|
||||
|
||||
_position.x -= _shadowOffset.width;
|
||||
_position.y -= _shadowOffset.height;
|
||||
_transformDirty = _inverseDirty = true;
|
||||
_displayedOpacity = oldOPacity;
|
||||
setColor(oldColor);
|
||||
_modelViewTransform = transform(_parentTransform);
|
||||
kmGLLoadMatrix(&_modelViewTransform);
|
||||
//kmGLPopMatrix();
|
||||
}
|
||||
|
||||
void Label::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
|
||||
{
|
||||
_customCommand.init(_globalZOrder);
|
||||
_customCommand.func = CC_CALLBACK_0(Label::onDraw, this);
|
||||
_customCommand.func = CC_CALLBACK_0(Label::onDraw, this, transform, transformUpdated);
|
||||
renderer->addCommand(&_customCommand);
|
||||
}
|
||||
|
||||
|
@ -692,34 +819,42 @@ void Label::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parent
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currLabelEffect == LabelEffect::SHADOW && _shadowBlurRadius <= 0)
|
||||
{
|
||||
_parentTransform = parentTransform;
|
||||
draw(renderer, _modelViewTransform, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool dirty = parentTransformUpdated || _transformUpdated;
|
||||
|
||||
if(dirty)
|
||||
_modelViewTransform = transform(parentTransform);
|
||||
_transformUpdated = false;
|
||||
|
||||
// IMPORTANT:
|
||||
// To ease the migration to v3.0, we still support the kmGL stack,
|
||||
// but it is deprecated and your code should not rely on it
|
||||
kmGLPushMatrix();
|
||||
kmGLLoadMatrix(&_modelViewTransform);
|
||||
|
||||
draw(renderer, _modelViewTransform, dirty);
|
||||
|
||||
kmGLPopMatrix();
|
||||
}
|
||||
|
||||
bool dirty = parentTransformUpdated || _transformUpdated;
|
||||
if(dirty)
|
||||
_modelViewTransform = transform(parentTransform);
|
||||
_transformUpdated = false;
|
||||
|
||||
// IMPORTANT:
|
||||
// To ease the migration to v3.0, we still support the kmGL stack,
|
||||
// but it is deprecated and your code should not rely on it
|
||||
kmGLPushMatrix();
|
||||
kmGLLoadMatrix(&_modelViewTransform);
|
||||
|
||||
draw(renderer, _modelViewTransform, dirty);
|
||||
|
||||
kmGLPopMatrix();
|
||||
|
||||
setOrderOfArrival(0);
|
||||
}
|
||||
|
||||
///// PROTOCOL STUFF
|
||||
|
||||
Sprite * Label::getLetter(int lettetIndex)
|
||||
{
|
||||
if (lettetIndex < getStringLenght())
|
||||
{
|
||||
if(_lettersInfo[lettetIndex].def.validDefinition == false)
|
||||
return nullptr;
|
||||
|
||||
|
||||
Sprite* sp = static_cast<Sprite*>(this->getChildByTag(lettetIndex));
|
||||
|
||||
if (!sp)
|
||||
|
@ -730,17 +865,17 @@ Sprite * Label::getLetter(int lettetIndex)
|
|||
uvRect.origin.x = _lettersInfo[lettetIndex].def.U;
|
||||
uvRect.origin.y = _lettersInfo[lettetIndex].def.V;
|
||||
|
||||
sp = Sprite::createWithTexture(&_fontAtlas->getTexture(_lettersInfo[lettetIndex].def.textureID),uvRect);
|
||||
sp = Sprite::createWithTexture(_fontAtlas->getTexture(_lettersInfo[lettetIndex].def.textureID),uvRect);
|
||||
sp->setBatchNode(this);
|
||||
sp->setAnchorPoint(Point::ANCHOR_MIDDLE);
|
||||
sp->setPosition(Point(_lettersInfo[lettetIndex].position.x+uvRect.size.width/2,_lettersInfo[lettetIndex].position.y-uvRect.size.height/2));
|
||||
sp->setOpacity(_realOpacity);
|
||||
|
||||
|
||||
this->addSpriteWithoutQuad(sp, lettetIndex, lettetIndex);
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -758,14 +893,14 @@ int Label::getStringNumLines() const
|
|||
void Label::computeStringNumLines()
|
||||
{
|
||||
int quantityOfLines = 1;
|
||||
|
||||
|
||||
unsigned int stringLen = _currentUTF16String ? cc_wcslen(_currentUTF16String) : -1;
|
||||
if (stringLen < 1)
|
||||
{
|
||||
_currNumLines = stringLen;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// count number of lines
|
||||
for (unsigned int i = 0; i < stringLen - 1; ++i)
|
||||
{
|
||||
|
@ -774,7 +909,7 @@ void Label::computeStringNumLines()
|
|||
quantityOfLines++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_currNumLines = quantityOfLines;
|
||||
}
|
||||
|
||||
|
@ -800,8 +935,6 @@ bool Label::breakLineWithoutSpace() const
|
|||
}
|
||||
|
||||
// RGBA protocol
|
||||
|
||||
|
||||
bool Label::isOpacityModifyRGB() const
|
||||
{
|
||||
return _isOpacityModifyRGB;
|
||||
|
@ -810,7 +943,7 @@ bool Label::isOpacityModifyRGB() const
|
|||
void Label::setOpacityModifyRGB(bool isOpacityModifyRGB)
|
||||
{
|
||||
_isOpacityModifyRGB = isOpacityModifyRGB;
|
||||
|
||||
|
||||
for(const auto& child: _children) {
|
||||
child->setOpacityModifyRGB(_isOpacityModifyRGB);
|
||||
}
|
||||
|
@ -820,16 +953,19 @@ void Label::setOpacityModifyRGB(bool isOpacityModifyRGB)
|
|||
|
||||
void Label::setColor(const Color3B& color)
|
||||
{
|
||||
_reusedLetter->setColor(color);
|
||||
_reusedLetter->setColor(color);
|
||||
SpriteBatchNode::setColor(color);
|
||||
}
|
||||
|
||||
void Label::updateColor()
|
||||
{
|
||||
V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads();
|
||||
auto count = _textureAtlas->getTotalQuads();
|
||||
if (nullptr == _textureAtlas)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity );
|
||||
|
||||
|
||||
// special opacity for premultiplied textures
|
||||
if (_isOpacityModifyRGB)
|
||||
{
|
||||
|
@ -837,13 +973,23 @@ void Label::updateColor()
|
|||
color4.g *= _displayedOpacity/255.0f;
|
||||
color4.b *= _displayedOpacity/255.0f;
|
||||
}
|
||||
for (int index=0; index<count; ++index)
|
||||
|
||||
cocos2d::TextureAtlas* textureAtlas;
|
||||
V3F_C4B_T2F_Quad *quads;
|
||||
for (const auto& batchNode:_batchNodes)
|
||||
{
|
||||
quads[index].bl.colors = color4;
|
||||
quads[index].br.colors = color4;
|
||||
quads[index].tl.colors = color4;
|
||||
quads[index].tr.colors = color4;
|
||||
_textureAtlas->updateQuad(&quads[index], index);
|
||||
textureAtlas = batchNode->getTextureAtlas();
|
||||
quads = textureAtlas->getQuads();
|
||||
auto count = textureAtlas->getTotalQuads();
|
||||
|
||||
for (int index = 0; index < count; ++index)
|
||||
{
|
||||
quads[index].bl.colors = color4;
|
||||
quads[index].br.colors = color4;
|
||||
quads[index].tl.colors = color4;
|
||||
quads[index].tr.colors = color4;
|
||||
textureAtlas->updateQuad(&quads[index], index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,20 +57,29 @@ typedef struct _ttfConfig
|
|||
GlyphCollection glyphs;
|
||||
const char *customGlyphs;
|
||||
bool distanceFieldEnabled;
|
||||
int outlineSize;
|
||||
|
||||
_ttfConfig(const char* filePath,int size = 36, const GlyphCollection& glyphCollection = GlyphCollection::NEHE,
|
||||
const char *customGlyphCollection = nullptr,bool useDistanceField = false)
|
||||
_ttfConfig(const char* filePath = "",int size = 36, const GlyphCollection& glyphCollection = GlyphCollection::NEHE,
|
||||
const char *customGlyphCollection = nullptr,bool useDistanceField = false,int outline = 0)
|
||||
:fontFilePath(filePath)
|
||||
,fontSize(size)
|
||||
,glyphs(glyphCollection)
|
||||
,customGlyphs(customGlyphCollection)
|
||||
,distanceFieldEnabled(useDistanceField)
|
||||
{}
|
||||
,outlineSize(outline)
|
||||
{
|
||||
if(outline > 0)
|
||||
{
|
||||
distanceFieldEnabled = false;
|
||||
}
|
||||
}
|
||||
}TTFConfig;
|
||||
|
||||
class CC_DLL Label : public SpriteBatchNode, public LabelProtocol
|
||||
{
|
||||
public:
|
||||
static const int DefultFontSize;
|
||||
|
||||
static Label* create();
|
||||
|
||||
CC_DEPRECATED_ATTRIBUTE static Label* createWithTTF(const std::string& label, const std::string& fontFilePath, int fontSize, int lineSize = 0, TextHAlignment alignment = TextHAlignment::LEFT, GlyphCollection glyphs = GlyphCollection::NEHE, const char *customGlyphs = 0, bool useDistanceField = false);
|
||||
|
@ -82,18 +91,33 @@ public:
|
|||
static Label * createWithCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
|
||||
static Label * createWithCharMap(const std::string& plistFile);
|
||||
|
||||
bool setTTFConfig(const TTFConfig& ttfConfig);
|
||||
virtual bool setTTFConfig(const TTFConfig& ttfConfig);
|
||||
|
||||
bool setBMFontFilePath(const std::string& bmfontFilePath, const Point& imageOffset = Point::ZERO);
|
||||
virtual bool setBMFontFilePath(const std::string& bmfontFilePath, const Point& imageOffset = Point::ZERO);
|
||||
|
||||
bool setCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
|
||||
bool setCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
|
||||
bool setCharMap(const std::string& plistFile);
|
||||
virtual bool setCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
|
||||
virtual bool setCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
|
||||
virtual bool setCharMap(const std::string& plistFile);
|
||||
|
||||
virtual void setString(const std::string& text) override;
|
||||
|
||||
//only support for TTF
|
||||
void setLabelEffect(LabelEffect effect,const Color3B& effectColor);
|
||||
CC_DEPRECATED_ATTRIBUTE void setLabelEffect(LabelEffect effect,const Color3B& effectColor);
|
||||
|
||||
/**
|
||||
* Enable shadow for the label
|
||||
*
|
||||
* @todo support blur for shadow effect
|
||||
*/
|
||||
virtual void enableShadow(const Color3B& shadowColor = Color3B::BLACK,const Size &offset = Size(2,-2), float opacity = 0.75f, int blurRadius = 0);
|
||||
|
||||
/** only support for TTF */
|
||||
virtual void enableOutline(const Color4B& outlineColor,int outlineSize = -1);
|
||||
|
||||
/** only support for TTF */
|
||||
virtual void enableGlow(const Color3B& glowColor);
|
||||
|
||||
/** disable shadow/outline/glow rendering */
|
||||
virtual void disableEffect();
|
||||
|
||||
virtual void setAlignment(TextHAlignment alignment);
|
||||
CC_DEPRECATED_ATTRIBUTE void setWidth(float width) { setMaxLineWidth(width);}
|
||||
|
@ -112,29 +136,30 @@ public:
|
|||
virtual Sprite * getLetter(int lettetIndex);
|
||||
|
||||
// font related stuff
|
||||
virtual int getCommonLineHeight() const;
|
||||
|
||||
int getCommonLineHeight() const;
|
||||
|
||||
// string related stuff
|
||||
virtual int getStringNumLines() const;
|
||||
virtual int getStringLenght() const;
|
||||
virtual TextHAlignment getTextAlignment() const;
|
||||
int getStringNumLines() const;
|
||||
int getStringLenght() const;
|
||||
TextHAlignment getTextAlignment() const;
|
||||
|
||||
// label related stuff
|
||||
virtual float getMaxLineWidth() const;
|
||||
virtual bool breakLineWithoutSpace() const;
|
||||
CC_DEPRECATED_ATTRIBUTE float getWidth() const { return getMaxLineWidth(); }
|
||||
float getMaxLineWidth() const;
|
||||
bool breakLineWithoutSpace() const;
|
||||
|
||||
virtual const std::string& getString() const override { return _originalUTF8String; }
|
||||
void addChild(Node * child, int zOrder=0, int tag=0) override;
|
||||
virtual void addChild(Node * child, int zOrder=0, int tag=0) override;
|
||||
|
||||
virtual std::string getDescription() const override;
|
||||
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
|
||||
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
|
||||
virtual void onDraw();
|
||||
|
||||
virtual FontAtlas* getFontAtlas() const {return _fontAtlas;}
|
||||
FontAtlas* getFontAtlas() const {return _fontAtlas;}
|
||||
|
||||
protected:
|
||||
void onDraw(const kmMat4& transform, bool transformUpdated);
|
||||
|
||||
private:
|
||||
struct LetterInfo
|
||||
{
|
||||
FontLetterDefinition def;
|
||||
|
@ -150,19 +175,19 @@ private:
|
|||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
~Label();
|
||||
virtual ~Label();
|
||||
|
||||
bool initWithFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled = false, bool useA8Shader = false);
|
||||
virtual bool initWithFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled = false, bool useA8Shader = false);
|
||||
|
||||
// CCLabelTextFormat protocol implementation
|
||||
virtual bool recordLetterInfo(const cocos2d::Point& point,const FontLetterDefinition& letterDef, int spriteIndex);
|
||||
virtual bool recordPlaceholderInfo(int spriteIndex);
|
||||
bool recordLetterInfo(const cocos2d::Point& point,const FontLetterDefinition& letterDef, int spriteIndex);
|
||||
bool recordPlaceholderInfo(int spriteIndex);
|
||||
|
||||
void setFontScale(float fontScale);
|
||||
|
||||
bool init();
|
||||
virtual bool init();
|
||||
|
||||
void alignText();
|
||||
virtual void alignText();
|
||||
|
||||
bool computeHorizontalKernings(unsigned short int *stringToRender);
|
||||
bool setCurrentString(unsigned short *stringToSet);
|
||||
|
@ -174,6 +199,10 @@ private:
|
|||
|
||||
virtual void updateColor() override;
|
||||
|
||||
virtual void initProgram();
|
||||
|
||||
void drawShadowWithoutBlur();
|
||||
|
||||
//! used for optimization
|
||||
Sprite *_reusedLetter;
|
||||
Rect _reusedRect;
|
||||
|
@ -204,6 +233,19 @@ private:
|
|||
|
||||
std::vector<SpriteBatchNode*> _batchNodes;
|
||||
|
||||
Size _shadowOffset;
|
||||
float _shadowOpacity;
|
||||
int _shadowBlurRadius;
|
||||
|
||||
Color4B _outlineColor;
|
||||
|
||||
TTFConfig _fontConfig;
|
||||
|
||||
kmMat4 _parentTransform;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(Label);
|
||||
|
||||
friend class LabelTextFormatter;
|
||||
};
|
||||
|
||||
|
|
|
@ -584,7 +584,7 @@ void LayerColor::updateColor()
|
|||
void LayerColor::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
|
||||
{
|
||||
_customCommand.init(_globalZOrder);
|
||||
_customCommand.func = CC_CALLBACK_0(LayerColor::onDraw, this);
|
||||
_customCommand.func = CC_CALLBACK_0(LayerColor::onDraw, this, transform, transformUpdated);
|
||||
renderer->addCommand(&_customCommand);
|
||||
|
||||
for(int i = 0; i < 4; ++i)
|
||||
|
@ -594,12 +594,12 @@ void LayerColor::draw(Renderer *renderer, const kmMat4 &transform, bool transfor
|
|||
kmVec3TransformCoord(&pos, &pos, &_modelViewTransform);
|
||||
_noMVPVertices[i] = Vertex3F(pos.x,pos.y,pos.z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LayerColor::onDraw()
|
||||
void LayerColor::onDraw(const kmMat4& transform, bool transformUpdated)
|
||||
{
|
||||
CC_NODE_DRAW_SETUP();
|
||||
getShaderProgram()->use();
|
||||
getShaderProgram()->setUniformsForBuiltins(transform);
|
||||
|
||||
GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR );
|
||||
//
|
||||
|
|
|
@ -266,8 +266,7 @@ public:
|
|||
// Overrides
|
||||
//
|
||||
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
|
||||
virtual void onDraw();
|
||||
|
||||
|
||||
virtual void setContentSize(const Size & var) override;
|
||||
/** BlendFunction. Conforms to BlendProtocol protocol */
|
||||
/**
|
||||
|
@ -289,7 +288,8 @@ public:
|
|||
protected:
|
||||
LayerColor();
|
||||
virtual ~LayerColor();
|
||||
virtual bool init();
|
||||
void onDraw(const kmMat4& transform, bool transformUpdated);
|
||||
bool init();
|
||||
bool initWithColor(const Color4B& color, GLfloat width, GLfloat height);
|
||||
bool initWithColor(const Color4B& color);
|
||||
|
||||
|
|
|
@ -325,10 +325,10 @@ void MotionStreak::reset()
|
|||
_nuPoints = 0;
|
||||
}
|
||||
|
||||
void MotionStreak::onDraw()
|
||||
void MotionStreak::onDraw(const kmMat4 &transform, bool transformUpdated)
|
||||
{
|
||||
getShaderProgram()->use();
|
||||
getShaderProgram()->setUniformsForBuiltins(_modelViewTransform);
|
||||
getShaderProgram()->setUniformsForBuiltins(transform);
|
||||
|
||||
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
|
||||
GL::blendFunc( _blendFunc.src, _blendFunc.dst );
|
||||
|
@ -360,9 +360,8 @@ void MotionStreak::draw(Renderer *renderer, const kmMat4 &transform, bool transf
|
|||
if(_nuPoints <= 1)
|
||||
return;
|
||||
_customCommand.init(_globalZOrder);
|
||||
_customCommand.func = CC_CALLBACK_0(MotionStreak::onDraw, this);
|
||||
_customCommand.func = CC_CALLBACK_0(MotionStreak::onDraw, this, transform, transformUpdated);
|
||||
renderer->addCommand(&_customCommand);
|
||||
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
|
||||
protected:
|
||||
//renderer callback
|
||||
void onDraw();
|
||||
void onDraw(const kmMat4 &transform, bool transformUpdated);
|
||||
MotionStreak();
|
||||
virtual ~MotionStreak();
|
||||
|
||||
|
|
|
@ -351,7 +351,6 @@ void ParticleBatchNode::removeChild(Node* aChild, bool cleanup)
|
|||
CCASSERT(_children.contains(aChild), "CCParticleBatchNode doesn't contain the sprite. Can't remove it");
|
||||
|
||||
ParticleSystem* child = static_cast<ParticleSystem*>(aChild);
|
||||
Node::removeChild(child, cleanup);
|
||||
|
||||
// remove child helper
|
||||
_textureAtlas->removeQuadsAtIndex(child->getAtlasIndex(), child->getTotalParticles());
|
||||
|
@ -361,6 +360,7 @@ void ParticleBatchNode::removeChild(Node* aChild, bool cleanup)
|
|||
|
||||
// particle could be reused for self rendering
|
||||
child->setBatchNode(nullptr);
|
||||
Node::removeChild(child, cleanup);
|
||||
|
||||
updateAllAtlasIndexes();
|
||||
}
|
||||
|
|
|
@ -501,10 +501,11 @@ Point ProgressTimer::boundaryTexCoord(char index)
|
|||
return Point::ZERO;
|
||||
}
|
||||
|
||||
void ProgressTimer::onDraw()
|
||||
void ProgressTimer::onDraw(const kmMat4 &transform, bool transformUpdated)
|
||||
{
|
||||
|
||||
CC_NODE_DRAW_SETUP();
|
||||
getShaderProgram()->use();
|
||||
getShaderProgram()->setUniformsForBuiltins(transform);
|
||||
|
||||
GL::blendFunc( _sprite->getBlendFunc().src, _sprite->getBlendFunc().dst );
|
||||
|
||||
|
@ -557,7 +558,7 @@ void ProgressTimer::draw(Renderer *renderer, const kmMat4 &transform, bool trans
|
|||
return;
|
||||
|
||||
_customCommand.init(_globalZOrder);
|
||||
_customCommand.func = CC_CALLBACK_0(ProgressTimer::onDraw, this);
|
||||
_customCommand.func = CC_CALLBACK_0(ProgressTimer::onDraw, this, transform, transformUpdated);
|
||||
renderer->addCommand(&_customCommand);
|
||||
}
|
||||
|
||||
|
|
|
@ -131,8 +131,7 @@ protected:
|
|||
|
||||
/** Initializes a progress timer with the sprite as the shape the timer goes through */
|
||||
bool initWithSprite(Sprite* sp);
|
||||
|
||||
void onDraw();
|
||||
void onDraw(const kmMat4 &transform, bool transformUpdated);
|
||||
|
||||
Tex2F textureCoordFromAlphaPoint(Point alpha);
|
||||
Vertex2F vertexFromAlphaPoint(Point alpha);
|
||||
|
|
|
@ -233,11 +233,7 @@ void TimerScriptHandler::trigger()
|
|||
|
||||
void TimerScriptHandler::cancel()
|
||||
{
|
||||
if (0 != _scriptHandler)
|
||||
{
|
||||
ScriptEngineManager::getInstance()->getScriptEngine()->removeScriptHandler(_scriptHandler);
|
||||
_scriptHandler = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,8 +45,7 @@ enum {
|
|||
kShaderType_PositionLengthTexureColor,
|
||||
kShaderType_LabelDistanceFieldNormal,
|
||||
kShaderType_LabelDistanceFieldGlow,
|
||||
kShaderType_LabelDistanceFieldOutline,
|
||||
kShaderType_LabelDistanceFieldShadow,
|
||||
kShaderType_LabelOutline,
|
||||
kShaderType_MAX,
|
||||
};
|
||||
|
||||
|
@ -177,12 +176,8 @@ void ShaderCache::loadDefaultShaders()
|
|||
_programs.insert( std::make_pair(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW, p) );
|
||||
|
||||
p = new GLProgram();
|
||||
loadDefaultShader(p, kShaderType_LabelDistanceFieldOutline);
|
||||
_programs.insert( std::make_pair(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE, p) );
|
||||
|
||||
p = new GLProgram();
|
||||
loadDefaultShader(p, kShaderType_LabelDistanceFieldShadow);
|
||||
_programs.insert( std::make_pair(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW, p) );
|
||||
loadDefaultShader(p, kShaderType_LabelOutline);
|
||||
_programs.insert( std::make_pair(GLProgram::SHADER_NAME_LABEL_OUTLINE, p) );
|
||||
}
|
||||
|
||||
void ShaderCache::reloadDefaultShaders()
|
||||
|
@ -260,122 +255,110 @@ void ShaderCache::reloadDefaultShaders()
|
|||
p->reset();
|
||||
loadDefaultShader(p, kShaderType_LabelDistanceFieldGlow);
|
||||
|
||||
p = getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE);
|
||||
p = getProgram(GLProgram::SHADER_NAME_LABEL_OUTLINE);
|
||||
p->reset();
|
||||
loadDefaultShader(p, kShaderType_LabelDistanceFieldOutline);
|
||||
|
||||
p = getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW);
|
||||
p->reset();
|
||||
loadDefaultShader(p, kShaderType_LabelDistanceFieldShadow);
|
||||
loadDefaultShader(p, kShaderType_LabelOutline);
|
||||
}
|
||||
|
||||
void ShaderCache::loadDefaultShader(GLProgram *p, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case kShaderType_PositionTextureColor:
|
||||
p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColor_frag);
|
||||
p->initWithByteArrays(ccPositionTextureColor_vert, ccPositionTextureColor_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
case kShaderType_PositionTextureColor_noMVP:
|
||||
p->initWithVertexShaderByteArray(ccPositionTextureColor_noMVP_vert, ccPositionTextureColor_noMVP_frag);
|
||||
p->initWithByteArrays(ccPositionTextureColor_noMVP_vert, ccPositionTextureColor_noMVP_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
|
||||
case kShaderType_PositionTextureColorAlphaTest:
|
||||
p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColorAlphaTest_frag);
|
||||
p->initWithByteArrays(ccPositionTextureColor_vert, ccPositionTextureColorAlphaTest_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
case kShaderType_PositionColor:
|
||||
p->initWithVertexShaderByteArray(ccPositionColor_vert ,ccPositionColor_frag);
|
||||
p->initWithByteArrays(ccPositionColor_vert ,ccPositionColor_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
|
||||
break;
|
||||
case kShaderType_PositionColor_noMVP:
|
||||
p->initWithVertexShaderByteArray(ccPositionTextureColor_noMVP_vert ,ccPositionColor_frag);
|
||||
p->initWithByteArrays(ccPositionTextureColor_noMVP_vert ,ccPositionColor_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
break;
|
||||
case kShaderType_PositionTexture:
|
||||
p->initWithVertexShaderByteArray(ccPositionTexture_vert ,ccPositionTexture_frag);
|
||||
p->initWithByteArrays(ccPositionTexture_vert ,ccPositionTexture_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
case kShaderType_PositionTexture_uColor:
|
||||
p->initWithVertexShaderByteArray(ccPositionTexture_uColor_vert, ccPositionTexture_uColor_frag);
|
||||
p->initWithByteArrays(ccPositionTexture_uColor_vert, ccPositionTexture_uColor_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
case kShaderType_PositionTextureA8Color:
|
||||
p->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, ccPositionTextureA8Color_frag);
|
||||
p->initWithByteArrays(ccPositionTextureA8Color_vert, ccPositionTextureA8Color_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
case kShaderType_Position_uColor:
|
||||
p->initWithVertexShaderByteArray(ccPosition_uColor_vert, ccPosition_uColor_frag);
|
||||
p->initWithByteArrays(ccPosition_uColor_vert, ccPosition_uColor_frag);
|
||||
|
||||
p->addAttribute("aVertex", GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation("aVertex", GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
|
||||
break;
|
||||
case kShaderType_PositionLengthTexureColor:
|
||||
p->initWithVertexShaderByteArray(ccPositionColorLengthTexture_vert, ccPositionColorLengthTexture_frag);
|
||||
p->initWithByteArrays(ccPositionColorLengthTexture_vert, ccPositionColorLengthTexture_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
|
||||
break;
|
||||
case kShaderType_LabelDistanceFieldNormal:
|
||||
p->initWithVertexShaderByteArray(ccLabelDistanceFieldNormal_vert, ccLabelDistanceFieldNormal_frag);
|
||||
p->initWithByteArrays(ccLabelDistanceFieldNormal_vert, ccLabelDistanceFieldNormal_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
case kShaderType_LabelDistanceFieldGlow:
|
||||
p->initWithVertexShaderByteArray(ccLabelDistanceFieldGlow_vert, ccLabelDistanceFieldGlow_frag);
|
||||
p->initWithByteArrays(ccLabelDistanceFieldGlow_vert, ccLabelDistanceFieldGlow_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
case kShaderType_LabelDistanceFieldOutline:
|
||||
p->initWithVertexShaderByteArray(ccLabelDistanceFieldOutline_vert, ccLabelDistanceFieldOutline_frag);
|
||||
case kShaderType_LabelOutline:
|
||||
p->initWithByteArrays(ccLabelOutline_vert, ccLabelOutline_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
case kShaderType_LabelDistanceFieldShadow:
|
||||
p->initWithVertexShaderByteArray(ccLabelDistanceFieldShadow_vert, ccLabelDistanceFieldShadow_frag);
|
||||
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
|
||||
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -18,7 +18,7 @@ void main() \n\
|
|||
//float width = fwidth(dist); \n\
|
||||
//assign width for constant will lead to a little bit fuzzy,it's temporary measure.\n\
|
||||
float width = 0.04; \n\
|
||||
float alpha = smoothstep(0.5-width, 0.5+width, dist); \n\
|
||||
float alpha = smoothstep(0.5-width, 0.5+width, dist) * v_fragmentColor.a; \n\
|
||||
gl_FragColor = vec4(v_fragmentColor.rgb,alpha); \n\
|
||||
} \n\
|
||||
";
|
||||
|
|
|
@ -6,19 +6,19 @@ precision lowp float; \n\
|
|||
varying vec4 v_fragmentColor; \n\
|
||||
varying vec2 v_texCoord; \n\
|
||||
uniform sampler2D CC_Texture0; \n\
|
||||
uniform vec3 v_effectColor; \n\
|
||||
uniform vec4 v_effectColor; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
float dist = texture2D(CC_Texture0, v_texCoord).a; \n\
|
||||
//todo:Implementation 'fwidth' for glsl 1.0 \n\
|
||||
//float width = fwidth(dist); \n\
|
||||
//assign width for constant will lead to a little bit fuzzy,it's temporary measure.\n\
|
||||
float width = 0.04; \n\
|
||||
float alpha = smoothstep(0.5-width, 0.5+width, dist); \n\
|
||||
//outline \n\
|
||||
float mu = smoothstep(0.545-width, 0.545+width, dist); \n\
|
||||
vec3 rgb = v_effectColor*(1.0-mu) + v_fragmentColor.rgb*mu; \n\
|
||||
gl_FragColor = vec4(rgb, max(alpha,mu)); \n\
|
||||
} \n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
vec4 sample = texture2D(CC_Texture0, v_texCoord); \n\
|
||||
float fontAlpha = sample.a; \n\
|
||||
float outlineAlpha = sample.r; \n\
|
||||
if (outlineAlpha > 0.0){ \n\
|
||||
vec3 color = v_fragmentColor.rgb * fontAlpha + v_effectColor.rgb * (1.0 - fontAlpha);\n\
|
||||
gl_FragColor = vec4( color,max(fontAlpha,outlineAlpha)*v_fragmentColor.a); \n\
|
||||
} \n\
|
||||
else { \n\
|
||||
discard; \n\
|
||||
} \n\
|
||||
} \n\
|
||||
";
|
||||
|
|
|
@ -91,14 +91,9 @@ const GLchar * ccLabelDistanceFieldGlow_frag =
|
|||
const GLchar * ccLabelDistanceFieldGlow_vert =
|
||||
#include "ccShader_Label_vert.h"
|
||||
|
||||
const GLchar * ccLabelDistanceFieldOutline_frag =
|
||||
const GLchar * ccLabelOutline_frag =
|
||||
#include "ccShader_Label_frag_outline.h"
|
||||
const GLchar * ccLabelDistanceFieldOutline_vert =
|
||||
#include "ccShader_Label_vert.h"
|
||||
|
||||
const GLchar * ccLabelDistanceFieldShadow_frag =
|
||||
#include "ccShader_Label_frag_shadow.h"
|
||||
const GLchar * ccLabelDistanceFieldShadow_vert =
|
||||
const GLchar * ccLabelOutline_vert =
|
||||
#include "ccShader_Label_vert.h"
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -68,11 +68,8 @@ extern CC_DLL const GLchar * ccLabelDistanceFieldNormal_vert;
|
|||
extern CC_DLL const GLchar * ccLabelDistanceFieldGlow_frag;
|
||||
extern CC_DLL const GLchar * ccLabelDistanceFieldGlow_vert;
|
||||
|
||||
extern CC_DLL const GLchar * ccLabelDistanceFieldOutline_frag;
|
||||
extern CC_DLL const GLchar * ccLabelDistanceFieldOutline_vert;
|
||||
|
||||
extern CC_DLL const GLchar * ccLabelDistanceFieldShadow_frag;
|
||||
extern CC_DLL const GLchar * ccLabelDistanceFieldShadow_vert;
|
||||
extern CC_DLL const GLchar * ccLabelOutline_frag;
|
||||
extern CC_DLL const GLchar * ccLabelOutline_vert;
|
||||
|
||||
extern CC_DLL const GLchar * ccExSwitchMask_frag;
|
||||
|
||||
|
|
|
@ -182,19 +182,42 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
|
|||
<ClCompile Include="..\base\CCValue.cpp" />
|
||||
<ClCompile Include="..\base\etc1.cpp" />
|
||||
<ClCompile Include="..\base\s3tc.cpp" />
|
||||
<ClCompile Include="..\math\kazmath\src\aabb.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\GL\mat4stack.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\GL\matrix.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\mat3.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\mat4.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\neon_matrix_impl.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\plane.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\quaternion.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\ray2.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\utility.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\vec2.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\vec3.c" />
|
||||
<ClCompile Include="..\math\kazmath\src\vec4.c" />
|
||||
<ClCompile Include="..\math\kazmath\kazmath\aabb.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\GL\mat4stack.c" />
|
||||
<ClCompile Include="..\math\kazmath\kazmath\GL\matrix.c" />
|
||||
<ClCompile Include="..\math\kazmath\kazmath\mat3.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\mat4.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\neon_matrix_impl.c" />
|
||||
<ClCompile Include="..\math\kazmath\kazmath\plane.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\quaternion.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\ray2.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\ray3.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\utility.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\vec2.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\vec3.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\vec4.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\physics\CCPhysicsBody.cpp" />
|
||||
<ClCompile Include="..\physics\CCPhysicsContact.cpp" />
|
||||
<ClCompile Include="..\physics\CCPhysicsJoint.cpp" />
|
||||
|
@ -358,20 +381,21 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
|
|||
<ClInclude Include="..\base\CCVector.h" />
|
||||
<ClInclude Include="..\base\etc1.h" />
|
||||
<ClInclude Include="..\base\s3tc.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\aabb.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\GL\mat4stack.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\GL\matrix.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\kazmath.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\mat3.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\mat4.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\neon_matrix_impl.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\plane.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\quaternion.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\ray2.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\utility.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\vec2.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\vec3.h" />
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\vec4.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\aabb.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\GL\mat4stack.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\GL\matrix.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\kazmath.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\mat3.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\mat4.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\neon_matrix_impl.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\plane.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\quaternion.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\ray2.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\ray3.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\utility.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\vec2.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\vec3.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\vec4.h" />
|
||||
<ClInclude Include="..\physics\CCPhysicsBody.h" />
|
||||
<ClInclude Include="..\physics\CCPhysicsContact.h" />
|
||||
<ClInclude Include="..\physics\CCPhysicsJoint.h" />
|
||||
|
@ -537,4 +561,4 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -180,45 +180,6 @@
|
|||
<ClCompile Include="CCTouch.cpp">
|
||||
<Filter>event_dispatcher</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\GL\mat4stack.c">
|
||||
<Filter>kazmath\src\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\GL\matrix.c">
|
||||
<Filter>kazmath\src\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\aabb.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\mat3.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\mat4.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\neon_matrix_impl.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\plane.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\quaternion.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\ray2.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\utility.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\vec2.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\vec3.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\src\vec4.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CCLayer.cpp">
|
||||
<Filter>layers_scenes_transitions_nodes</Filter>
|
||||
</ClCompile>
|
||||
|
@ -598,6 +559,49 @@
|
|||
<ClCompile Include="platform\CCImage.cpp">
|
||||
<Filter>platform</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CCTweenFunction.cpp" />
|
||||
<ClCompile Include="..\math\kazmath\kazmath\GL\mat4stack.c">
|
||||
<Filter>kazmath\src\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\GL\matrix.c">
|
||||
<Filter>kazmath\src\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\aabb.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\mat3.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\mat4.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\neon_matrix_impl.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\plane.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\quaternion.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\ray2.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\ray3.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\utility.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\vec2.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\vec3.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\math\kazmath\kazmath\vec4.c">
|
||||
<Filter>kazmath\src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\physics\CCPhysicsBody.h">
|
||||
|
@ -684,48 +688,6 @@
|
|||
<ClInclude Include="cocos2d.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\aabb.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\kazmath.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\mat3.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\mat4.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\neon_matrix_impl.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\plane.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\quaternion.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\ray2.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\utility.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\vec2.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\vec3.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\vec4.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\GL\mat4stack.h">
|
||||
<Filter>kazmath\include\kazmath\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\include\kazmath\GL\matrix.h">
|
||||
<Filter>kazmath\include\kazmath\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CCLayer.h">
|
||||
<Filter>layers_scenes_transitions_nodes</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1198,5 +1160,51 @@
|
|||
<ClInclude Include="platform\desktop\CCGLView.h">
|
||||
<Filter>platform\desktop</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CCTweenFunction.h" />
|
||||
<ClInclude Include="..\math\kazmath\kazmath\GL\mat4stack.h">
|
||||
<Filter>kazmath\include\kazmath\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\GL\matrix.h">
|
||||
<Filter>kazmath\include\kazmath\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\aabb.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\kazmath.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\mat3.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\mat4.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\neon_matrix_impl.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\plane.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\quaternion.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\ray2.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\ray3.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\utility.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\vec2.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\vec3.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\math\kazmath\kazmath\vec4.h">
|
||||
<Filter>kazmath\include\kazmath</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -7,7 +7,7 @@
|
|||
<PropertyGroup />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)cocos\2d;$(EngineRoot)cocos\2d\renderer;$(EngineRoot)cocos\gui;$(EngineRoot)cocos\base;$(EngineRoot)cocos\physics;$(EngineRoot)cocos\math\kazmath\include;$(EngineRoot)cocos\2d\platform\win32;$(EngineRoot)cocos\2d\platform\desktop;$(EngineRoot)external\glfw3\include\win32;$(EngineRoot)external\win32-specific\gles\include\OGLES</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)cocos\2d;$(EngineRoot)cocos\2d\renderer;$(EngineRoot)cocos\gui;$(EngineRoot)cocos\base;$(EngineRoot)cocos\physics;$(EngineRoot)cocos\math\kazmath;$(EngineRoot)cocos\2d\platform\win32;$(EngineRoot)cocos\2d\platform\desktop;$(EngineRoot)external\glfw3\include\win32;$(EngineRoot)external\win32-specific\gles\include\OGLES</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_VARIADIC_MAX=10;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
|
|
@ -24,7 +24,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
|||
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
|
||||
$(LOCAL_PATH)/../.. \
|
||||
$(LOCAL_PATH)/../../../base \
|
||||
$(LOCAL_PATH)/../../../math/kazmath/include \
|
||||
$(LOCAL_PATH)/../../../math/kazmath \
|
||||
$(LOCAL_PATH)/../../../physics
|
||||
|
||||
LOCAL_LDLIBS := -lGLESv1_CM \
|
||||
|
|
|
@ -191,7 +191,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
normal = cDir;
|
||||
kmVec3Scale(&point, &cDir, nearPlane);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &point, &normal);
|
||||
}
|
||||
|
||||
//far
|
||||
|
@ -201,7 +201,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
kmVec3Scale(&normal, &cDir, -1);
|
||||
kmVec3Scale(&point, &cDir, farPlane);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &point, &normal);
|
||||
}
|
||||
|
||||
//left
|
||||
|
@ -211,7 +211,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
normal = cRight;
|
||||
kmVec3Scale(&point, &cRight, -width * 0.5);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
|
||||
}
|
||||
|
||||
//right
|
||||
|
@ -221,7 +221,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
kmVec3Scale(&normal, &cRight, -1);
|
||||
kmVec3Scale(&point, &cRight, width * 0.5);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
|
||||
}
|
||||
|
||||
//bottom
|
||||
|
@ -231,7 +231,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
normal = cUp;
|
||||
kmVec3Scale(&point, &cUp, -height * 0.5);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
|
||||
}
|
||||
|
||||
//top
|
||||
|
@ -241,7 +241,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
kmVec3Scale(&normal, &cUp, -1);
|
||||
kmVec3Scale(&point, &cUp, height * 0.5);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,14 +267,14 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
|
||||
//near
|
||||
{
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &nearCenter, &cDir);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &nearCenter, &cDir);
|
||||
}
|
||||
|
||||
//far
|
||||
{
|
||||
kmVec3 normal;
|
||||
kmVec3Scale(&normal, &cDir, -1);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &farCenter, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &farCenter, &normal);
|
||||
}
|
||||
|
||||
//left
|
||||
|
@ -288,7 +288,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
kmVec3Cross(&normal, &normal, &cUp);
|
||||
kmVec3Normalize(&normal, &normal);
|
||||
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
|
||||
}
|
||||
|
||||
//right
|
||||
|
@ -302,7 +302,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
kmVec3Cross(&normal, &cUp, &normal);
|
||||
kmVec3Normalize(&normal, &normal);
|
||||
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
|
||||
}
|
||||
|
||||
//bottom
|
||||
|
@ -316,7 +316,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
kmVec3Cross(&normal, &cRight, &normal);
|
||||
kmVec3Normalize(&normal, &normal);
|
||||
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
|
||||
}
|
||||
|
||||
//top
|
||||
|
@ -330,7 +330,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
kmVec3Cross(&normal, &normal, &cRight);
|
||||
kmVec3Normalize(&normal, &normal);
|
||||
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ LOCAL_SRC_FILES := cddSimpleAudioEngine.cpp \
|
|||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include \
|
||||
$(LOCAL_PATH)/../../math/kazmath/include \
|
||||
$(LOCAL_PATH)/../../math/kazmath \
|
||||
$(LOCAL_PATH)/../../2d \
|
||||
$(LOCAL_PATH)/../../2d/platform/android \
|
||||
$(LOCAL_PATH)/../../base \
|
||||
|
|
|
@ -381,7 +381,7 @@ void Armature::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool t
|
|||
{
|
||||
if (_parentBone == nullptr && _batchNode == nullptr)
|
||||
{
|
||||
CC_NODE_DRAW_SETUP();
|
||||
// CC_NODE_DRAW_SETUP();
|
||||
}
|
||||
|
||||
|
||||
|
@ -418,7 +418,7 @@ void Armature::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool t
|
|||
default:
|
||||
{
|
||||
node->visit(renderer, transform, transformUpdated);
|
||||
CC_NODE_DRAW_SETUP();
|
||||
// CC_NODE_DRAW_SETUP();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ void Armature::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool t
|
|||
else if(Node *node = dynamic_cast<Node *>(object))
|
||||
{
|
||||
node->visit(renderer, transform, transformUpdated);
|
||||
CC_NODE_DRAW_SETUP();
|
||||
// CC_NODE_DRAW_SETUP();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ void BatchNode::draw(Renderer *renderer, const kmMat4 &transform, bool transform
|
|||
return;
|
||||
}
|
||||
|
||||
CC_NODE_DRAW_SETUP();
|
||||
// CC_NODE_DRAW_SETUP();
|
||||
|
||||
bool pushed = false;
|
||||
for(auto object : _children)
|
||||
|
|
|
@ -355,8 +355,8 @@ void WidgetPropertiesReader0250::setColorPropsForWidgetFromJsonDictionary(Widget
|
|||
widget->setAnchorPoint(Point(apxf, apyf));
|
||||
bool flipX = DICTOOL->getBooleanValue_json(options, "flipX");
|
||||
bool flipY = DICTOOL->getBooleanValue_json(options, "flipY");
|
||||
widget->setFlipX(flipX);
|
||||
widget->setFlipY(flipY);
|
||||
widget->setFlippedX(flipX);
|
||||
widget->setFlippedY(flipY);
|
||||
}
|
||||
|
||||
void WidgetPropertiesReader0250::setPropsForButtonFromJsonDictionary(Widget*widget,const rapidjson::Value& options)
|
||||
|
@ -1129,8 +1129,8 @@ void WidgetPropertiesReader0300::setColorPropsForWidgetFromJsonDictionary(Widget
|
|||
widget->setAnchorPoint(Point(apxf, apyf));
|
||||
bool flipX = DICTOOL->getBooleanValue_json(options, "flipX");
|
||||
bool flipY = DICTOOL->getBooleanValue_json(options, "flipY");
|
||||
widget->setFlipX(flipX);
|
||||
widget->setFlipY(flipY);
|
||||
widget->setFlippedX(flipX);
|
||||
widget->setFlippedY(flipY);
|
||||
}
|
||||
|
||||
void WidgetPropertiesReader0300::setPropsForButtonFromJsonDictionary(Widget*widget,const rapidjson::Value& options)
|
||||
|
|
|
@ -129,13 +129,14 @@ void Skeleton::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool t
|
|||
{
|
||||
|
||||
_customCommand.init(_globalZOrder);
|
||||
_customCommand.func = CC_CALLBACK_0(Skeleton::onDraw, this);
|
||||
_customCommand.func = CC_CALLBACK_0(Skeleton::onDraw, this, transform, transformUpdated);
|
||||
renderer->addCommand(&_customCommand);
|
||||
}
|
||||
|
||||
void Skeleton::onDraw ()
|
||||
void Skeleton::onDraw(const kmMat4 &transform, bool transformUpdated)
|
||||
{
|
||||
CC_NODE_DRAW_SETUP();
|
||||
getShaderProgram()->use();
|
||||
getShaderProgram()->setUniformsForBuiltins(transform);
|
||||
|
||||
GL::blendFunc(blendFunc.src, blendFunc.dst);
|
||||
Color3B color = getColor();
|
||||
|
@ -193,7 +194,7 @@ void Skeleton::onDraw ()
|
|||
|
||||
if(debugBones || debugSlots) {
|
||||
kmGLPushMatrix();
|
||||
kmGLLoadMatrix(&_modelViewTransform);
|
||||
kmGLLoadMatrix(&transform);
|
||||
|
||||
if (debugSlots) {
|
||||
// Slots.
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
|
||||
virtual void update (float deltaTime) override;
|
||||
virtual void draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
|
||||
void onDraw();
|
||||
void onDraw(const kmMat4 &transform, bool transformUpdated);
|
||||
void onEnter() override;
|
||||
void onExit() override;
|
||||
virtual cocos2d::Rect getBoundingBox () const override;
|
||||
|
|
|
@ -33,7 +33,7 @@ static const int NORMAL_RENDERER_Z = (-2);
|
|||
static const int PRESSED_RENDERER_Z = (-2);
|
||||
static const int DISABLED_RENDERER_Z = (-2);
|
||||
static const int TITLE_RENDERER_Z = (-1);
|
||||
|
||||
|
||||
Button::Button():
|
||||
_buttonNormalRenderer(nullptr),
|
||||
_buttonClickedRenderer(nullptr),
|
||||
|
@ -63,7 +63,7 @@ _normalTextureLoaded(false),
|
|||
_pressedTextureLoaded(false),
|
||||
_disabledTextureLoaded(false)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
Button::~Button()
|
||||
|
@ -97,7 +97,7 @@ void Button::initRenderer()
|
|||
_buttonClickedRenderer = Sprite::create();
|
||||
_buttonDisableRenderer = Sprite::create();
|
||||
_titleRenderer = LabelTTF::create();
|
||||
|
||||
|
||||
Node::addChild(_buttonNormalRenderer, NORMAL_RENDERER_Z, -1);
|
||||
Node::addChild(_buttonClickedRenderer, PRESSED_RENDERER_Z, -1);
|
||||
Node::addChild(_buttonDisableRenderer, DISABLED_RENDERER_Z, -1);
|
||||
|
@ -152,7 +152,7 @@ void Button::setScale9Enabled(bool able)
|
|||
setCapInsetsDisabledRenderer(_capInsetsDisabled);
|
||||
setBright(_bright);
|
||||
}
|
||||
|
||||
|
||||
bool Button::isScale9Enabled()
|
||||
{
|
||||
return _scale9Enabled;
|
||||
|
@ -331,7 +331,7 @@ void Button::setCapInsetsNormalRenderer(const Rect &capInsets)
|
|||
}
|
||||
static_cast<extension::Scale9Sprite*>(_buttonNormalRenderer)->setCapInsets(capInsets);
|
||||
}
|
||||
|
||||
|
||||
const Rect& Button::getCapInsetsNormalRenderer()
|
||||
{
|
||||
return _capInsetsNormal;
|
||||
|
@ -346,7 +346,7 @@ void Button::setCapInsetsPressedRenderer(const Rect &capInsets)
|
|||
}
|
||||
static_cast<extension::Scale9Sprite*>(_buttonClickedRenderer)->setCapInsets(capInsets);
|
||||
}
|
||||
|
||||
|
||||
const Rect& Button::getCapInsetsPressedRenderer()
|
||||
{
|
||||
return _capInsetsPressed;
|
||||
|
@ -361,7 +361,7 @@ void Button::setCapInsetsDisabledRenderer(const Rect &capInsets)
|
|||
}
|
||||
static_cast<extension::Scale9Sprite*>(_buttonDisableRenderer)->setCapInsets(capInsets);
|
||||
}
|
||||
|
||||
|
||||
const Rect& Button::getCapInsetsDisabledRenderer()
|
||||
{
|
||||
return _capInsetsDisabled;
|
||||
|
@ -425,31 +425,31 @@ void Button::onPressStateChangedToDisabled()
|
|||
_buttonClickedRenderer->setScale(_pressedTextureScaleXInSize, _pressedTextureScaleYInSize);
|
||||
}
|
||||
|
||||
void Button::setFlipX(bool flipX)
|
||||
void Button::setFlippedX(bool flippedX)
|
||||
{
|
||||
_titleRenderer->setFlippedX(flipX);
|
||||
_titleRenderer->setFlippedX(flippedX);
|
||||
if (_scale9Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static_cast<Sprite*>(_buttonNormalRenderer)->setFlippedX(flipX);
|
||||
static_cast<Sprite*>(_buttonClickedRenderer)->setFlippedX(flipX);
|
||||
static_cast<Sprite*>(_buttonDisableRenderer)->setFlippedX(flipX);
|
||||
static_cast<Sprite*>(_buttonNormalRenderer)->setFlippedX(flippedX);
|
||||
static_cast<Sprite*>(_buttonClickedRenderer)->setFlippedX(flippedX);
|
||||
static_cast<Sprite*>(_buttonDisableRenderer)->setFlippedX(flippedX);
|
||||
}
|
||||
|
||||
void Button::setFlipY(bool flipY)
|
||||
void Button::setFlippedY(bool flippedY)
|
||||
{
|
||||
_titleRenderer->setFlippedY(flipY);
|
||||
_titleRenderer->setFlippedY(flippedY);
|
||||
if (_scale9Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static_cast<Sprite*>(_buttonNormalRenderer)->setFlippedY(flipY);
|
||||
static_cast<Sprite*>(_buttonClickedRenderer)->setFlippedY(flipY);
|
||||
static_cast<Sprite*>(_buttonDisableRenderer)->setFlippedY(flipY);
|
||||
static_cast<Sprite*>(_buttonNormalRenderer)->setFlippedY(flippedY);
|
||||
static_cast<Sprite*>(_buttonClickedRenderer)->setFlippedY(flippedY);
|
||||
static_cast<Sprite*>(_buttonDisableRenderer)->setFlippedY(flippedY);
|
||||
}
|
||||
|
||||
bool Button::isFlipX()
|
||||
bool Button::isFlippedX()
|
||||
{
|
||||
if (_scale9Enabled)
|
||||
{
|
||||
|
@ -458,7 +458,7 @@ bool Button::isFlipX()
|
|||
return static_cast<Sprite*>(_buttonNormalRenderer)->isFlippedX();
|
||||
}
|
||||
|
||||
bool Button::isFlipY()
|
||||
bool Button::isFlippedY()
|
||||
{
|
||||
if (_scale9Enabled)
|
||||
{
|
||||
|
@ -677,7 +677,7 @@ void Button::copySpecialProperties(Widget *widget)
|
|||
{
|
||||
Button* button = dynamic_cast<Button*>(widget);
|
||||
if (button)
|
||||
{
|
||||
{
|
||||
_prevIgnoreSize = button->_prevIgnoreSize;
|
||||
setScale9Enabled(button->_scale9Enabled);
|
||||
loadTextureNormal(button->_normalFileName.c_str(), button->_normalTexType);
|
||||
|
|
|
@ -42,17 +42,17 @@ public:
|
|||
* Default constructor
|
||||
*/
|
||||
Button();
|
||||
|
||||
|
||||
/**
|
||||
* Default destructor
|
||||
*/
|
||||
virtual ~Button();
|
||||
|
||||
|
||||
/**
|
||||
* Allocates and initializes.
|
||||
*/
|
||||
static Button* create();
|
||||
|
||||
|
||||
/**
|
||||
* Load textures for button.
|
||||
*
|
||||
|
@ -65,7 +65,7 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTextures(const char* normal,const char* selected,const char* disabled,TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Load normal state texture for button.
|
||||
*
|
||||
|
@ -74,7 +74,7 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTextureNormal(const char* normal, TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Load selected state texture for button.
|
||||
*
|
||||
|
@ -83,7 +83,7 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTexturePressed(const char* selected, TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Load dark state texture for button.
|
||||
*
|
||||
|
@ -92,7 +92,7 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTextureDisabled(const char* disabled, TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Sets capinsets for button, if button is using scale9 renderer.
|
||||
*
|
||||
|
@ -106,67 +106,76 @@ public:
|
|||
* @param capInsets capinsets for button
|
||||
*/
|
||||
void setCapInsetsNormalRenderer(const Rect &capInsets);
|
||||
|
||||
|
||||
const Rect& getCapInsetsNormalRenderer();
|
||||
|
||||
|
||||
/**
|
||||
* Sets capinsets for button, if button is using scale9 renderer.
|
||||
*
|
||||
* @param capInsets capinsets for button
|
||||
*/
|
||||
void setCapInsetsPressedRenderer(const Rect &capInsets);
|
||||
|
||||
|
||||
const Rect& getCapInsetsPressedRenderer();
|
||||
|
||||
|
||||
/**
|
||||
* Sets capinsets for button, if button is using scale9 renderer.
|
||||
*
|
||||
* @param capInsets capinsets for button
|
||||
*/
|
||||
void setCapInsetsDisabledRenderer(const Rect &capInsets);
|
||||
|
||||
|
||||
const Rect& getCapInsetsDisabledRenderer();
|
||||
|
||||
|
||||
//override "setAnchorPoint" of widget.
|
||||
virtual void setAnchorPoint(const Point &pt) override;
|
||||
|
||||
|
||||
/**
|
||||
* Sets if button is using scale9 renderer.
|
||||
*
|
||||
* @param true that using scale9 renderer, false otherwise.
|
||||
*/
|
||||
virtual void setScale9Enabled(bool able);
|
||||
|
||||
|
||||
bool isScale9Enabled();
|
||||
|
||||
//override "setFlipX" of widget.
|
||||
virtual void setFlipX(bool flipX) override;
|
||||
|
||||
//override "setFlipY" of widget.
|
||||
virtual void setFlipY(bool flipY) override;
|
||||
|
||||
//override "isFlipX" of widget.
|
||||
virtual bool isFlipX() override;
|
||||
|
||||
//override "isFlipY" of widget.
|
||||
virtual bool isFlipY() override;
|
||||
|
||||
|
||||
//override "setFlippedX" of widget.
|
||||
virtual void setFlippedX(bool flippedX) override;
|
||||
|
||||
//override "setFlippedY" of widget.
|
||||
virtual void setFlippedY(bool flippedY) override;
|
||||
|
||||
//override "isFlippedX" of widget.
|
||||
virtual bool isFlippedX() override;
|
||||
|
||||
//override "isFlippedY" of widget.
|
||||
virtual bool isFlippedY() override;
|
||||
|
||||
/** @deprecated Use isFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
|
||||
/** @deprecated Use setFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
|
||||
/** @deprecated Use isFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
|
||||
/** @deprecated Use setFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
|
||||
|
||||
/**
|
||||
* Changes if button can be clicked zoom effect.
|
||||
*
|
||||
* @param true that can be clicked zoom effect, false otherwise.
|
||||
*/
|
||||
void setPressedActionEnabled(bool enabled);
|
||||
|
||||
|
||||
//override "ignoreContentAdaptWithSize" method of widget.
|
||||
virtual void ignoreContentAdaptWithSize(bool ignore) override;
|
||||
|
||||
|
||||
//override "getContentSize" method of widget.
|
||||
virtual const Size& getContentSize() const override;
|
||||
|
||||
|
||||
//override "getVirtualRenderer" method of widget.
|
||||
virtual Node* getVirtualRenderer() override;
|
||||
|
||||
|
||||
/**
|
||||
* Sets color to widget
|
||||
*
|
||||
|
@ -175,12 +184,12 @@ public:
|
|||
* @param color
|
||||
*/
|
||||
virtual void setColor(const Color3B &color) override;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the "class name" of widget.
|
||||
*/
|
||||
virtual std::string getDescription() const override;
|
||||
|
||||
|
||||
void setTitleText(const std::string& text);
|
||||
const std::string& getTitleText() const;
|
||||
void setTitleColor(const Color3B& color);
|
||||
|
@ -197,7 +206,7 @@ protected:
|
|||
virtual void onPressStateChangedToPressed() override;
|
||||
virtual void onPressStateChangedToDisabled() override;
|
||||
virtual void onSizeChanged() override;
|
||||
|
||||
|
||||
void normalTextureScaleChangedWithSize();
|
||||
void pressedTextureScaleChangedWithSize();
|
||||
void disabledTextureScaleChangedWithSize();
|
||||
|
|
|
@ -322,30 +322,30 @@ void CheckBox::addEventListenerCheckBox(Ref *target, SEL_SelectedStateEvent sele
|
|||
_checkBoxEventSelector = selector;
|
||||
}
|
||||
|
||||
void CheckBox::setFlipX(bool flipX)
|
||||
void CheckBox::setFlippedX(bool flippedX)
|
||||
{
|
||||
_backGroundBoxRenderer->setFlippedX(flipX);
|
||||
_backGroundSelectedBoxRenderer->setFlippedX(flipX);
|
||||
_frontCrossRenderer->setFlippedX(flipX);
|
||||
_backGroundBoxDisabledRenderer->setFlippedX(flipX);
|
||||
_frontCrossDisabledRenderer->setFlippedX(flipX);
|
||||
_backGroundBoxRenderer->setFlippedX(flippedX);
|
||||
_backGroundSelectedBoxRenderer->setFlippedX(flippedX);
|
||||
_frontCrossRenderer->setFlippedX(flippedX);
|
||||
_backGroundBoxDisabledRenderer->setFlippedX(flippedX);
|
||||
_frontCrossDisabledRenderer->setFlippedX(flippedX);
|
||||
}
|
||||
|
||||
void CheckBox::setFlipY(bool flipY)
|
||||
void CheckBox::setFlippedY(bool flippedY)
|
||||
{
|
||||
_backGroundBoxRenderer->setFlippedY(flipY);
|
||||
_backGroundSelectedBoxRenderer->setFlippedY(flipY);
|
||||
_frontCrossRenderer->setFlippedY(flipY);
|
||||
_backGroundBoxDisabledRenderer->setFlippedY(flipY);
|
||||
_frontCrossDisabledRenderer->setFlippedY(flipY);
|
||||
_backGroundBoxRenderer->setFlippedY(flippedY);
|
||||
_backGroundSelectedBoxRenderer->setFlippedY(flippedY);
|
||||
_frontCrossRenderer->setFlippedY(flippedY);
|
||||
_backGroundBoxDisabledRenderer->setFlippedY(flippedY);
|
||||
_frontCrossDisabledRenderer->setFlippedY(flippedY);
|
||||
}
|
||||
|
||||
bool CheckBox::isFlipX()
|
||||
bool CheckBox::isFlippedX()
|
||||
{
|
||||
return _backGroundBoxRenderer->isFlippedX();
|
||||
}
|
||||
|
||||
bool CheckBox::isFlipY()
|
||||
bool CheckBox::isFlippedY()
|
||||
{
|
||||
return _backGroundBoxRenderer->isFlippedY();
|
||||
}
|
||||
|
|
|
@ -51,17 +51,17 @@ public:
|
|||
* Default constructor
|
||||
*/
|
||||
CheckBox();
|
||||
|
||||
|
||||
/**
|
||||
* Default destructor
|
||||
*/
|
||||
virtual ~CheckBox();
|
||||
|
||||
|
||||
/**
|
||||
* Allocates and initializes.
|
||||
*/
|
||||
static CheckBox* create();
|
||||
|
||||
|
||||
/**
|
||||
* Load textures for checkbox.
|
||||
*
|
||||
|
@ -76,7 +76,7 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTextures(const char* backGround,const char* backGroundSelected,const char* cross,const char* backGroundDisabled,const char* frontCrossDisabled,TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Load backGround texture for checkbox.
|
||||
*
|
||||
|
@ -85,7 +85,7 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTextureBackGround(const char* backGround,TextureResType type = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Load backGroundSelected texture for checkbox.
|
||||
*
|
||||
|
@ -94,7 +94,7 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTextureBackGroundSelected(const char* backGroundSelected,TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Load cross texture for checkbox.
|
||||
*
|
||||
|
@ -103,7 +103,7 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTextureFrontCross(const char* cross,TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Load backGroundDisabled texture for checkbox.
|
||||
*
|
||||
|
@ -112,7 +112,7 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTextureBackGroundDisabled(const char* backGroundDisabled,TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Load frontCrossDisabled texture for checkbox.
|
||||
*
|
||||
|
@ -121,48 +121,57 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTextureFrontCrossDisabled(const char* frontCrossDisabled,TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Sets selcted state for checkbox.
|
||||
*
|
||||
* @param selected true that checkbox is selected, false otherwise.
|
||||
*/
|
||||
void setSelectedState(bool selected);
|
||||
|
||||
|
||||
/**
|
||||
* Gets selcted state of checkbox.
|
||||
*
|
||||
* @return selected true that checkbox is selected, false otherwise.
|
||||
*/
|
||||
bool getSelectedState();
|
||||
|
||||
|
||||
//override "setAnchorPoint" method of widget.
|
||||
virtual void setAnchorPoint(const Point &pt) override;
|
||||
|
||||
|
||||
//add a call back function would called when checkbox is selected or unselected.
|
||||
void addEventListenerCheckBox(Ref* target,SEL_SelectedStateEvent selector);
|
||||
|
||||
//override "setFlipX" method of widget.
|
||||
virtual void setFlipX(bool flipX) override;
|
||||
|
||||
//override "setFlipY" method of widget.
|
||||
virtual void setFlipY(bool flipY) override;
|
||||
|
||||
//override "isFlipX" method of widget.
|
||||
virtual bool isFlipX() override;
|
||||
|
||||
//override "isFlipY" method of widget.
|
||||
virtual bool isFlipY() override;
|
||||
|
||||
|
||||
//override "setFlippedX" method of widget.
|
||||
virtual void setFlippedX(bool flippedX) override;
|
||||
|
||||
//override "setFlippedY" method of widget.
|
||||
virtual void setFlippedY(bool flippedY) override;
|
||||
|
||||
//override "isFlippedX" method of widget.
|
||||
virtual bool isFlippedX() override;
|
||||
|
||||
//override "isFlippedY" method of widget.
|
||||
virtual bool isFlippedY() override;
|
||||
|
||||
/** @deprecated Use isFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
|
||||
/** @deprecated Use setFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
|
||||
/** @deprecated Use isFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
|
||||
/** @deprecated Use setFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
|
||||
|
||||
//override "onTouchEnded" method of widget.
|
||||
virtual void onTouchEnded(Touch *touch, Event *unusedEvent);
|
||||
|
||||
|
||||
//override "getContentSize" method of widget.
|
||||
virtual const Size& getContentSize() const override;
|
||||
|
||||
|
||||
//override "getVirtualRenderer" method of widget.
|
||||
virtual Node* getVirtualRenderer() override;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the "class name" of widget.
|
||||
*/
|
||||
|
@ -194,13 +203,13 @@ protected:
|
|||
|
||||
Ref* _checkBoxEventListener;
|
||||
SEL_SelectedStateEvent _checkBoxEventSelector;
|
||||
|
||||
|
||||
TextureResType _backGroundTexType;
|
||||
TextureResType _backGroundSelectedTexType;
|
||||
TextureResType _frontCrossTexType;
|
||||
TextureResType _backGroundDisabledTexType;
|
||||
TextureResType _frontCrossDisabledTexType;
|
||||
|
||||
|
||||
std::string _backGroundFileName;
|
||||
std::string _backGroundSelectedFileName;
|
||||
std::string _frontCrossFileName;
|
||||
|
|
|
@ -127,29 +127,29 @@ void ImageView::setTextureRect(const Rect &rect)
|
|||
}
|
||||
}
|
||||
|
||||
void ImageView::setFlipX(bool flipX)
|
||||
void ImageView::setFlippedX(bool flippedX)
|
||||
{
|
||||
if (_scale9Enabled)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
STATIC_CAST_CCSPRITE->setFlippedX(flipX);
|
||||
STATIC_CAST_CCSPRITE->setFlippedX(flippedX);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageView::setFlipY(bool flipY)
|
||||
void ImageView::setFlippedY(bool flippedY)
|
||||
{
|
||||
if (_scale9Enabled)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
STATIC_CAST_CCSPRITE->setFlippedY(flipY);
|
||||
STATIC_CAST_CCSPRITE->setFlippedY(flippedY);
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageView::isFlipX()
|
||||
bool ImageView::isFlippedX()
|
||||
{
|
||||
if (_scale9Enabled)
|
||||
{
|
||||
|
@ -161,7 +161,7 @@ bool ImageView::isFlipX()
|
|||
}
|
||||
}
|
||||
|
||||
bool ImageView::isFlipY()
|
||||
bool ImageView::isFlippedY()
|
||||
{
|
||||
if (_scale9Enabled)
|
||||
{
|
||||
|
|
|
@ -42,17 +42,17 @@ public:
|
|||
* Default constructor
|
||||
*/
|
||||
ImageView();
|
||||
|
||||
|
||||
/**
|
||||
* Default destructor
|
||||
*/
|
||||
virtual ~ImageView();
|
||||
|
||||
|
||||
/**
|
||||
* Allocates and initializes.
|
||||
*/
|
||||
static ImageView* create();
|
||||
|
||||
|
||||
/**
|
||||
* Load texture for imageview.
|
||||
*
|
||||
|
@ -61,54 +61,63 @@ public:
|
|||
* @param texType @see UI_TEX_TYPE_LOCAL
|
||||
*/
|
||||
void loadTexture(const char* fileName,TextureResType texType = UI_TEX_TYPE_LOCAL);
|
||||
|
||||
|
||||
/**
|
||||
* Updates the texture rect of the ImageView in points.
|
||||
* It will call setTextureRect:rotated:untrimmedSize with rotated = NO, and utrimmedSize = rect.size.
|
||||
*/
|
||||
void setTextureRect(const Rect& rect);
|
||||
|
||||
|
||||
/**
|
||||
* Sets if imageview is using scale9 renderer.
|
||||
*
|
||||
* @param true that using scale9 renderer, false otherwise.
|
||||
*/
|
||||
void setScale9Enabled(bool able);
|
||||
|
||||
|
||||
bool isScale9Enabled();
|
||||
|
||||
|
||||
/**
|
||||
* Sets capinsets for imageview, if imageview is using scale9 renderer.
|
||||
*
|
||||
* @param capInsets capinsets for imageview
|
||||
*/
|
||||
void setCapInsets(const Rect &capInsets);
|
||||
|
||||
|
||||
const Rect& getCapInsets();
|
||||
|
||||
//override "setFlipX" method of widget.
|
||||
virtual void setFlipX(bool flipX) override;
|
||||
|
||||
//override "setFlipY" method of widget.
|
||||
virtual void setFlipY(bool flipY) override;
|
||||
|
||||
//override "isFlipX" method of widget.
|
||||
virtual bool isFlipX() override;
|
||||
|
||||
//override "isFlipY" method of widget.
|
||||
virtual bool isFlipY() override;
|
||||
|
||||
|
||||
//override "setFlippedX" method of widget.
|
||||
virtual void setFlippedX(bool flippedX) override;
|
||||
|
||||
//override "setFlippedY" method of widget.
|
||||
virtual void setFlippedY(bool flippedY) override;
|
||||
|
||||
//override "isFlippedX" method of widget.
|
||||
virtual bool isFlippedX() override;
|
||||
|
||||
//override "isFlippedY" method of widget.
|
||||
virtual bool isFlippedY() override;
|
||||
|
||||
/** @deprecated Use isFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
|
||||
/** @deprecated Use setFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
|
||||
/** @deprecated Use isFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
|
||||
/** @deprecated Use setFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
|
||||
|
||||
//override "setAnchorPoint" method of widget.
|
||||
virtual void setAnchorPoint(const Point &pt) override;
|
||||
|
||||
|
||||
//override "ignoreContentAdaptWithSize" method of widget.
|
||||
virtual void ignoreContentAdaptWithSize(bool ignore) override;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the "class name" of widget.
|
||||
*/
|
||||
virtual std::string getDescription() const override;
|
||||
|
||||
|
||||
virtual const Size& getContentSize() const override;
|
||||
virtual Node* getVirtualRenderer() override;
|
||||
protected:
|
||||
|
|
|
@ -197,22 +197,22 @@ void Text::onPressStateChangedToDisabled()
|
|||
|
||||
}
|
||||
|
||||
void Text::setFlipX(bool flipX)
|
||||
void Text::setFlippedX(bool flippedX)
|
||||
{
|
||||
_labelRenderer->setFlippedX(flipX);
|
||||
_labelRenderer->setFlippedX(flippedX);
|
||||
}
|
||||
|
||||
void Text::setFlipY(bool flipY)
|
||||
void Text::setFlippedY(bool flippedY)
|
||||
{
|
||||
_labelRenderer->setFlippedY(flipY);
|
||||
_labelRenderer->setFlippedY(flippedY);
|
||||
}
|
||||
|
||||
bool Text::isFlipX()
|
||||
bool Text::isFlippedX()
|
||||
{
|
||||
return _labelRenderer->isFlippedX();
|
||||
}
|
||||
|
||||
bool Text::isFlipY()
|
||||
bool Text::isFlippedY()
|
||||
{
|
||||
return _labelRenderer->isFlippedY();
|
||||
}
|
||||
|
|
|
@ -42,70 +42,70 @@ public:
|
|||
* Default constructor
|
||||
*/
|
||||
Text();
|
||||
|
||||
|
||||
/**
|
||||
* Default destructor
|
||||
*/
|
||||
virtual ~Text();
|
||||
|
||||
|
||||
/**
|
||||
* Allocates and initializes.
|
||||
*/
|
||||
static Text* create();
|
||||
|
||||
|
||||
/**
|
||||
* Changes the string value of label.
|
||||
*
|
||||
* @param text string value.
|
||||
*/
|
||||
void setText(const std::string& text);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the string value of label.
|
||||
*
|
||||
* @return text string value.
|
||||
*/
|
||||
const std::string& getStringValue();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the string length of label.
|
||||
*
|
||||
* @return string length.
|
||||
*/
|
||||
ssize_t getStringLength();
|
||||
|
||||
|
||||
/**
|
||||
* Sets the font size of label.
|
||||
*
|
||||
* @param font size.
|
||||
*/
|
||||
void setFontSize(int size);
|
||||
|
||||
|
||||
int getFontSize();
|
||||
|
||||
|
||||
/**
|
||||
* Sets the font name of label.
|
||||
*
|
||||
* @param font name.
|
||||
*/
|
||||
void setFontName(const std::string& name);
|
||||
|
||||
|
||||
const std::string& getFontName();
|
||||
|
||||
|
||||
/**
|
||||
* Sets the touch scale enabled of label.
|
||||
*
|
||||
* @param touch scale enabled of label.
|
||||
*/
|
||||
void setTouchScaleChangeEnabled(bool enabled);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the touch scale enabled of label.
|
||||
*
|
||||
* @return touch scale enabled of label.
|
||||
*/
|
||||
bool isTouchScaleChangeEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Changes both X and Y scale factor of the widget.
|
||||
*
|
||||
|
@ -114,7 +114,7 @@ public:
|
|||
* @param scale The scale factor for both X and Y axis.
|
||||
*/
|
||||
virtual void setScale(float fScale) override;
|
||||
|
||||
|
||||
/**
|
||||
* Changes the scale factor on X axis of this widget
|
||||
*
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
* @param fScaleX The scale factor on X axis.
|
||||
*/
|
||||
virtual void setScaleX(float fScaleX) override;
|
||||
|
||||
|
||||
/**
|
||||
* Changes the scale factor on Y axis of this widget
|
||||
*
|
||||
|
@ -132,46 +132,55 @@ public:
|
|||
* @param fScaleY The scale factor on Y axis.
|
||||
*/
|
||||
virtual void setScaleY(float fScaleY) override;
|
||||
|
||||
|
||||
//override "setFlipX" method of widget.
|
||||
virtual void setFlipX(bool flipX) override;
|
||||
|
||||
//override "setFlipY" method of widget.
|
||||
virtual void setFlipY(bool flipY) override;
|
||||
|
||||
//override "isFlipX" method of widget.
|
||||
virtual bool isFlipX() override;
|
||||
|
||||
//override "isFlipY" method of widget.
|
||||
virtual bool isFlipY() override;
|
||||
|
||||
|
||||
//override "setFlippedX" method of widget.
|
||||
virtual void setFlippedX(bool flippedX) override;
|
||||
|
||||
//override "setFlippedY" method of widget.
|
||||
virtual void setFlippedY(bool flippedY) override;
|
||||
|
||||
//override "isFlippedX" method of widget.
|
||||
virtual bool isFlippedX() override;
|
||||
|
||||
//override "isFlippedY" method of widget.
|
||||
virtual bool isFlippedY() override;
|
||||
|
||||
/** @deprecated Use isFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
|
||||
/** @deprecated Use setFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
|
||||
/** @deprecated Use isFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
|
||||
/** @deprecated Use setFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
|
||||
|
||||
//override "setAnchorPoint" method of widget.
|
||||
virtual void setAnchorPoint(const Point &pt) override;
|
||||
|
||||
|
||||
//override "getContentSize" method of widget.
|
||||
virtual const Size& getContentSize() const override;
|
||||
|
||||
|
||||
//override "getVirtualRenderer" method of widget.
|
||||
virtual Node* getVirtualRenderer() override;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the "class name" of widget.
|
||||
*/
|
||||
virtual std::string getDescription() const override;
|
||||
|
||||
|
||||
void setTextAreaSize(const Size &size);
|
||||
|
||||
|
||||
const Size& getTextAreaSize();
|
||||
|
||||
|
||||
void setTextHorizontalAlignment(TextHAlignment alignment);
|
||||
|
||||
|
||||
TextHAlignment getTextHorizontalAlignment();
|
||||
|
||||
|
||||
void setTextVerticalAlignment(TextVAlignment alignment);
|
||||
|
||||
|
||||
TextVAlignment getTextVerticalAlignment();
|
||||
|
||||
|
||||
protected:
|
||||
virtual bool init() override;
|
||||
virtual void initRenderer() override;
|
||||
|
|
|
@ -29,7 +29,7 @@ THE SOFTWARE.
|
|||
NS_CC_BEGIN
|
||||
|
||||
namespace ui {
|
||||
|
||||
|
||||
Widget::Widget():
|
||||
_enabled(true),
|
||||
_bright(true),
|
||||
|
@ -57,7 +57,7 @@ _reorderWidgetChildDirty(true),
|
|||
_hitted(false),
|
||||
_touchListener(nullptr)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
Widget::~Widget()
|
||||
|
@ -107,13 +107,13 @@ void Widget::onExit()
|
|||
unscheduleUpdate();
|
||||
Node::onExit();
|
||||
}
|
||||
|
||||
|
||||
void Widget::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
|
||||
{
|
||||
if (_enabled)
|
||||
{
|
||||
Node::visit(renderer, parentTransform, parentTransformUpdated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Widget::addChild(Node *child)
|
||||
|
@ -125,14 +125,14 @@ void Widget::addChild(Node * child, int zOrder)
|
|||
{
|
||||
Node::addChild(child, zOrder);
|
||||
}
|
||||
|
||||
|
||||
void Widget::addChild(Node* child, int zOrder, int tag)
|
||||
{
|
||||
CCASSERT(dynamic_cast<Widget*>(child) != nullptr, "Widget only supports Widgets as children");
|
||||
Node::addChild(child, zOrder, tag);
|
||||
_widgetChildren.pushBack(child);
|
||||
}
|
||||
|
||||
|
||||
void Widget::sortAllChildren()
|
||||
{
|
||||
_reorderWidgetChildDirty = _reorderChildDirty;
|
||||
|
@ -143,11 +143,11 @@ void Widget::sortAllChildren()
|
|||
_reorderWidgetChildDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Node* Widget::getChildByTag(int aTag)
|
||||
{
|
||||
CCASSERT( aTag != Node::INVALID_TAG, "Invalid tag");
|
||||
|
||||
|
||||
for (auto& child : _widgetChildren)
|
||||
{
|
||||
if(child && child->getTag() == aTag)
|
||||
|
@ -160,12 +160,12 @@ Vector<Node*>& Widget::getChildren()
|
|||
{
|
||||
return _widgetChildren;
|
||||
}
|
||||
|
||||
|
||||
const Vector<Node*>& Widget::getChildren() const
|
||||
{
|
||||
return _widgetChildren;
|
||||
}
|
||||
|
||||
|
||||
ssize_t Widget::getChildrenCount() const
|
||||
{
|
||||
return _widgetChildren.size();
|
||||
|
@ -175,7 +175,7 @@ Widget* Widget::getWidgetParent()
|
|||
{
|
||||
return dynamic_cast<Widget*>(getParent());
|
||||
}
|
||||
|
||||
|
||||
void Widget::removeFromParent()
|
||||
{
|
||||
removeFromParentAndCleanup(true);
|
||||
|
@ -195,9 +195,9 @@ void Widget::removeChild(Node *child, bool cleanup)
|
|||
void Widget::removeChildByTag(int tag, bool cleanup)
|
||||
{
|
||||
CCASSERT( tag != Node::INVALID_TAG, "Invalid tag");
|
||||
|
||||
|
||||
Node *child = getChildByTag(tag);
|
||||
|
||||
|
||||
if (child == nullptr)
|
||||
{
|
||||
CCLOG("cocos2d: removeChildByTag(tag = %d): child not found!", tag);
|
||||
|
@ -212,7 +212,7 @@ void Widget::removeAllChildren()
|
|||
{
|
||||
removeAllChildrenWithCleanup(true);
|
||||
}
|
||||
|
||||
|
||||
void Widget::removeAllChildrenWithCleanup(bool cleanup)
|
||||
{
|
||||
for (auto& child : _widgetChildren)
|
||||
|
@ -252,7 +252,7 @@ Widget* Widget::getChildByName(const char *name)
|
|||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void Widget::addNode(Node* node)
|
||||
{
|
||||
addNode(node, node->getLocalZOrder(), node->getTag());
|
||||
|
@ -273,7 +273,7 @@ void Widget::addNode(Node* node, int zOrder, int tag)
|
|||
Node* Widget::getNodeByTag(int tag)
|
||||
{
|
||||
CCAssert( tag != Node::INVALID_TAG, "Invalid tag");
|
||||
|
||||
|
||||
for (auto& node : _nodes)
|
||||
{
|
||||
if(node && node->getTag() == tag)
|
||||
|
@ -296,9 +296,9 @@ void Widget::removeNode(Node* node)
|
|||
void Widget::removeNodeByTag(int tag)
|
||||
{
|
||||
CCAssert( tag != Node::INVALID_TAG, "Invalid tag");
|
||||
|
||||
|
||||
Node *node = this->getNodeByTag(tag);
|
||||
|
||||
|
||||
if (node == nullptr)
|
||||
{
|
||||
CCLOG("cocos2d: removeNodeByTag(tag = %d): child not found!", tag);
|
||||
|
@ -688,22 +688,22 @@ void Widget::setBrightStyle(BrightStyle style)
|
|||
|
||||
void Widget::onPressStateChangedToNormal()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Widget::onPressStateChangedToPressed()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Widget::onPressStateChangedToDisabled()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Widget::didNotSelectSelf()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool Widget::onTouchBegan(Touch *touch, Event *unusedEvent)
|
||||
|
@ -837,13 +837,13 @@ bool Widget::clippingParentAreaContainPoint(const Point &pt)
|
|||
}
|
||||
parent = parent->getWidgetParent();
|
||||
}
|
||||
|
||||
|
||||
if (!_affectByClipping)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (clippingParent)
|
||||
{
|
||||
bool bRet = false;
|
||||
|
@ -1020,7 +1020,7 @@ Widget* Widget::createCloneInstance()
|
|||
void Widget::copyClonedWidgetChildren(Widget* model)
|
||||
{
|
||||
auto& modelChildren = model->getChildren();
|
||||
|
||||
|
||||
for (auto& subWidget : modelChildren)
|
||||
{
|
||||
Widget* child = static_cast<Widget*>(subWidget);
|
||||
|
@ -1030,7 +1030,7 @@ void Widget::copyClonedWidgetChildren(Widget* model)
|
|||
|
||||
void Widget::copySpecialProperties(Widget* model)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Widget::copyProperties(Widget *widget)
|
||||
|
@ -1059,8 +1059,8 @@ void Widget::copyProperties(Widget *widget)
|
|||
setRotation(widget->getRotation());
|
||||
setRotationX(widget->getRotationX());
|
||||
setRotationY(widget->getRotationY());
|
||||
setFlipX(widget->isFlipX());
|
||||
setFlipY(widget->isFlipY());
|
||||
setFlippedX(widget->isFlippedX());
|
||||
setFlippedY(widget->isFlippedY());
|
||||
setColor(widget->getColor());
|
||||
setOpacity(widget->getOpacity());
|
||||
setCascadeOpacityEnabled(widget->isCascadeOpacityEnabled());
|
||||
|
@ -1083,7 +1083,7 @@ int Widget::getActionTag()
|
|||
{
|
||||
return _actionTag;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -80,22 +80,22 @@ typedef void (Ref::*SEL_TouchEvent)(Ref*,TouchEventType);
|
|||
*/
|
||||
class Widget : public Node
|
||||
{
|
||||
public:
|
||||
public:
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
Widget(void);
|
||||
|
||||
|
||||
/**
|
||||
* Default destructor
|
||||
*/
|
||||
virtual ~Widget();
|
||||
|
||||
|
||||
/**
|
||||
* Allocates and initializes a widget.
|
||||
*/
|
||||
static Widget* create();
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether the widget is enabled
|
||||
*
|
||||
|
@ -105,14 +105,14 @@ public:
|
|||
* @param enabled true if the widget is enabled, widget may be touched and visible, false if the widget is disabled, widget cannot be touched and hidden.
|
||||
*/
|
||||
virtual void setEnabled(bool enabled);
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the widget is enabled
|
||||
*
|
||||
* @return true if the widget is enabled, false if the widget is disabled.
|
||||
*/
|
||||
bool isEnabled() const;
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether the widget is bright
|
||||
*
|
||||
|
@ -121,14 +121,14 @@ public:
|
|||
* @param visible true if the widget is bright, false if the widget is dark.
|
||||
*/
|
||||
void setBright(bool bright);
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the widget is bright
|
||||
*
|
||||
* @return true if the widget is bright, false if the widget is dark.
|
||||
*/
|
||||
bool isBright() const;
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether the widget is touch enabled
|
||||
*
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
* @param visible true if the widget is touch enabled, false if the widget is touch disabled.
|
||||
*/
|
||||
virtual void setTouchEnabled(bool enabled);
|
||||
|
||||
|
||||
/**
|
||||
* To set the bright style of widget.
|
||||
*
|
||||
|
@ -146,14 +146,14 @@ public:
|
|||
* @param style BRIGHT_NORMAL the widget is normal state, BRIGHT_HIGHLIGHT the widget is height light state.
|
||||
*/
|
||||
void setBrightStyle(BrightStyle style);
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the widget is touch enabled
|
||||
*
|
||||
* @return true if the widget is touch enabled, false if the widget is touch disabled.
|
||||
*/
|
||||
bool isTouchEnabled() const;
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the widget is on focused
|
||||
*
|
||||
|
@ -169,28 +169,28 @@ public:
|
|||
* @param fucosed true if the widget is on focused, false if the widget is not on focused.
|
||||
*/
|
||||
void setFocused(bool fucosed);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the left boundary position of this widget.
|
||||
*
|
||||
* @return The left boundary position of this widget.
|
||||
*/
|
||||
float getLeftInParent();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the bottom boundary position of this widget.
|
||||
*
|
||||
* @return The bottom boundary position of this widget.
|
||||
*/
|
||||
float getBottomInParent();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the right boundary position of this widget.
|
||||
*
|
||||
* @return The right boundary position of this widget.
|
||||
*/
|
||||
float getRightInParent();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the top boundary position of this widget.
|
||||
*
|
||||
|
@ -233,7 +233,7 @@ public:
|
|||
* @return a Node object whose tag equals to the input parameter
|
||||
*/
|
||||
virtual Node * getChildByTag(int tag) override;
|
||||
|
||||
|
||||
virtual void sortAllChildren() override;
|
||||
/**
|
||||
* Return an array of children
|
||||
|
@ -253,14 +253,14 @@ public:
|
|||
*/
|
||||
virtual Vector<Node*>& getChildren() override;
|
||||
virtual const Vector<Node*>& getChildren() const override;
|
||||
|
||||
|
||||
/**
|
||||
* Get the amount of children.
|
||||
*
|
||||
* @return The amount of children.
|
||||
*/
|
||||
virtual ssize_t getChildrenCount() const override;
|
||||
|
||||
|
||||
/**
|
||||
* Removes this node itself from its parent node with a cleanup.
|
||||
* If the node orphan, then nothing happens.
|
||||
|
@ -275,7 +275,7 @@ public:
|
|||
* @lua removeFromParent
|
||||
*/
|
||||
virtual void removeFromParentAndCleanup(bool cleanup) override;
|
||||
|
||||
|
||||
/**
|
||||
* Removes a child from the container. It will also cleanup all running actions depending on the cleanup parameter.
|
||||
*
|
||||
|
@ -283,7 +283,7 @@ public:
|
|||
* @param cleanup true if all running actions and callbacks on the child node will be cleanup, false otherwise.
|
||||
*/
|
||||
virtual void removeChild(Node* child, bool cleanup = true) override;
|
||||
|
||||
|
||||
/**
|
||||
* Removes a child from the container by tag value. It will also cleanup all running actions depending on the cleanup parameter
|
||||
*
|
||||
|
@ -305,7 +305,7 @@ public:
|
|||
* @lua removeAllChildren
|
||||
*/
|
||||
virtual void removeAllChildrenWithCleanup(bool cleanup) override;
|
||||
|
||||
|
||||
/**
|
||||
* Gets a child from the container with its name
|
||||
*
|
||||
|
@ -314,33 +314,33 @@ public:
|
|||
* @return a Widget object whose name equals to the input parameter
|
||||
*/
|
||||
virtual Widget* getChildByName(const char* name);
|
||||
|
||||
|
||||
virtual void addNode(Node* node);
|
||||
|
||||
|
||||
virtual void addNode(Node * node, int zOrder);
|
||||
|
||||
|
||||
virtual void addNode(Node* node, int zOrder, int tag);
|
||||
|
||||
|
||||
virtual Node * getNodeByTag(int tag);
|
||||
|
||||
|
||||
virtual Vector<Node*>& getNodes();
|
||||
|
||||
|
||||
virtual void removeNode(Node* node);
|
||||
|
||||
|
||||
virtual void removeNodeByTag(int tag);
|
||||
|
||||
|
||||
virtual void removeAllNodes();
|
||||
|
||||
|
||||
virtual void visit(cocos2d::Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the touch event target/selector of the menu item
|
||||
*/
|
||||
void addTouchEventListener(Ref* target,SEL_TouchEvent selector);
|
||||
|
||||
|
||||
|
||||
|
||||
//cocos2d property
|
||||
|
||||
|
||||
/**
|
||||
* Changes the position (x,y) of the widget in OpenGL coordinates
|
||||
*
|
||||
|
@ -350,7 +350,7 @@ public:
|
|||
* @param position The position (x,y) of the widget in OpenGL coordinates
|
||||
*/
|
||||
virtual void setPosition(const Point &pos) override;
|
||||
|
||||
|
||||
/**
|
||||
* Changes the position (x,y) of the widget in OpenGL coordinates
|
||||
*
|
||||
|
@ -360,7 +360,7 @@ public:
|
|||
* @param percent The percent (x,y) of the widget in OpenGL coordinates
|
||||
*/
|
||||
void setPositionPercent(const Point &percent);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the percent (x,y) of the widget in OpenGL coordinates
|
||||
*
|
||||
|
@ -369,7 +369,7 @@ public:
|
|||
* @return The percent (x,y) of the widget in OpenGL coordinates
|
||||
*/
|
||||
const Point& getPositionPercent();
|
||||
|
||||
|
||||
/**
|
||||
* Changes the position type of the widget
|
||||
*
|
||||
|
@ -387,14 +387,14 @@ public:
|
|||
* @return type the position type of widget
|
||||
*/
|
||||
PositionType getPositionType() const;
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether the widget should be flipped horizontally or not.
|
||||
*
|
||||
* @param bFlipX true if the widget should be flipped horizaontally, false otherwise.
|
||||
* @param bFlippedX true if the widget should be flipped horizaontally, false otherwise.
|
||||
*/
|
||||
virtual void setFlipX(bool flipX){};
|
||||
|
||||
virtual void setFlippedX(bool flippedX){};
|
||||
|
||||
/**
|
||||
* Returns the flag which indicates whether the widget is flipped horizontally or not.
|
||||
*
|
||||
|
@ -405,15 +405,15 @@ public:
|
|||
*
|
||||
* @return true if the widget is flipped horizaontally, false otherwise.
|
||||
*/
|
||||
virtual bool isFlipX(){return false;};
|
||||
|
||||
virtual bool isFlippedX(){return false;};
|
||||
|
||||
/**
|
||||
* Sets whether the widget should be flipped vertically or not.
|
||||
*
|
||||
* @param bFlipY true if the widget should be flipped vertically, flase otherwise.
|
||||
* @param bFlippedY true if the widget should be flipped vertically, flase otherwise.
|
||||
*/
|
||||
virtual void setFlipY(bool flipY){};
|
||||
|
||||
virtual void setFlippedY(bool flippedY){};
|
||||
|
||||
/**
|
||||
* Return the flag which indicates whether the widget is flipped vertically or not.
|
||||
*
|
||||
|
@ -424,13 +424,22 @@ public:
|
|||
*
|
||||
* @return true if the widget is flipped vertically, flase otherwise.
|
||||
*/
|
||||
virtual bool isFlipY(){return false;};
|
||||
|
||||
virtual bool isFlippedY(){return false;};
|
||||
|
||||
/** @deprecated Use isFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
|
||||
/** @deprecated Use setFlippedX() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
|
||||
/** @deprecated Use isFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
|
||||
/** @deprecated Use setFlippedY() instead */
|
||||
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
|
||||
|
||||
/**
|
||||
* A call back function when widget lost of focus.
|
||||
*/
|
||||
void didNotSelectSelf();
|
||||
|
||||
|
||||
/*
|
||||
* Checks a point if in parent's area.
|
||||
*
|
||||
|
@ -439,40 +448,40 @@ public:
|
|||
* @return true if the point is in parent's area, flase otherwise.
|
||||
*/
|
||||
bool clippingParentAreaContainPoint(const Point &pt);
|
||||
|
||||
|
||||
/*
|
||||
* Sends the touch event to widget's parent
|
||||
*/
|
||||
virtual void checkChildInfo(int handleState,Widget* sender,const Point &touchPoint);
|
||||
|
||||
|
||||
/*
|
||||
* Gets the touch began point of widget when widget is selected.
|
||||
*
|
||||
* @return the touch began point.
|
||||
*/
|
||||
const Point& getTouchStartPos();
|
||||
|
||||
|
||||
/*
|
||||
* Gets the touch move point of widget when widget is selected.
|
||||
*
|
||||
* @return the touch move point.
|
||||
*/
|
||||
const Point& getTouchMovePos();
|
||||
|
||||
|
||||
/*
|
||||
* Gets the touch end point of widget when widget is selected.
|
||||
*
|
||||
* @return the touch end point.
|
||||
*/
|
||||
const Point& getTouchEndPos();
|
||||
|
||||
|
||||
/**
|
||||
* Changes the name that is used to identify the widget easily.
|
||||
*
|
||||
* @param A const char* that indentifies the widget.
|
||||
*/
|
||||
void setName(const char* name);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a name that is used to identify the widget easily.
|
||||
*
|
||||
|
@ -481,7 +490,7 @@ public:
|
|||
* @return A const char* that identifies the widget.
|
||||
*/
|
||||
const char* getName() const;
|
||||
|
||||
|
||||
/**
|
||||
* Returns a type that is widget's type
|
||||
*
|
||||
|
@ -490,21 +499,21 @@ public:
|
|||
* @return A WidgetType
|
||||
*/
|
||||
WidgetType getWidgetType() const;
|
||||
|
||||
|
||||
/**
|
||||
* Changes the size that is widget's size
|
||||
*
|
||||
* @param size that is widget's size
|
||||
*/
|
||||
virtual void setSize(const Size &size);
|
||||
|
||||
|
||||
/**
|
||||
* Changes the percent that is widget's percent size
|
||||
*
|
||||
* @param percent that is widget's percent size
|
||||
*/
|
||||
virtual void setSizePercent(const Point &percent);
|
||||
|
||||
|
||||
/**
|
||||
* Changes the size type of widget.
|
||||
*
|
||||
|
@ -522,21 +531,21 @@ public:
|
|||
* @param type that is widget's size type
|
||||
*/
|
||||
SizeType getSizeType() const;
|
||||
|
||||
|
||||
/**
|
||||
* Returns size of widget
|
||||
*
|
||||
* @return size
|
||||
*/
|
||||
const Size& getSize() const;
|
||||
|
||||
|
||||
/**
|
||||
* Returns size percent of widget
|
||||
*
|
||||
* @return size percent
|
||||
*/
|
||||
const Point& getSizePercent() const;
|
||||
|
||||
|
||||
/**
|
||||
* Checks a point if is in widget's space
|
||||
*
|
||||
|
@ -545,14 +554,14 @@ public:
|
|||
* @return true if the point is in widget's space, flase otherwise.
|
||||
*/
|
||||
virtual bool hitTest(const Point &pt);
|
||||
|
||||
|
||||
virtual bool onTouchBegan(Touch *touch, Event *unusedEvent);
|
||||
virtual void onTouchMoved(Touch *touch, Event *unusedEvent);
|
||||
virtual void onTouchEnded(Touch *touch, Event *unusedEvent);
|
||||
virtual void onTouchCancelled(Touch *touch, Event *unusedEvent);
|
||||
|
||||
|
||||
/**
|
||||
* Sets a LayoutParameter to widget.
|
||||
* Sets a LayoutParameter to widget.
|
||||
*
|
||||
* @see LayoutParameter
|
||||
*
|
||||
|
@ -561,7 +570,7 @@ public:
|
|||
* @param type Relative or Linear
|
||||
*/
|
||||
void setLayoutParameter(LayoutParameter* parameter);
|
||||
|
||||
|
||||
/**
|
||||
* Gets LayoutParameter of widget.
|
||||
*
|
||||
|
@ -572,21 +581,21 @@ public:
|
|||
* @return LayoutParameter
|
||||
*/
|
||||
LayoutParameter* getLayoutParameter(LayoutParameterType type);
|
||||
|
||||
|
||||
/**
|
||||
* Ignore the widget size
|
||||
*
|
||||
* @param ignore, true that widget will ignore it's size, use texture size, false otherwise. Default value is true.
|
||||
*/
|
||||
virtual void ignoreContentAdaptWithSize(bool ignore);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the widget if is ignore it's size.
|
||||
*
|
||||
* @param ignore, true that widget will ignore it's size, use texture size, false otherwise. Default value is true.
|
||||
*/
|
||||
bool isIgnoreContentAdaptWithSize() const;
|
||||
|
||||
|
||||
/**
|
||||
* Gets world position of widget.
|
||||
*
|
||||
|
@ -602,45 +611,45 @@ public:
|
|||
* @return Node pointer.
|
||||
*/
|
||||
virtual Node* getVirtualRenderer();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the content size of widget.
|
||||
*
|
||||
* Content size is widget's texture size.
|
||||
*/
|
||||
virtual const Size& getContentSize() const;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the "class name" of widget.
|
||||
*/
|
||||
virtual std::string getDescription() const override;
|
||||
|
||||
|
||||
Widget* clone();
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
|
||||
|
||||
void updateSizeAndPosition();
|
||||
|
||||
|
||||
/*temp action*/
|
||||
void setActionTag(int tag);
|
||||
int getActionTag();
|
||||
protected:
|
||||
//call back function called when size changed.
|
||||
virtual void onSizeChanged();
|
||||
|
||||
|
||||
//initializes state of widget.
|
||||
virtual bool init();
|
||||
|
||||
|
||||
//initializes renderer of widget.
|
||||
virtual void initRenderer();
|
||||
|
||||
|
||||
//call back function called widget's state changed to normal.
|
||||
virtual void onPressStateChangedToNormal();
|
||||
|
||||
|
||||
//call back function called widget's state changed to selected.
|
||||
virtual void onPressStateChangedToPressed();
|
||||
|
||||
|
||||
//call back function called widget's state changed to dark.
|
||||
virtual void onPressStateChangedToDisabled();
|
||||
void pushDownEvent();
|
||||
|
|
|
@ -10,11 +10,12 @@ SET(KAZMATH_SOURCES
|
|||
utility.c
|
||||
aabb.c
|
||||
ray2.c
|
||||
ray3.c
|
||||
GL/mat4stack.c
|
||||
GL/matrix.c
|
||||
)
|
||||
|
||||
ADD_SUBDIRECTORY(src)
|
||||
ADD_SUBDIRECTORY(kazmath)
|
||||
|
||||
set_target_properties(kazmath
|
||||
PROPERTIES
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MAT3_H_INCLUDED
|
||||
#define MAT3_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
struct kmQuaternion;
|
||||
|
||||
typedef struct kmMat3{
|
||||
kmScalar mat[9];
|
||||
} kmMat3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CC_DLL kmMat3* const kmMat3Fill(kmMat3* pOut, const kmScalar* pMat);
|
||||
CC_DLL kmMat3* const kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn);
|
||||
CC_DLL kmMat3* const kmMat3Identity(kmMat3* pOut);
|
||||
CC_DLL kmMat3* const kmMat3Inverse(kmMat3* pOut, const kmScalar pDeterminate, const kmMat3* pM);
|
||||
CC_DLL const int kmMat3IsIdentity(const kmMat3* pIn);
|
||||
CC_DLL kmMat3* const kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn);
|
||||
CC_DLL const kmScalar kmMat3Determinant(const kmMat3* pIn);
|
||||
CC_DLL kmMat3* const kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2);
|
||||
CC_DLL kmMat3* const kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
CC_DLL struct kmVec3* const kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3Assign(kmMat3* pOut, const kmMat3* pIn);
|
||||
CC_DLL const int kmMat3AreEqual(const kmMat3* pM1, const kmMat3* pM2);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3RotationX(kmMat3* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat3* const kmMat3RotationY(kmMat3* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat3* const kmMat3RotationZ(kmMat3* pOut, const kmScalar radians);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3Rotation(kmMat3* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat3* const kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y);
|
||||
CC_DLL kmMat3* const kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3RotationQuaternion(kmMat3* pOut, const struct kmQuaternion* pIn);
|
||||
CC_DLL kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
CC_DLL struct kmVec3* const kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // MAT3_H_INCLUDED
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAT4_H_INCLUDED
|
||||
#define MAT4_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
struct kmMat3;
|
||||
struct kmQuaternion;
|
||||
struct kmPlane;
|
||||
|
||||
/*
|
||||
A 4x4 matrix
|
||||
|
||||
| 0 4 8 12 |
|
||||
mat = | 1 5 9 13 |
|
||||
| 2 6 10 14 |
|
||||
| 3 7 11 15 |
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct kmMat4 {
|
||||
kmScalar mat[16];
|
||||
} kmMat4;
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Fill(kmMat4* pOut, const kmScalar* pMat);
|
||||
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Identity(kmMat4* pOut);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Inverse(kmMat4* pOut, const kmMat4* pM);
|
||||
|
||||
|
||||
CC_DLL const int kmMat4IsIdentity(const kmMat4* pIn);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn);
|
||||
CC_DLL kmMat4* const kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Assign(kmMat4* pOut, const kmMat4* pIn);
|
||||
CC_DLL const int kmMat4AreEqual(const kmMat4* pM1, const kmMat4* pM2);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4RotationX(kmMat4* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat4* const kmMat4RotationY(kmMat4* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat4* const kmMat4RotationZ(kmMat4* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat4* const kmMat4RotationPitchYawRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll);
|
||||
CC_DLL kmMat4* const kmMat4RotationQuaternion(kmMat4* pOut, const struct kmQuaternion* pQ);
|
||||
CC_DLL kmMat4* const kmMat4RotationTranslation(kmMat4* pOut, const struct kmMat3* rotation, const struct kmVec3* translation);
|
||||
CC_DLL kmMat4* const kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
|
||||
CC_DLL kmMat4* const kmMat4Translation(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
|
||||
|
||||
CC_DLL struct kmVec3* const kmMat4GetUpVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmVec3* const kmMat4GetRightVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmVec3* const kmMat4GetForwardVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, kmScalar aspect, kmScalar zNear, kmScalar zFar);
|
||||
CC_DLL kmMat4* const kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, kmScalar right, kmScalar bottom, kmScalar top, kmScalar nearVal, kmScalar farVal);
|
||||
CC_DLL kmMat4* const kmMat4LookAt(kmMat4* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
CC_DLL struct kmMat3* const kmMat4ExtractRotation(struct kmMat3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmPlane* const kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane);
|
||||
CC_DLL struct kmVec3* const kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* MAT4_H_INCLUDED */
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
#ADD_LIBRARY(Kazmath STATIC ${KAZMATH_SRCS})
|
||||
#INSTALL(TARGETS Kazmath ARCHIVE DESTINATION lib)
|
||||
FIND_PACKAGE(Threads REQUIRED)
|
||||
ADD_LIBRARY(kazmath SHARED ${KAZMATH_SOURCES})
|
||||
TARGET_LINK_LIBRARIES(kazmath ${CMAKE_THREAD_LIBS_INIT})
|
||||
SET_TARGET_PROPERTIES(kazmath
|
||||
PROPERTIES
|
||||
VERSION 0.0.1
|
||||
SOVERSION 1)
|
||||
INSTALL(TARGETS kazmath DESTINATION lib)
|
||||
|
||||
#ADD_LIBRARY(KazmathGL STATIC ${GL_UTILS_SRCS})
|
||||
#INSTALL(TARGETS KazmathGL ARCHIVE DESTINATION lib)
|
||||
|
||||
INSTALL(FILES ${KAZMATH_HEADERS} DESTINATION include/kazmath)
|
||||
INSTALL(FILES ${GL_UTILS_HEADERS} DESTINATION include/kazmath/GL)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_modules/KAZMATHConfig.cmake DESTINATION ${CMAKE_INSTALL_PREFIX}/share/kazmath)
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "aabb.h"
|
||||
|
||||
|
||||
/**
|
||||
Initializes the AABB around a central point. If centre is NULL then the origin
|
||||
is used. Returns pBox.
|
||||
*/
|
||||
kmAABB* kmAABBInitialize(kmAABB* pBox, const kmVec3* centre, const kmScalar width, const kmScalar height, const kmScalar depth) {
|
||||
if(!pBox) return 0;
|
||||
|
||||
kmVec3 origin;
|
||||
kmVec3* point = centre ? (kmVec3*) centre : &origin;
|
||||
kmVec3Zero(&origin);
|
||||
|
||||
pBox->min.x = point->x - (width / 2);
|
||||
pBox->min.y = point->y - (height / 2);
|
||||
pBox->min.z = point->z - (depth / 2);
|
||||
|
||||
pBox->max.x = point->x + (width / 2);
|
||||
pBox->max.y = point->y + (height / 2);
|
||||
pBox->max.z = point->z + (depth / 2);
|
||||
|
||||
return pBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if point is in the specified AABB, returns
|
||||
* KM_FALSE otherwise.
|
||||
*/
|
||||
int kmAABBContainsPoint(const kmAABB* pBox, const kmVec3* pPoint)
|
||||
{
|
||||
if(pPoint->x >= pBox->min.x && pPoint->x <= pBox->max.x &&
|
||||
pPoint->y >= pBox->min.y && pPoint->y <= pBox->max.y &&
|
||||
pPoint->z >= pBox->min.z && pPoint->z <= pBox->max.z) {
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut, returns pOut.
|
||||
*/
|
||||
kmAABB* kmAABBAssign(kmAABB* pOut, const kmAABB* pIn)
|
||||
{
|
||||
kmVec3Assign(&pOut->min, &pIn->min);
|
||||
kmVec3Assign(&pOut->max, &pIn->max);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales pIn by s, stores the resulting AABB in pOut. Returns pOut
|
||||
*/
|
||||
kmAABB* kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmBool kmAABBIntersectsTriangle(kmAABB* box, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3) {
|
||||
assert(0 && "Not implemented");
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
kmEnum kmAABBContainsAABB(const kmAABB* container, const kmAABB* to_check) {
|
||||
kmVec3 corners[8];
|
||||
kmEnum result = KM_CONTAINS_ALL;
|
||||
kmBool found = KM_FALSE;
|
||||
|
||||
kmVec3Fill(&corners[0], to_check->min.x, to_check->min.y, to_check->min.z);
|
||||
kmVec3Fill(&corners[1], to_check->max.x, to_check->min.y, to_check->min.z);
|
||||
kmVec3Fill(&corners[2], to_check->max.x, to_check->max.y, to_check->min.z);
|
||||
kmVec3Fill(&corners[3], to_check->min.x, to_check->max.y, to_check->min.z);
|
||||
kmVec3Fill(&corners[4], to_check->min.x, to_check->min.y, to_check->max.z);
|
||||
kmVec3Fill(&corners[5], to_check->max.x, to_check->min.y, to_check->max.z);
|
||||
kmVec3Fill(&corners[6], to_check->max.x, to_check->max.y, to_check->max.z);
|
||||
kmVec3Fill(&corners[7], to_check->min.x, to_check->max.y, to_check->max.z);
|
||||
|
||||
kmUchar i;
|
||||
for(i = 0; i < 8; ++i) {
|
||||
if(!kmAABBContainsPoint(container, &corners[i])) {
|
||||
result = KM_CONTAINS_PARTIAL;
|
||||
if(found) {
|
||||
//If we previously found a corner that was within the container
|
||||
//We know that partial is the final result
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
found = KM_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
result = KM_CONTAINS_NONE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
kmScalar kmAABBDiameterX(const kmAABB* aabb) {
|
||||
return fabs(aabb->max.x - aabb->min.x);
|
||||
}
|
||||
|
||||
kmScalar kmAABBDiameterY(const kmAABB* aabb) {
|
||||
return fabs(aabb->max.y - aabb->min.y);
|
||||
}
|
||||
|
||||
kmScalar kmAABBDiameterZ(const kmAABB* aabb) {
|
||||
return fabs(aabb->max.z - aabb->min.z);
|
||||
}
|
||||
|
||||
kmVec3* kmAABBCentre(const kmAABB* aabb, kmVec3* pOut) {
|
||||
kmVec3Add(pOut, &aabb->min, &aabb->max);
|
||||
kmVec3Scale(pOut, pOut, 0.5);
|
||||
return pOut;
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define KAZMATH_AABB_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
|
||||
#include "vec3.h"
|
||||
#include "utility.h"
|
||||
|
||||
|
@ -35,7 +36,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* A structure that represents an axis-aligned
|
||||
* A struture that represents an axis-aligned
|
||||
* bounding box.
|
||||
*/
|
||||
typedef struct kmAABB {
|
||||
|
@ -43,9 +44,17 @@ typedef struct kmAABB {
|
|||
kmVec3 max; /** The min corner of the box */
|
||||
} kmAABB;
|
||||
|
||||
CC_DLL const int kmAABBContainsPoint(const kmVec3* pPoint, const kmAABB* pBox);
|
||||
CC_DLL kmAABB* const kmAABBAssign(kmAABB* pOut, const kmAABB* pIn);
|
||||
CC_DLL kmAABB* const kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s);
|
||||
|
||||
CC_DLL kmAABB* kmAABBInitialize(kmAABB* pBox, const kmVec3* centre, const kmScalar width, const kmScalar height, const kmScalar depth);
|
||||
CC_DLL int kmAABBContainsPoint(const kmAABB* pBox, const kmVec3* pPoint);
|
||||
CC_DLL kmAABB* kmAABBAssign(kmAABB* pOut, const kmAABB* pIn);
|
||||
CC_DLL kmAABB* kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s);
|
||||
CC_DLL kmBool kmAABBIntersectsTriangle(kmAABB* box, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3);
|
||||
CC_DLL kmEnum kmAABBContainsAABB(const kmAABB* container, const kmAABB* to_check);
|
||||
CC_DLL kmScalar kmAABBDiameterX(const kmAABB* aabb);
|
||||
CC_DLL kmScalar kmAABBDiameterY(const kmAABB* aabb);
|
||||
CC_DLL kmScalar kmAABBDiameterZ(const kmAABB* aabb);
|
||||
CC_DLL kmVec3* kmAABBCentre(const kmAABB* aabb, kmVec3* pOut);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "vec2.h"
|
||||
#include "vec3.h"
|
||||
#include "vec4.h"
|
||||
#include "mat3.h"
|
||||
#include "mat4.h"
|
||||
#include "utility.h"
|
||||
|
@ -36,5 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "plane.h"
|
||||
#include "aabb.h"
|
||||
#include "ray2.h"
|
||||
#include "ray3.h"
|
||||
|
||||
#endif // KAZMATH_H_INCLUDED
|
|
@ -0,0 +1,458 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "utility.h"
|
||||
#include "vec3.h"
|
||||
#include "mat3.h"
|
||||
#include "mat4.h"
|
||||
#include "quaternion.h"
|
||||
|
||||
kmMat3* kmMat3Fill(kmMat3* pOut, const kmScalar* pMat)
|
||||
{
|
||||
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 9);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Sets pOut to an identity matrix returns pOut*/
|
||||
kmMat3* kmMat3Identity(kmMat3* pOut)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(kmScalar) * 9);
|
||||
pOut->mat[0] = pOut->mat[4] = pOut->mat[8] = 1.0f;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmMat3Determinant(const kmMat3* pIn)
|
||||
{
|
||||
kmScalar output;
|
||||
/*
|
||||
calculating the determinant following the rule of sarus,
|
||||
| 0 3 6 | 0 3 |
|
||||
m = | 1 4 7 | 1 4 |
|
||||
| 2 5 8 | 2 5 |
|
||||
now sum up the products of the diagonals going to the right (i.e. 0,4,8)
|
||||
and substract the products of the other diagonals (i.e. 2,4,6)
|
||||
*/
|
||||
|
||||
output = pIn->mat[0] * pIn->mat[4] * pIn->mat[8] + pIn->mat[1] * pIn->mat[5] * pIn->mat[6] + pIn->mat[2] * pIn->mat[3] * pIn->mat[7];
|
||||
output -= pIn->mat[2] * pIn->mat[4] * pIn->mat[6] + pIn->mat[0] * pIn->mat[5] * pIn->mat[7] + pIn->mat[1] * pIn->mat[3] * pIn->mat[8];
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
kmMat3* kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
pOut->mat[0] = pIn->mat[4] * pIn->mat[8] - pIn->mat[5] * pIn->mat[7];
|
||||
pOut->mat[1] = pIn->mat[2] * pIn->mat[7] - pIn->mat[1] * pIn->mat[8];
|
||||
pOut->mat[2] = pIn->mat[1] * pIn->mat[5] - pIn->mat[2] * pIn->mat[4];
|
||||
pOut->mat[3] = pIn->mat[5] * pIn->mat[6] - pIn->mat[3] * pIn->mat[8];
|
||||
pOut->mat[4] = pIn->mat[0] * pIn->mat[8] - pIn->mat[2] * pIn->mat[6];
|
||||
pOut->mat[5] = pIn->mat[2] * pIn->mat[3] - pIn->mat[0] * pIn->mat[5];
|
||||
pOut->mat[6] = pIn->mat[3] * pIn->mat[7] - pIn->mat[4] * pIn->mat[6];
|
||||
pOut->mat[7] = pIn->mat[1] * pIn->mat[6] - pIn->mat[0] * pIn->mat[7];
|
||||
pOut->mat[8] = pIn->mat[0] * pIn->mat[4] - pIn->mat[1] * pIn->mat[3];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3Inverse(kmMat3* pOut, const kmMat3* pM)
|
||||
{
|
||||
kmScalar determinate = kmMat3Determinant(pM);
|
||||
kmScalar detInv;
|
||||
kmMat3 adjugate;
|
||||
|
||||
if(determinate == 0.0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
detInv = 1.0 / determinate;
|
||||
|
||||
kmMat3Adjugate(&adjugate, pM);
|
||||
kmMat3ScalarMultiply(pOut, &adjugate, detInv);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Returns true if pIn is an identity matrix */
|
||||
int kmMat3IsIdentity(const kmMat3* pIn)
|
||||
{
|
||||
static kmScalar identity [] = { 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f};
|
||||
|
||||
return (memcmp(identity, pIn->mat, sizeof(kmScalar) * 9) == 0);
|
||||
}
|
||||
|
||||
/** Sets pOut to the transpose of pIn, returns pOut */
|
||||
kmMat3* kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
kmScalar temp[9];
|
||||
|
||||
temp[0] = pIn->mat[0];
|
||||
temp[1] = pIn->mat[3];
|
||||
temp[2] = pIn->mat[6];
|
||||
|
||||
temp[3] = pIn->mat[1];
|
||||
temp[4] = pIn->mat[4];
|
||||
temp[5] = pIn->mat[7];
|
||||
|
||||
temp[6] = pIn->mat[2];
|
||||
temp[7] = pIn->mat[5];
|
||||
temp[8] = pIn->mat[8];
|
||||
|
||||
memcpy(&pOut->mat, temp, sizeof(kmScalar)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/* Multiplies pM1 with pM2, stores the result in pOut, returns pOut */
|
||||
kmMat3* kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2)
|
||||
{
|
||||
kmScalar mat[9];
|
||||
|
||||
const kmScalar *m1 = pM1->mat, *m2 = pM2->mat;
|
||||
|
||||
mat[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2];
|
||||
mat[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2];
|
||||
mat[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2];
|
||||
|
||||
mat[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5];
|
||||
mat[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5];
|
||||
mat[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5];
|
||||
|
||||
mat[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8];
|
||||
mat[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8];
|
||||
mat[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8];
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(kmScalar)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor)
|
||||
{
|
||||
kmScalar mat[9];
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 9; i++)
|
||||
{
|
||||
mat[i] = pM->mat[i] * pFactor;
|
||||
}
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(kmScalar)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Assigns the value of pIn to pOut */
|
||||
kmMat3* kmMat3Assign(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
assert(pOut != pIn); //You have tried to self-assign!!
|
||||
|
||||
memcpy(pOut->mat, pIn->mat, sizeof(kmScalar)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3AssignMat4(kmMat3* pOut, const kmMat4* pIn) {
|
||||
pOut->mat[0] = pIn->mat[0];
|
||||
pOut->mat[1] = pIn->mat[1];
|
||||
pOut->mat[2] = pIn->mat[2];
|
||||
|
||||
pOut->mat[3] = pIn->mat[4];
|
||||
pOut->mat[4] = pIn->mat[5];
|
||||
pOut->mat[5] = pIn->mat[6];
|
||||
|
||||
pOut->mat[6] = pIn->mat[8];
|
||||
pOut->mat[7] = pIn->mat[9];
|
||||
pOut->mat[8] = pIn->mat[10];
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Returns true if the 2 matrices are equal (approximately) */
|
||||
int kmMat3AreEqual(const kmMat3* pMat1, const kmMat3* pMat2)
|
||||
{
|
||||
int i;
|
||||
if (pMat1 == pMat2) {
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
|
||||
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/* Rotation around the z axis so everything stays planar in XY */
|
||||
kmMat3* kmMat3Rotation(kmMat3* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 |
|
||||
M = | sin(A) cos(A) 0 |
|
||||
| 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = -sinf(radians);
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Builds a scaling matrix */
|
||||
kmMat3* kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y)
|
||||
{
|
||||
// memset(pOut->mat, 0, sizeof(kmScalar) * 9);
|
||||
kmMat3Identity(pOut);
|
||||
pOut->mat[0] = x;
|
||||
pOut->mat[4] = y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y)
|
||||
{
|
||||
// memset(pOut->mat, 0, sizeof(kmScalar) * 9);
|
||||
kmMat3Identity(pOut);
|
||||
pOut->mat[6] = x;
|
||||
pOut->mat[7] = y;
|
||||
// pOut->mat[8] = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
kmMat3* kmMat3RotationQuaternion(kmMat3* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
if (!pIn || !pOut) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// First row
|
||||
pOut->mat[0] = 1.0f - 2.0f * (pIn->y * pIn->y + pIn->z * pIn->z);
|
||||
pOut->mat[1] = 2.0f * (pIn->x * pIn->y - pIn->w * pIn->z);
|
||||
pOut->mat[2] = 2.0f * (pIn->x * pIn->z + pIn->w * pIn->y);
|
||||
|
||||
// Second row
|
||||
pOut->mat[3] = 2.0f * (pIn->x * pIn->y + pIn->w * pIn->z);
|
||||
pOut->mat[4] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->z * pIn->z);
|
||||
pOut->mat[5] = 2.0f * (pIn->y * pIn->z - pIn->w * pIn->x);
|
||||
|
||||
// Third row
|
||||
pOut->mat[6] = 2.0f * (pIn->x * pIn->z - pIn->w * pIn->y);
|
||||
pOut->mat[7] = 2.0f * (pIn->y * pIn->z + pIn->w * pIn->x);
|
||||
pOut->mat[8] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->y * pIn->y);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians)
|
||||
{
|
||||
kmScalar rcos = cosf(radians);
|
||||
kmScalar rsin = sinf(radians);
|
||||
|
||||
pOut->mat[0] = rcos + axis->x * axis->x * (1 - rcos);
|
||||
pOut->mat[1] = axis->z * rsin + axis->y * axis->x * (1 - rcos);
|
||||
pOut->mat[2] = -axis->y * rsin + axis->z * axis->x * (1 - rcos);
|
||||
|
||||
pOut->mat[3] = -axis->z * rsin + axis->x * axis->y * (1 - rcos);
|
||||
pOut->mat[4] = rcos + axis->y * axis->y * (1 - rcos);
|
||||
pOut->mat[5] = axis->x * rsin + axis->z * axis->y * (1 - rcos);
|
||||
|
||||
pOut->mat[6] = axis->y * rsin + axis->x * axis->z * (1 - rcos);
|
||||
pOut->mat[7] = -axis->x * rsin + axis->y * axis->z * (1 - rcos);
|
||||
pOut->mat[8] = rcos + axis->z * axis->z * (1 - rcos);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat3RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn)
|
||||
{
|
||||
/*Surely not this easy?*/
|
||||
kmQuaternion temp;
|
||||
kmQuaternionRotationMatrix(&temp, pIn);
|
||||
kmQuaternionToAxisAngle(&temp, pAxis, radians);
|
||||
return pAxis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
|
||||
*/
|
||||
kmMat3* kmMat3RotationX(kmMat3* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| 1 0 0 |
|
||||
M = | 0 cos(A) -sin(A) |
|
||||
| 0 sin(A) cos(A) |
|
||||
|
||||
*/
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = 0.0f;
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = sinf(radians);
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = -sinf(radians);
|
||||
pOut->mat[8] = cosf(radians);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix using the rotation around the Y-axis
|
||||
* The result is stored in pOut, pOut is returned.
|
||||
*/
|
||||
kmMat3* kmMat3RotationY(kmMat3* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) 0 sin(A) |
|
||||
M = | 0 1 0 |
|
||||
| -sin(A) 0 cos(A) |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = -sinf(radians);
|
||||
|
||||
pOut->mat[3] = 0.0f;
|
||||
pOut->mat[4] = 1.0f;
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = sinf(radians);
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = cosf(radians);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix around the Z-axis. The resulting
|
||||
* matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat3* kmMat3RotationZ(kmMat3* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 |
|
||||
M = | sin(A) cos(A) 0 |
|
||||
| 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] =-sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = sinf(radians);
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat3GetUpVec3(kmVec3* pOut, const kmMat3* pIn) {
|
||||
pOut->x = pIn->mat[3];
|
||||
pOut->y = pIn->mat[4];
|
||||
pOut->z = pIn->mat[5];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat3GetRightVec3(kmVec3* pOut, const kmMat3* pIn) {
|
||||
pOut->x = pIn->mat[0];
|
||||
pOut->y = pIn->mat[1];
|
||||
pOut->z = pIn->mat[2];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat3GetForwardVec3(kmVec3* pOut, const kmMat3* pIn) {
|
||||
pOut->x = pIn->mat[6];
|
||||
pOut->y = pIn->mat[7];
|
||||
pOut->z = pIn->mat[8];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3LookAt(kmMat3* pOut, const kmVec3* pEye,
|
||||
const kmVec3* pCenter, const kmVec3* pUp)
|
||||
{
|
||||
kmVec3 f, up, s, u;
|
||||
|
||||
kmVec3Subtract(&f, pCenter, pEye);
|
||||
kmVec3Normalize(&f, &f);
|
||||
|
||||
kmVec3Assign(&up, pUp);
|
||||
kmVec3Normalize(&up, &up);
|
||||
|
||||
kmVec3Cross(&s, &f, &up);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmVec3Cross(&u, &s, &f);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
pOut->mat[0] = s.x;
|
||||
pOut->mat[3] = s.y;
|
||||
pOut->mat[6] = s.z;
|
||||
|
||||
pOut->mat[1] = u.x;
|
||||
pOut->mat[4] = u.y;
|
||||
pOut->mat[7] = u.z;
|
||||
|
||||
pOut->mat[2] = -f.x;
|
||||
pOut->mat[5] = -f.y;
|
||||
pOut->mat[8] = -f.z;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef HEADER_8E9D0ABA3C76B989
|
||||
#define HEADER_8E9D0ABA3C76B989
|
||||
|
||||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MAT3_H_INCLUDED
|
||||
#define MAT3_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
struct kmQuaternion;
|
||||
struct kmMat4;
|
||||
|
||||
typedef struct kmMat3{
|
||||
kmScalar mat[9];
|
||||
} kmMat3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CC_DLL kmMat3* kmMat3Fill(kmMat3* pOut, const kmScalar* pMat);
|
||||
CC_DLL kmMat3* kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn);
|
||||
CC_DLL kmMat3* kmMat3Identity(kmMat3* pOut);
|
||||
CC_DLL kmMat3* kmMat3Inverse(kmMat3* pOut, const kmMat3* pM);
|
||||
CC_DLL int kmMat3IsIdentity(const kmMat3* pIn);
|
||||
CC_DLL kmMat3* kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn);
|
||||
CC_DLL kmScalar kmMat3Determinant(const kmMat3* pIn);
|
||||
CC_DLL kmMat3* kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2);
|
||||
CC_DLL kmMat3* kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor);
|
||||
|
||||
CC_DLL kmMat3* kmMat3Assign(kmMat3* pOut, const kmMat3* pIn);
|
||||
CC_DLL kmMat3* kmMat3AssignMat4(kmMat3* pOut, const struct kmMat4* pIn);
|
||||
CC_DLL int kmMat3AreEqual(const kmMat3* pM1, const kmMat3* pM2);
|
||||
|
||||
CC_DLL struct kmVec3* kmMat3GetUpVec3(struct kmVec3* pOut, const kmMat3* pIn);
|
||||
CC_DLL struct kmVec3* kmMat3GetRightVec3(struct kmVec3* pOut, const kmMat3* pIn);
|
||||
CC_DLL struct kmVec3* kmMat3GetForwardVec3(struct kmVec3* pOut, const kmMat3* pIn);
|
||||
|
||||
CC_DLL kmMat3* kmMat3RotationX(kmMat3* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat3* kmMat3RotationY(kmMat3* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat3* kmMat3RotationZ(kmMat3* pOut, const kmScalar radians);
|
||||
|
||||
CC_DLL kmMat3* kmMat3Rotation(kmMat3* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat3* kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y);
|
||||
CC_DLL kmMat3* kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y);
|
||||
|
||||
CC_DLL kmMat3* kmMat3RotationQuaternion(kmMat3* pOut, const struct kmQuaternion* pIn);
|
||||
|
||||
CC_DLL kmMat3* kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
CC_DLL struct kmVec3* kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
|
||||
CC_DLL kmMat3* kmMat3LookAt(kmMat3* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // MAT3_H_INCLUDED
|
||||
|
||||
|
||||
#endif // header guard
|
|
@ -0,0 +1,805 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file mat4.c
|
||||
*/
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "utility.h"
|
||||
#include "vec3.h"
|
||||
#include "mat4.h"
|
||||
#include "mat3.h"
|
||||
#include "quaternion.h"
|
||||
#include "plane.h"
|
||||
#include "neon_matrix_impl.h"
|
||||
|
||||
|
||||
/**
|
||||
* Fills a kmMat4 structure with the values from a 16
|
||||
* element array of kmScalars
|
||||
* @Params pOut - A pointer to the destination matrix
|
||||
* pMat - A 16 element array of kmScalars
|
||||
* @Return Returns pOut so that the call can be nested
|
||||
*/
|
||||
kmMat4* kmMat4Fill(kmMat4* pOut, const kmScalar* pMat)
|
||||
{
|
||||
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 16);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pOut to an identity matrix returns pOut
|
||||
* @Params pOut - A pointer to the matrix to set to identity
|
||||
* @Return Returns pOut so that the call can be nested
|
||||
*/
|
||||
kmMat4* kmMat4Identity(kmMat4* pOut)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(kmScalar) * 16);
|
||||
pOut->mat[0] = pOut->mat[5] = pOut->mat[10] = pOut->mat[15] = 1.0f;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the inverse of pM and stores the result in
|
||||
* pOut.
|
||||
* @Return Returns NULL if there is no inverse, else pOut
|
||||
*/
|
||||
kmMat4* kmMat4Inverse(kmMat4* pOut, const kmMat4* pM) {
|
||||
kmMat4 tmp;
|
||||
double det;
|
||||
int i;
|
||||
|
||||
tmp.mat[0] = pM->mat[5] * pM->mat[10] * pM->mat[15] -
|
||||
pM->mat[5] * pM->mat[11] * pM->mat[14] -
|
||||
pM->mat[9] * pM->mat[6] * pM->mat[15] +
|
||||
pM->mat[9] * pM->mat[7] * pM->mat[14] +
|
||||
pM->mat[13] * pM->mat[6] * pM->mat[11] -
|
||||
pM->mat[13] * pM->mat[7] * pM->mat[10];
|
||||
|
||||
tmp.mat[4] = -pM->mat[4] * pM->mat[10] * pM->mat[15] +
|
||||
pM->mat[4] * pM->mat[11] * pM->mat[14] +
|
||||
pM->mat[8] * pM->mat[6] * pM->mat[15] -
|
||||
pM->mat[8] * pM->mat[7] * pM->mat[14] -
|
||||
pM->mat[12] * pM->mat[6] * pM->mat[11] +
|
||||
pM->mat[12] * pM->mat[7] * pM->mat[10];
|
||||
|
||||
tmp.mat[8] = pM->mat[4] * pM->mat[9] * pM->mat[15] -
|
||||
pM->mat[4] * pM->mat[11] * pM->mat[13] -
|
||||
pM->mat[8] * pM->mat[5] * pM->mat[15] +
|
||||
pM->mat[8] * pM->mat[7] * pM->mat[13] +
|
||||
pM->mat[12] * pM->mat[5] * pM->mat[11] -
|
||||
pM->mat[12] * pM->mat[7] * pM->mat[9];
|
||||
|
||||
tmp.mat[12] = -pM->mat[4] * pM->mat[9] * pM->mat[14] +
|
||||
pM->mat[4] * pM->mat[10] * pM->mat[13] +
|
||||
pM->mat[8] * pM->mat[5] * pM->mat[14] -
|
||||
pM->mat[8] * pM->mat[6] * pM->mat[13] -
|
||||
pM->mat[12] * pM->mat[5] * pM->mat[10] +
|
||||
pM->mat[12] * pM->mat[6] * pM->mat[9];
|
||||
|
||||
tmp.mat[1] = -pM->mat[1] * pM->mat[10] * pM->mat[15] +
|
||||
pM->mat[1] * pM->mat[11] * pM->mat[14] +
|
||||
pM->mat[9] * pM->mat[2] * pM->mat[15] -
|
||||
pM->mat[9] * pM->mat[3] * pM->mat[14] -
|
||||
pM->mat[13] * pM->mat[2] * pM->mat[11] +
|
||||
pM->mat[13] * pM->mat[3] * pM->mat[10];
|
||||
|
||||
tmp.mat[5] = pM->mat[0] * pM->mat[10] * pM->mat[15] -
|
||||
pM->mat[0] * pM->mat[11] * pM->mat[14] -
|
||||
pM->mat[8] * pM->mat[2] * pM->mat[15] +
|
||||
pM->mat[8] * pM->mat[3] * pM->mat[14] +
|
||||
pM->mat[12] * pM->mat[2] * pM->mat[11] -
|
||||
pM->mat[12] * pM->mat[3] * pM->mat[10];
|
||||
|
||||
tmp.mat[9] = -pM->mat[0] * pM->mat[9] * pM->mat[15] +
|
||||
pM->mat[0] * pM->mat[11] * pM->mat[13] +
|
||||
pM->mat[8] * pM->mat[1] * pM->mat[15] -
|
||||
pM->mat[8] * pM->mat[3] * pM->mat[13] -
|
||||
pM->mat[12] * pM->mat[1] * pM->mat[11] +
|
||||
pM->mat[12] * pM->mat[3] * pM->mat[9];
|
||||
|
||||
tmp.mat[13] = pM->mat[0] * pM->mat[9] * pM->mat[14] -
|
||||
pM->mat[0] * pM->mat[10] * pM->mat[13] -
|
||||
pM->mat[8] * pM->mat[1] * pM->mat[14] +
|
||||
pM->mat[8] * pM->mat[2] * pM->mat[13] +
|
||||
pM->mat[12] * pM->mat[1] * pM->mat[10] -
|
||||
pM->mat[12] * pM->mat[2] * pM->mat[9];
|
||||
|
||||
tmp.mat[2] = pM->mat[1] * pM->mat[6] * pM->mat[15] -
|
||||
pM->mat[1] * pM->mat[7] * pM->mat[14] -
|
||||
pM->mat[5] * pM->mat[2] * pM->mat[15] +
|
||||
pM->mat[5] * pM->mat[3] * pM->mat[14] +
|
||||
pM->mat[13] * pM->mat[2] * pM->mat[7] -
|
||||
pM->mat[13] * pM->mat[3] * pM->mat[6];
|
||||
|
||||
tmp.mat[6] = -pM->mat[0] * pM->mat[6] * pM->mat[15] +
|
||||
pM->mat[0] * pM->mat[7] * pM->mat[14] +
|
||||
pM->mat[4] * pM->mat[2] * pM->mat[15] -
|
||||
pM->mat[4] * pM->mat[3] * pM->mat[14] -
|
||||
pM->mat[12] * pM->mat[2] * pM->mat[7] +
|
||||
pM->mat[12] * pM->mat[3] * pM->mat[6];
|
||||
|
||||
tmp.mat[10] = pM->mat[0] * pM->mat[5] * pM->mat[15] -
|
||||
pM->mat[0] * pM->mat[7] * pM->mat[13] -
|
||||
pM->mat[4] * pM->mat[1] * pM->mat[15] +
|
||||
pM->mat[4] * pM->mat[3] * pM->mat[13] +
|
||||
pM->mat[12] * pM->mat[1] * pM->mat[7] -
|
||||
pM->mat[12] * pM->mat[3] * pM->mat[5];
|
||||
|
||||
tmp.mat[14] = -pM->mat[0] * pM->mat[5] * pM->mat[14] +
|
||||
pM->mat[0] * pM->mat[6] * pM->mat[13] +
|
||||
pM->mat[4] * pM->mat[1] * pM->mat[14] -
|
||||
pM->mat[4] * pM->mat[2] * pM->mat[13] -
|
||||
pM->mat[12] * pM->mat[1] * pM->mat[6] +
|
||||
pM->mat[12] * pM->mat[2] * pM->mat[5];
|
||||
|
||||
tmp.mat[3] = -pM->mat[1] * pM->mat[6] * pM->mat[11] +
|
||||
pM->mat[1] * pM->mat[7] * pM->mat[10] +
|
||||
pM->mat[5] * pM->mat[2] * pM->mat[11] -
|
||||
pM->mat[5] * pM->mat[3] * pM->mat[10] -
|
||||
pM->mat[9] * pM->mat[2] * pM->mat[7] +
|
||||
pM->mat[9] * pM->mat[3] * pM->mat[6];
|
||||
|
||||
tmp.mat[7] = pM->mat[0] * pM->mat[6] * pM->mat[11] -
|
||||
pM->mat[0] * pM->mat[7] * pM->mat[10] -
|
||||
pM->mat[4] * pM->mat[2] * pM->mat[11] +
|
||||
pM->mat[4] * pM->mat[3] * pM->mat[10] +
|
||||
pM->mat[8] * pM->mat[2] * pM->mat[7] -
|
||||
pM->mat[8] * pM->mat[3] * pM->mat[6];
|
||||
|
||||
tmp.mat[11] = -pM->mat[0] * pM->mat[5] * pM->mat[11] +
|
||||
pM->mat[0] * pM->mat[7] * pM->mat[9] +
|
||||
pM->mat[4] * pM->mat[1] * pM->mat[11] -
|
||||
pM->mat[4] * pM->mat[3] * pM->mat[9] -
|
||||
pM->mat[8] * pM->mat[1] * pM->mat[7] +
|
||||
pM->mat[8] * pM->mat[3] * pM->mat[5];
|
||||
|
||||
tmp.mat[15] = pM->mat[0] * pM->mat[5] * pM->mat[10] -
|
||||
pM->mat[0] * pM->mat[6] * pM->mat[9] -
|
||||
pM->mat[4] * pM->mat[1] * pM->mat[10] +
|
||||
pM->mat[4] * pM->mat[2] * pM->mat[9] +
|
||||
pM->mat[8] * pM->mat[1] * pM->mat[6] -
|
||||
pM->mat[8] * pM->mat[2] * pM->mat[5];
|
||||
|
||||
det = pM->mat[0] * tmp.mat[0] + pM->mat[1] * tmp.mat[4] + pM->mat[2] * tmp.mat[8] + pM->mat[3] * tmp.mat[12];
|
||||
|
||||
if (det == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
det = 1.0 / det;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
pOut->mat[i] = tmp.mat[i] * det;
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
/**
|
||||
* Returns KM_TRUE if pIn is an identity matrix
|
||||
* KM_FALSE otherwise
|
||||
*/
|
||||
int kmMat4IsIdentity(const kmMat4* pIn)
|
||||
{
|
||||
static kmScalar identity [] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
return (memcmp(identity, pIn->mat, sizeof(kmScalar) * 16) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pOut to the transpose of pIn, returns pOut
|
||||
*/
|
||||
kmMat4* kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn)
|
||||
{
|
||||
int x, z;
|
||||
|
||||
for (z = 0; z < 4; ++z) {
|
||||
for (x = 0; x < 4; ++x) {
|
||||
pOut->mat[(z * 4) + x] = pIn->mat[(x * 4) + z];
|
||||
}
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies pM1 with pM2, stores the result in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2)
|
||||
{
|
||||
#if defined(__ARM_NEON__) && !defined(__arm64__)
|
||||
|
||||
// It is possible to skip the memcpy() since "out" does not overwrite p1 or p2.
|
||||
// otherwise a temp must be needed.
|
||||
float *mat = pOut->mat;
|
||||
|
||||
// Invert column-order with row-order
|
||||
NEON_Matrix4Mul( &pM2->mat[0], &pM1->mat[0], &mat[0] );
|
||||
|
||||
#else
|
||||
|
||||
kmScalar mat[16];
|
||||
|
||||
const kmScalar *m1 = pM1->mat, *m2 = pM2->mat;
|
||||
|
||||
mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
|
||||
mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
|
||||
mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
|
||||
mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
|
||||
|
||||
mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
|
||||
mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
|
||||
mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
|
||||
mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
|
||||
|
||||
mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
|
||||
mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
|
||||
mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
|
||||
mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
|
||||
|
||||
mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
|
||||
mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
|
||||
mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
|
||||
mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
|
||||
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(kmScalar)*16);
|
||||
#endif
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the value of pIn to pOut
|
||||
*/
|
||||
kmMat4* kmMat4Assign(kmMat4* pOut, const kmMat4* pIn)
|
||||
{
|
||||
assert(pOut != pIn && "You have tried to self-assign!!");
|
||||
|
||||
memcpy(pOut->mat, pIn->mat, sizeof(kmScalar)*16);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat4* kmMat4AssignMat3(kmMat4* pOut, const kmMat3* pIn) {
|
||||
kmMat4Identity(pOut);
|
||||
|
||||
pOut->mat[0] = pIn->mat[0];
|
||||
pOut->mat[1] = pIn->mat[1];
|
||||
pOut->mat[2] = pIn->mat[2];
|
||||
pOut->mat[3] = 0.0;
|
||||
|
||||
pOut->mat[4] = pIn->mat[3];
|
||||
pOut->mat[5] = pIn->mat[4];
|
||||
pOut->mat[6] = pIn->mat[5];
|
||||
pOut->mat[7] = 0.0;
|
||||
|
||||
pOut->mat[8] = pIn->mat[6];
|
||||
pOut->mat[9] = pIn->mat[7];
|
||||
pOut->mat[10] = pIn->mat[8];
|
||||
pOut->mat[11] = 0.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if the 2 matrices are equal (approximately)
|
||||
*/
|
||||
int kmMat4AreEqual(const kmMat4* pMat1, const kmMat4* pMat2)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
assert(pMat1 != pMat2 && "You are comparing the same thing!");
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
|
||||
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a rotation matrix from an axis and an angle. Result is stored in pOut.
|
||||
* pOut is returned.
|
||||
*/
|
||||
kmMat4* kmMat4RotationAxisAngle(kmMat4* pOut, const kmVec3* axis, kmScalar radians)
|
||||
{
|
||||
kmQuaternion quat;
|
||||
kmQuaternionRotationAxisAngle(&quat, axis, radians);
|
||||
kmMat4RotationQuaternion(pOut, &quat);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* kmMat4RotationX(kmMat4* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| 1 0 0 0 |
|
||||
M = | 0 cos(A) -sin(A) 0 |
|
||||
| 0 sin(A) cos(A) 0 |
|
||||
| 0 0 0 1 |
|
||||
|
||||
*/
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = 0.0f;
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = 0.0f;
|
||||
pOut->mat[5] = cosf(radians);
|
||||
pOut->mat[6] = sinf(radians);
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = 0.0f;
|
||||
pOut->mat[9] = -sinf(radians);
|
||||
pOut->mat[10] = cosf(radians);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix using the rotation around the Y-axis
|
||||
* The result is stored in pOut, pOut is returned.
|
||||
*/
|
||||
kmMat4* kmMat4RotationY(kmMat4* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) 0 sin(A) 0 |
|
||||
M = | 0 1 0 0 |
|
||||
| -sin(A) 0 cos(A) 0 |
|
||||
| 0 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = -sinf(radians);
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = 0.0f;
|
||||
pOut->mat[5] = 1.0f;
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = sinf(radians);
|
||||
pOut->mat[9] = 0.0f;
|
||||
pOut->mat[10] = cosf(radians);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix around the Z-axis. The resulting
|
||||
* matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat4* kmMat4RotationZ(kmMat4* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 0 |
|
||||
M = | sin(A) cos(A) 0 0 |
|
||||
| 0 0 1 0 |
|
||||
| 0 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = -sinf(radians);
|
||||
pOut->mat[5] = cosf(radians);
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = 0.0f;
|
||||
pOut->mat[9] = 0.0f;
|
||||
pOut->mat[10] = 1.0f;
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix from pitch, yaw and roll. The resulting
|
||||
* matrix is stored in pOut and pOut is returned
|
||||
*/
|
||||
kmMat4* kmMat4RotationYawPitchRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll)
|
||||
{
|
||||
|
||||
kmMat4 yaw_matrix;
|
||||
kmMat4RotationY(&yaw_matrix, yaw);
|
||||
|
||||
kmMat4 pitch_matrix;
|
||||
kmMat4RotationX(&pitch_matrix, pitch);
|
||||
|
||||
kmMat4 roll_matrix;
|
||||
kmMat4RotationZ(&roll_matrix, roll);
|
||||
|
||||
kmMat4Multiply(pOut, &pitch_matrix, &roll_matrix);
|
||||
kmMat4Multiply(pOut, &yaw_matrix, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Converts a quaternion to a rotation matrix,
|
||||
* the result is stored in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* kmMat4RotationQuaternion(kmMat4* pOut, const kmQuaternion* pQ)
|
||||
{
|
||||
double xx = pQ->x * pQ->x;
|
||||
double xy = pQ->x * pQ->y;
|
||||
double xz = pQ->x * pQ->z;
|
||||
double xw = pQ->x * pQ->w;
|
||||
|
||||
double yy = pQ->y * pQ->y;
|
||||
double yz = pQ->y * pQ->z;
|
||||
double yw = pQ->y * pQ->w;
|
||||
|
||||
double zz = pQ->z * pQ->z;
|
||||
double zw = pQ->z * pQ->w;
|
||||
|
||||
pOut->mat[0] = 1 - 2 * (yy + zz);
|
||||
pOut->mat[1] = 2 * (xy + zw);
|
||||
pOut->mat[2] = 2 * (xz - yw);
|
||||
pOut->mat[3] = 0;
|
||||
|
||||
pOut->mat[4] = 2 * (xy - zw);
|
||||
pOut->mat[5] = 1 - 2 * (xx + zz);
|
||||
pOut->mat[6] = 2 * (yz + xw);
|
||||
pOut->mat[7] = 0.0;
|
||||
|
||||
pOut->mat[8] = 2 * (xz + yw);
|
||||
pOut->mat[9] = 2 * (yz - xw);
|
||||
pOut->mat[10] = 1 - 2 * (xx + yy);
|
||||
pOut->mat[11] = 0.0;
|
||||
|
||||
pOut->mat[12] = 0.0;
|
||||
pOut->mat[13] = 0.0;
|
||||
pOut->mat[14] = 0.0;
|
||||
pOut->mat[15] = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Builds a scaling matrix */
|
||||
kmMat4* kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y,
|
||||
kmScalar z)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(kmScalar) * 16);
|
||||
pOut->mat[0] = x;
|
||||
pOut->mat[5] = y;
|
||||
pOut->mat[10] = z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a translation matrix. All other elements in the matrix
|
||||
* will be set to zero except for the diagonal which is set to 1.0
|
||||
*/
|
||||
kmMat4* kmMat4Translation(kmMat4* pOut, const kmScalar x,
|
||||
kmScalar y, const kmScalar z)
|
||||
{
|
||||
//FIXME: Write a test for this
|
||||
memset(pOut->mat, 0, sizeof(kmScalar) * 16);
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[5] = 1.0f;
|
||||
pOut->mat[10] = 1.0f;
|
||||
|
||||
pOut->mat[12] = x;
|
||||
pOut->mat[13] = y;
|
||||
pOut->mat[14] = z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the up vector from a matrix. pIn is the matrix you
|
||||
* wish to extract the vector from. pOut is a pointer to the
|
||||
* kmVec3 structure that should hold the resulting vector
|
||||
*/
|
||||
kmVec3* kmMat4GetUpVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
kmVec3MultiplyMat4(pOut, &KM_VEC3_POS_Y, pIn);
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Extract the right vector from a 4x4 matrix. The result is
|
||||
* stored in pOut. Returns pOut.
|
||||
*/
|
||||
kmVec3* kmMat4GetRightVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
kmVec3MultiplyMat4(pOut, &KM_VEC3_POS_X, pIn);
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the forward vector from a 4x4 matrix. The result is
|
||||
* stored in pOut. Returns pOut.
|
||||
*/
|
||||
kmVec3* kmMat4GetForwardVec3RH(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
kmVec3MultiplyMat4(pOut, &KM_VEC3_NEG_Z, pIn);
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat4GetForwardVec3LH(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
kmVec3MultiplyMat4(pOut, &KM_VEC3_POS_Z, pIn);
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a perspective projection matrix in the
|
||||
* same way as gluPerspective
|
||||
*/
|
||||
kmMat4* kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY,
|
||||
kmScalar aspect, kmScalar zNear,
|
||||
kmScalar zFar)
|
||||
{
|
||||
kmScalar r = kmDegreesToRadians(fovY / 2);
|
||||
kmScalar deltaZ = zFar - zNear;
|
||||
kmScalar s = sin(r);
|
||||
kmScalar cotangent = 0;
|
||||
|
||||
if (deltaZ == 0 || s == 0 || aspect == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//cos(r) / sin(r) = cot(r)
|
||||
cotangent = cos(r) / s;
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
pOut->mat[0] = cotangent / aspect;
|
||||
pOut->mat[5] = cotangent;
|
||||
pOut->mat[10] = -(zFar + zNear) / deltaZ;
|
||||
pOut->mat[11] = -1;
|
||||
pOut->mat[14] = -2 * zNear * zFar / deltaZ;
|
||||
pOut->mat[15] = 0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Creates an orthographic projection matrix like glOrtho */
|
||||
kmMat4* kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left,
|
||||
kmScalar right, kmScalar bottom,
|
||||
kmScalar top, kmScalar nearVal,
|
||||
kmScalar farVal)
|
||||
{
|
||||
kmScalar tx = -((right + left) / (right - left));
|
||||
kmScalar ty = -((top + bottom) / (top - bottom));
|
||||
kmScalar tz = -((farVal + nearVal) / (farVal - nearVal));
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
pOut->mat[0] = 2 / (right - left);
|
||||
pOut->mat[5] = 2 / (top - bottom);
|
||||
pOut->mat[10] = -2 / (farVal - nearVal);
|
||||
pOut->mat[12] = tx;
|
||||
pOut->mat[13] = ty;
|
||||
pOut->mat[14] = tz;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a translation matrix in the same way as gluLookAt()
|
||||
* the resulting matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat4* kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
|
||||
const kmVec3* pCenter, const kmVec3* pUp)
|
||||
{
|
||||
kmVec3 f, up, s, u;
|
||||
kmMat4 translate;
|
||||
|
||||
kmVec3Subtract(&f, pCenter, pEye);
|
||||
kmVec3Normalize(&f, &f);
|
||||
|
||||
kmVec3Assign(&up, pUp);
|
||||
kmVec3Normalize(&up, &up);
|
||||
|
||||
kmVec3Cross(&s, &f, &up);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmVec3Cross(&u, &s, &f);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
|
||||
pOut->mat[0] = s.x;
|
||||
pOut->mat[4] = s.y;
|
||||
pOut->mat[8] = s.z;
|
||||
|
||||
pOut->mat[1] = u.x;
|
||||
pOut->mat[5] = u.y;
|
||||
pOut->mat[9] = u.z;
|
||||
|
||||
pOut->mat[2] = -f.x;
|
||||
pOut->mat[6] = -f.y;
|
||||
pOut->mat[10] = -f.z;
|
||||
|
||||
kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z);
|
||||
kmMat4Multiply(pOut, pOut, &translate);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a 3x3 rotation matrix from the input 4x4 transformation.
|
||||
* Stores the result in pOut, returns pOut
|
||||
*/
|
||||
kmMat3* kmMat4ExtractRotation(kmMat3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->mat[0] = pIn->mat[0];
|
||||
pOut->mat[1] = pIn->mat[1];
|
||||
pOut->mat[2] = pIn->mat[2];
|
||||
|
||||
pOut->mat[3] = pIn->mat[4];
|
||||
pOut->mat[4] = pIn->mat[5];
|
||||
pOut->mat[5] = pIn->mat[6];
|
||||
|
||||
pOut->mat[6] = pIn->mat[8];
|
||||
pOut->mat[7] = pIn->mat[9];
|
||||
pOut->mat[8] = pIn->mat[10];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians)
|
||||
* returns the output axis.
|
||||
*/
|
||||
kmVec3* kmMat4RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn)
|
||||
{
|
||||
/*Surely not this easy?*/
|
||||
kmQuaternion temp;
|
||||
kmMat3 rotation;
|
||||
kmMat4ExtractRotation(&rotation, pIn);
|
||||
kmQuaternionRotationMatrix(&temp, &rotation);
|
||||
kmQuaternionToAxisAngle(&temp, pAxis, radians);
|
||||
return pAxis;
|
||||
}
|
||||
|
||||
/** Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix,
|
||||
* and a 3d vector representing a translation. Assign the result to pOut,
|
||||
* pOut is also returned.
|
||||
*/
|
||||
kmMat4* kmMat4RotationTranslation(kmMat4* pOut, const kmMat3* rotation, const kmVec3* translation)
|
||||
{
|
||||
pOut->mat[0] = rotation->mat[0];
|
||||
pOut->mat[1] = rotation->mat[1];
|
||||
pOut->mat[2] = rotation->mat[2];
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = rotation->mat[3];
|
||||
pOut->mat[5] = rotation->mat[4];
|
||||
pOut->mat[6] = rotation->mat[5];
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = rotation->mat[6];
|
||||
pOut->mat[9] = rotation->mat[7];
|
||||
pOut->mat[10] = rotation->mat[8];
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = translation->x;
|
||||
pOut->mat[13] = translation->y;
|
||||
pOut->mat[14] = translation->z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmMat4ExtractPlane(kmPlane* pOut, const kmMat4* pIn, const kmEnum plane)
|
||||
{
|
||||
kmScalar t = 1.0f;
|
||||
|
||||
switch(plane) {
|
||||
case KM_PLANE_RIGHT:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[0];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[4];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[8];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[12];
|
||||
break;
|
||||
case KM_PLANE_LEFT:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[0];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[4];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[8];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[12];
|
||||
break;
|
||||
case KM_PLANE_BOTTOM:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[1];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[5];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[9];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[13];
|
||||
break;
|
||||
case KM_PLANE_TOP:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[1];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[5];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[9];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[13];
|
||||
break;
|
||||
case KM_PLANE_FAR:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[2];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[6];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[10];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[14];
|
||||
break;
|
||||
case KM_PLANE_NEAR:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[2];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[6];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[10];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[14];
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Invalid plane index");
|
||||
}
|
||||
|
||||
t = sqrtf(pOut->a * pOut->a +
|
||||
pOut->b * pOut->b +
|
||||
pOut->c * pOut->c);
|
||||
pOut->a /= t;
|
||||
pOut->b /= t;
|
||||
pOut->c /= t;
|
||||
pOut->d /= t;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAT4_H_INCLUDED
|
||||
#define MAT4_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
struct kmMat3;
|
||||
struct kmQuaternion;
|
||||
struct kmPlane;
|
||||
|
||||
/*
|
||||
A 4x4 matrix
|
||||
|
||||
| 0 4 8 12 |
|
||||
mat = | 1 5 9 13 |
|
||||
| 2 6 10 14 |
|
||||
| 3 7 11 15 |
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct kmMat4 {
|
||||
kmScalar mat[16];
|
||||
} kmMat4;
|
||||
|
||||
CC_DLL kmMat4* kmMat4Fill(kmMat4* pOut, const kmScalar* pMat);
|
||||
|
||||
|
||||
CC_DLL kmMat4* kmMat4Identity(kmMat4* pOut);
|
||||
|
||||
CC_DLL kmMat4* kmMat4Inverse(kmMat4* pOut, const kmMat4* pM);
|
||||
|
||||
|
||||
CC_DLL int kmMat4IsIdentity(const kmMat4* pIn);
|
||||
|
||||
CC_DLL kmMat4* kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn);
|
||||
CC_DLL kmMat4* kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2);
|
||||
|
||||
CC_DLL kmMat4* kmMat4Assign(kmMat4* pOut, const kmMat4* pIn);
|
||||
CC_DLL kmMat4* kmMat4AssignMat3(kmMat4* pOut, const struct kmMat3* pIn);
|
||||
|
||||
CC_DLL int kmMat4AreEqual(const kmMat4* pM1, const kmMat4* pM2);
|
||||
|
||||
CC_DLL kmMat4* kmMat4RotationX(kmMat4* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat4* kmMat4RotationY(kmMat4* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat4* kmMat4RotationZ(kmMat4* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat4* kmMat4RotationYawPitchRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll);
|
||||
CC_DLL kmMat4* kmMat4RotationQuaternion(kmMat4* pOut, const struct kmQuaternion* pQ);
|
||||
CC_DLL kmMat4* kmMat4RotationTranslation(kmMat4* pOut, const struct kmMat3* rotation, const struct kmVec3* translation);
|
||||
CC_DLL kmMat4* kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
|
||||
CC_DLL kmMat4* kmMat4Translation(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
|
||||
|
||||
CC_DLL struct kmVec3* kmMat4GetUpVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmVec3* kmMat4GetRightVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmVec3* kmMat4GetForwardVec3RH(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmVec3* kmMat4GetForwardVec3LH(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
|
||||
CC_DLL kmMat4* kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, kmScalar aspect, kmScalar zNear, kmScalar zFar);
|
||||
CC_DLL kmMat4* kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, kmScalar right, kmScalar bottom, kmScalar top, kmScalar nearVal, kmScalar farVal);
|
||||
CC_DLL kmMat4* kmMat4LookAt(kmMat4* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
|
||||
|
||||
CC_DLL kmMat4* kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
CC_DLL struct kmMat3* kmMat4ExtractRotation(struct kmMat3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmPlane* kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane);
|
||||
CC_DLL struct kmVec3* kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* MAT4_H_INCLUDED */
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "vec3.h"
|
||||
#include "vec4.h"
|
||||
#include "plane.h"
|
||||
#include "mat4.h"
|
||||
|
||||
kmScalar kmPlaneDot(const kmPlane* pP, const kmVec4* pV)
|
||||
{
|
||||
//a*x + b*y + c*z + d*w
|
||||
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z +
|
||||
pP->d * pV->w);
|
||||
}
|
||||
|
||||
kmScalar kmPlaneDotCoord(const kmPlane* pP, const kmVec3* pV)
|
||||
{
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z + pP->d);
|
||||
}
|
||||
|
||||
kmScalar kmPlaneDotNormal(const kmPlane* pP, const kmVec3* pV)
|
||||
{
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z);
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneFromNormalAndDistance(kmPlane* plane, const struct kmVec3* normal, const kmScalar dist) {
|
||||
plane->a = normal->x;
|
||||
plane->b = normal->y;
|
||||
plane->c = normal->z;
|
||||
plane->d = dist;
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneFromPointAndNormal(kmPlane* pOut, const kmVec3* pPoint, const kmVec3* pNormal)
|
||||
{
|
||||
/*
|
||||
Planea = Nx
|
||||
Planeb = Ny
|
||||
Planec = Nz
|
||||
Planed = −N⋅P
|
||||
*/
|
||||
|
||||
|
||||
pOut->a = pNormal->x;
|
||||
pOut->b = pNormal->y;
|
||||
pOut->c = pNormal->z;
|
||||
pOut->d = -kmVec3Dot(pNormal, pPoint);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a plane from 3 points. The result is stored in pOut.
|
||||
* pOut is returned.
|
||||
*/
|
||||
kmPlane* kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3)
|
||||
{
|
||||
/*
|
||||
v = (B − A) × (C − A)
|
||||
n = 1⁄|v| v
|
||||
Outa = nx
|
||||
Outb = ny
|
||||
Outc = nz
|
||||
Outd = −n⋅A
|
||||
*/
|
||||
|
||||
kmVec3 n, v1, v2;
|
||||
kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle
|
||||
kmVec3Subtract(&v2, p3, p1);
|
||||
kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal
|
||||
|
||||
kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
// Added by tlensing (http://icedcoffee-framework.org)
|
||||
kmVec3* kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
/*
|
||||
n = (Planea, Planeb, Planec)
|
||||
d = V − U
|
||||
Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0]
|
||||
*/
|
||||
kmVec3 d; // direction from V1 to V2
|
||||
kmVec3Subtract(&d, pV2, pV1); // Get the direction vector
|
||||
|
||||
kmVec3 n; // plane normal
|
||||
n.x = pP->a;
|
||||
n.y = pP->b;
|
||||
n.z = pP->c;
|
||||
kmVec3Normalize(&n, &n);
|
||||
|
||||
kmScalar nt = -(n.x * pV1->x + n.y * pV1->y + n.z * pV1->z + pP->d);
|
||||
kmScalar dt = (n.x * d.x + n.y * d.y + n.z * d.z);
|
||||
|
||||
if (fabs(dt) < kmEpsilon) {
|
||||
pOut = NULL;
|
||||
return pOut; // line parallel or contained
|
||||
}
|
||||
|
||||
kmScalar t = nt/dt;
|
||||
pOut->x = pV1->x + d.x * t;
|
||||
pOut->y = pV1->y + d.y * t;
|
||||
pOut->z = pV1->z + d.z * t;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP)
|
||||
{
|
||||
kmVec3 n;
|
||||
kmScalar l = 0;
|
||||
|
||||
if (!pP->a && !pP->b && !pP->c) {
|
||||
pOut->a = pP->a;
|
||||
pOut->b = pP->b;
|
||||
pOut->c = pP->c;
|
||||
pOut->d = pP->d;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
n.x = pP->a;
|
||||
n.y = pP->b;
|
||||
n.z = pP->c;
|
||||
|
||||
l = 1.0f / kmVec3Length(&n); //Get 1/length
|
||||
kmVec3Normalize(&n, &n); //Normalize the vector and assign to pOut
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
|
||||
pOut->d = pP->d * l; //Scale the D value and assign to pOut
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns
|
||||
* POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise
|
||||
*/
|
||||
KM_POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP)
|
||||
{
|
||||
// This function will determine if a point is on, in front of, or behind
|
||||
// the plane. First we store the dot product of the plane and the point.
|
||||
kmScalar distance = pIn->a * pP->x + pIn->b * pP->y + pIn->c * pP->z + pIn->d;
|
||||
|
||||
// Simply put if the dot product is greater than 0 then it is infront of it.
|
||||
// If it is less than 0 then it is behind it. And if it is 0 then it is on it.
|
||||
if(distance > kmEpsilon) return POINT_INFRONT_OF_PLANE;
|
||||
if(distance < -kmEpsilon) return POINT_BEHIND_PLANE;
|
||||
|
||||
return POINT_ON_PLANE;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row) {
|
||||
int scale = (row < 0) ? -1 : 1;
|
||||
row = abs(row) - 1;
|
||||
|
||||
pOut->a = pIn->mat[3] + scale * pIn->mat[row];
|
||||
pOut->b = pIn->mat[7] + scale * pIn->mat[row + 4];
|
||||
pOut->c = pIn->mat[11] + scale * pIn->mat[row + 8];
|
||||
pOut->d = pIn->mat[15] + scale * pIn->mat[row + 12];
|
||||
|
||||
return kmPlaneNormalize(pOut, pOut);
|
||||
}
|
||||
|
||||
kmVec3* kmPlaneGetIntersection(kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3) {
|
||||
kmVec3 n1, n2, n3, cross;
|
||||
kmVec3 r1, r2, r3;
|
||||
double denom = 0;
|
||||
|
||||
kmVec3Fill(&n1, p1->a, p1->b, p1->c);
|
||||
kmVec3Fill(&n2, p2->a, p2->b, p2->c);
|
||||
kmVec3Fill(&n3, p3->a, p3->b, p3->c);
|
||||
|
||||
kmVec3Cross(&cross, &n2, &n3);
|
||||
|
||||
denom = kmVec3Dot(&n1, &cross);
|
||||
|
||||
if (kmAlmostEqual(denom, 0.0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmVec3Cross(&r1, &n2, &n3);
|
||||
kmVec3Cross(&r2, &n3, &n1);
|
||||
kmVec3Cross(&r3, &n1, &n2);
|
||||
|
||||
kmVec3Scale(&r1, &r1, -p1->d);
|
||||
kmVec3Scale(&r2, &r2, p2->d);
|
||||
kmVec3Scale(&r3, &r3, p3->d);
|
||||
|
||||
kmVec3Subtract(pOut, &r1, &r2);
|
||||
kmVec3Subtract(pOut, pOut, &r3);
|
||||
kmVec3Scale(pOut, pOut, 1.0 / denom);
|
||||
|
||||
//p = -d1 * ( n2.Cross ( n3 ) ) – d2 * ( n3.Cross ( n1 ) ) – d3 * ( n1.Cross ( n2 ) ) / denom;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneFill(kmPlane* plane, kmScalar a, kmScalar b, kmScalar c, kmScalar d) {
|
||||
plane->a = a;
|
||||
plane->b = b;
|
||||
plane->c = c;
|
||||
plane->d = d;
|
||||
|
||||
return plane;
|
||||
}
|
|
@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define KM_PLANE_FAR 5
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
|
@ -41,28 +42,33 @@ struct kmVec4;
|
|||
struct kmMat4;
|
||||
|
||||
typedef struct kmPlane {
|
||||
kmScalar a, b, c, d;
|
||||
kmScalar a, b, c, d;
|
||||
} kmPlane;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum POINT_CLASSIFICATION {
|
||||
POINT_INFRONT_OF_PLANE = 0,
|
||||
POINT_BEHIND_PLANE,
|
||||
POINT_ON_PLANE,
|
||||
} POINT_CLASSIFICATION;
|
||||
typedef enum KM_POINT_CLASSIFICATION {
|
||||
POINT_BEHIND_PLANE = -1,
|
||||
POINT_ON_PLANE = 0,
|
||||
POINT_INFRONT_OF_PLANE = 1
|
||||
} KM_POINT_CLASSIFICATION;
|
||||
|
||||
CC_DLL const kmScalar kmPlaneDot(const kmPlane* pP, const struct kmVec4* pV);
|
||||
CC_DLL const kmScalar kmPlaneDotCoord(const kmPlane* pP, const struct kmVec3* pV);
|
||||
CC_DLL const kmScalar kmPlaneDotNormal(const kmPlane* pP, const struct kmVec3* pV);
|
||||
CC_DLL kmPlane* const kmPlaneFromPointNormal(kmPlane* pOut, const struct kmVec3* pPoint, const struct kmVec3* pNormal);
|
||||
CC_DLL kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const struct kmVec3* p1, const struct kmVec3* p2, const struct kmVec3* p3);
|
||||
CC_DLL kmVec3* const kmPlaneIntersectLine(struct kmVec3* pOut, const kmPlane* pP, const struct kmVec3* pV1, const struct kmVec3* pV2);
|
||||
CC_DLL kmPlane* const kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP);
|
||||
CC_DLL kmPlane* const kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s);
|
||||
CC_DLL const POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP); /** Classifies a point against a plane */
|
||||
CC_DLL kmPlane* kmPlaneFill(kmPlane* plane, float a, float b, float c, float d);
|
||||
CC_DLL kmScalar kmPlaneDot(const kmPlane* pP, const struct kmVec4* pV);
|
||||
CC_DLL kmScalar kmPlaneDotCoord(const kmPlane* pP, const struct kmVec3* pV);
|
||||
CC_DLL kmScalar kmPlaneDotNormal(const kmPlane* pP, const struct kmVec3* pV);
|
||||
CC_DLL kmPlane* kmPlaneFromNormalAndDistance(kmPlane* plane, const struct kmVec3* normal, const kmScalar dist);
|
||||
CC_DLL kmPlane* kmPlaneFromPointAndNormal(kmPlane* pOut, const struct kmVec3* pPoint, const struct kmVec3* pNormal);
|
||||
CC_DLL kmPlane* kmPlaneFromPoints(kmPlane* pOut, const struct kmVec3* p1, const struct kmVec3* p2, const struct kmVec3* p3);
|
||||
CC_DLL struct kmVec3* kmPlaneIntersectLine(struct kmVec3* pOut, const kmPlane* pP, const struct kmVec3* pV1, const struct kmVec3* pV2);
|
||||
CC_DLL kmPlane* kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP);
|
||||
CC_DLL kmPlane* kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s);
|
||||
CC_DLL KM_POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const struct kmVec3* pP); /** Classifys a point against a plane */
|
||||
|
||||
CC_DLL kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row);
|
||||
CC_DLL struct kmVec3* kmPlaneGetIntersection(struct kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -0,0 +1,609 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include "mat4.h"
|
||||
#include "utility.h"
|
||||
#include "mat3.h"
|
||||
#include "vec3.h"
|
||||
#include "quaternion.h"
|
||||
|
||||
int kmQuaternionAreEqual(const kmQuaternion* p1, const kmQuaternion* p2) {
|
||||
if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) &&
|
||||
(p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) &&
|
||||
(p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon)) &&
|
||||
(p1->w < (p2->w + kmEpsilon) && p1->w > (p2->w - kmEpsilon))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionFill(kmQuaternion* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w) {
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
pOut->z = z;
|
||||
pOut->w = w;
|
||||
return pOut;
|
||||
}
|
||||
///< Returns the dot product of the 2 quaternions
|
||||
kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2)
|
||||
{
|
||||
/* A dot B = B dot A = AtBt + AxBx + AyBy + AzBz */
|
||||
|
||||
return (q1->w * q2->w +
|
||||
q1->x * q2->x +
|
||||
q1->y * q2->y +
|
||||
q1->z * q2->z);
|
||||
}
|
||||
|
||||
///< Returns the exponential of the quaternion
|
||||
kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
assert(0);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Makes the passed quaternion an identity quaternion
|
||||
kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns the inverse of the passed Quaternion
|
||||
kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
kmScalar l = kmQuaternionLength(pIn);
|
||||
|
||||
if (fabs(l) < kmEpsilon)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 0.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
pOut->x = -pIn->x;
|
||||
pOut->y = -pIn->y;
|
||||
pOut->z = -pIn->z;
|
||||
pOut->w = pIn->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns true if the quaternion is an identity quaternion
|
||||
int kmQuaternionIsIdentity(const kmQuaternion* pIn)
|
||||
{
|
||||
return (pIn->x == 0.0 && pIn->y == 0.0 && pIn->z == 0.0 &&
|
||||
pIn->w == 1.0);
|
||||
}
|
||||
|
||||
///< Returns the length of the quaternion
|
||||
kmScalar kmQuaternionLength(const kmQuaternion* pIn)
|
||||
{
|
||||
return sqrt(kmQuaternionLengthSq(pIn));
|
||||
}
|
||||
|
||||
///< Returns the length of the quaternion squared (prevents a sqrt)
|
||||
kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn)
|
||||
{
|
||||
return pIn->x * pIn->x + pIn->y * pIn->y + pIn->z * pIn->z + pIn->w * pIn->w;
|
||||
}
|
||||
|
||||
///< Returns the natural logarithm
|
||||
kmQuaternion* kmQuaternionLn(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
/*
|
||||
A unit quaternion, is defined by:
|
||||
Q == (cos(theta), sin(theta) * v) where |v| = 1
|
||||
The natural logarithm of Q is, ln(Q) = (0, theta * v)
|
||||
*/
|
||||
|
||||
assert(0);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Multiplies 2 quaternions together
|
||||
extern
|
||||
kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut,
|
||||
const kmQuaternion* qu1,
|
||||
const kmQuaternion* qu2)
|
||||
{
|
||||
kmQuaternion tmp1, tmp2;
|
||||
kmQuaternionAssign(&tmp1, qu1);
|
||||
kmQuaternionAssign(&tmp2, qu2);
|
||||
|
||||
//Just aliasing
|
||||
kmQuaternion* q1 = &tmp1;
|
||||
kmQuaternion* q2 = &tmp2;
|
||||
|
||||
pOut->x = q1->w * q2->x + q1->x * q2->w + q1->y * q2->z - q1->z * q2->y;
|
||||
pOut->y = q1->w * q2->y + q1->y * q2->w + q1->z * q2->x - q1->x * q2->z;
|
||||
pOut->z = q1->w * q2->z + q1->z * q2->w + q1->x * q2->y - q1->y * q2->x;
|
||||
pOut->w = q1->w * q2->w - q1->x * q2->x - q1->y * q2->y - q1->z * q2->z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Normalizes a quaternion
|
||||
kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
kmScalar length = kmQuaternionLength(pIn);
|
||||
|
||||
if (fabs(length) < kmEpsilon)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 0.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternionFill(pOut,
|
||||
pOut->x / length,
|
||||
pOut->y / length,
|
||||
pOut->z / length,
|
||||
pOut->w / length
|
||||
);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Rotates a quaternion around an axis
|
||||
kmQuaternion* kmQuaternionRotationAxisAngle(kmQuaternion* pOut,
|
||||
const kmVec3* pV,
|
||||
kmScalar angle)
|
||||
{
|
||||
kmScalar rad = angle * 0.5f;
|
||||
kmScalar scale = sinf(rad);
|
||||
|
||||
pOut->x = pV->x * scale;
|
||||
pOut->y = pV->y * scale;
|
||||
pOut->z = pV->z * scale;
|
||||
pOut->w = cosf(rad);
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Creates a quaternion from a rotation matrix
|
||||
kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut,
|
||||
const kmMat3* pIn)
|
||||
{
|
||||
/*
|
||||
Note: The OpenGL matrices are transposed from the description below
|
||||
taken from the Matrix and Quaternion FAQ
|
||||
|
||||
if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0:
|
||||
S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
|
||||
X = 0.25 * S;
|
||||
Y = (mat[4] + mat[1] ) / S;
|
||||
Z = (mat[2] + mat[8] ) / S;
|
||||
W = (mat[9] - mat[6] ) / S;
|
||||
} else if ( mat[5] > mat[10] ) { // Column 1:
|
||||
S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
|
||||
X = (mat[4] + mat[1] ) / S;
|
||||
Y = 0.25 * S;
|
||||
Z = (mat[9] + mat[6] ) / S;
|
||||
W = (mat[2] - mat[8] ) / S;
|
||||
} else { // Column 2:
|
||||
S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
|
||||
X = (mat[2] + mat[8] ) / S;
|
||||
Y = (mat[9] + mat[6] ) / S;
|
||||
Z = 0.25 * S;
|
||||
W = (mat[4] - mat[1] ) / S;
|
||||
}
|
||||
*/
|
||||
|
||||
kmScalar x, y, z, w;
|
||||
kmScalar *pMatrix = NULL;
|
||||
kmScalar m4x4[16] = {0};
|
||||
kmScalar scale = 0.0f;
|
||||
kmScalar diagonal = 0.0f;
|
||||
|
||||
if(!pIn) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 0 3 6
|
||||
1 4 7
|
||||
2 5 8
|
||||
|
||||
0 1 2 3
|
||||
4 5 6 7
|
||||
8 9 10 11
|
||||
12 13 14 15*/
|
||||
|
||||
m4x4[0] = pIn->mat[0];
|
||||
m4x4[1] = pIn->mat[3];
|
||||
m4x4[2] = pIn->mat[6];
|
||||
m4x4[4] = pIn->mat[1];
|
||||
m4x4[5] = pIn->mat[4];
|
||||
m4x4[6] = pIn->mat[7];
|
||||
m4x4[8] = pIn->mat[2];
|
||||
m4x4[9] = pIn->mat[5];
|
||||
m4x4[10] = pIn->mat[8];
|
||||
m4x4[15] = 1;
|
||||
pMatrix = &m4x4[0];
|
||||
|
||||
diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1;
|
||||
|
||||
if(diagonal > kmEpsilon) {
|
||||
// Calculate the scale of the diagonal
|
||||
scale = (kmScalar)sqrt(diagonal ) * 2;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = ( pMatrix[9] - pMatrix[6] ) / scale;
|
||||
y = ( pMatrix[2] - pMatrix[8] ) / scale;
|
||||
z = ( pMatrix[4] - pMatrix[1] ) / scale;
|
||||
w = 0.25f * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the first element of the diagonal is the greatest value
|
||||
if ( pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10] )
|
||||
{
|
||||
// Find the scale according to the first element, and double that value
|
||||
scale = (kmScalar)sqrt( 1.0f + pMatrix[0] - pMatrix[5] - pMatrix[10] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = 0.25f * scale;
|
||||
y = (pMatrix[4] + pMatrix[1] ) / scale;
|
||||
z = (pMatrix[2] + pMatrix[8] ) / scale;
|
||||
w = (pMatrix[9] - pMatrix[6] ) / scale;
|
||||
}
|
||||
// Else if the second element of the diagonal is the greatest value
|
||||
else if (pMatrix[5] > pMatrix[10])
|
||||
{
|
||||
// Find the scale according to the second element, and double that value
|
||||
scale = (kmScalar)sqrt( 1.0f + pMatrix[5] - pMatrix[0] - pMatrix[10] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = (pMatrix[4] + pMatrix[1] ) / scale;
|
||||
y = 0.25f * scale;
|
||||
z = (pMatrix[9] + pMatrix[6] ) / scale;
|
||||
w = (pMatrix[2] - pMatrix[8] ) / scale;
|
||||
}
|
||||
// Else the third element of the diagonal is the greatest value
|
||||
else
|
||||
{
|
||||
// Find the scale according to the third element, and double that value
|
||||
scale = (kmScalar)sqrt( 1.0f + pMatrix[10] - pMatrix[0] - pMatrix[5] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = (pMatrix[2] + pMatrix[8] ) / scale;
|
||||
y = (pMatrix[9] + pMatrix[6] ) / scale;
|
||||
z = 0.25f * scale;
|
||||
w = (pMatrix[4] - pMatrix[1] ) / scale;
|
||||
}
|
||||
}
|
||||
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
pOut->z = z;
|
||||
pOut->w = w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Create a quaternion from yaw, pitch and roll
|
||||
kmQuaternion* kmQuaternionRotationPitchYawRoll(kmQuaternion* pOut,
|
||||
kmScalar pitch,
|
||||
kmScalar yaw,
|
||||
kmScalar roll)
|
||||
{
|
||||
assert(pitch <= 2*kmPI);
|
||||
assert(yaw <= 2*kmPI);
|
||||
assert(roll <= 2*kmPI);
|
||||
|
||||
// Finds the Sin and Cosin for each half angles.
|
||||
float sY = sinf(yaw * 0.5);
|
||||
float cY = cosf(yaw * 0.5);
|
||||
float sZ = sinf(roll * 0.5);
|
||||
float cZ = cosf(roll * 0.5);
|
||||
float sX = sinf(pitch * 0.5);
|
||||
float cX = cosf(pitch * 0.5);
|
||||
|
||||
// Formula to construct a new Quaternion based on Euler Angles.
|
||||
pOut->w = cY * cZ * cX - sY * sZ * sX;
|
||||
pOut->x = sY * sZ * cX + cY * cZ * sX;
|
||||
pOut->y = sY * cZ * cX + cY * sZ * sX;
|
||||
pOut->z = cY * sZ * cX - sY * cZ * sX;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Interpolate between 2 quaternions
|
||||
kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut,
|
||||
const kmQuaternion* q1,
|
||||
const kmQuaternion* q2,
|
||||
kmScalar t)
|
||||
{
|
||||
|
||||
kmScalar dot = kmQuaternionDot(q1, q2);
|
||||
const double DOT_THRESHOLD = 0.9995;
|
||||
|
||||
if (dot > DOT_THRESHOLD) {
|
||||
kmQuaternion diff;
|
||||
kmQuaternionSubtract(&diff, q2, q1);
|
||||
kmQuaternionScale(&diff, &diff, t);
|
||||
|
||||
kmQuaternionAdd(pOut, q1, &diff);
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
dot = kmClamp(dot, -1, 1);
|
||||
|
||||
kmScalar theta_0 = acos(dot);
|
||||
kmScalar theta = theta_0 * t;
|
||||
|
||||
kmQuaternion tmp;
|
||||
kmQuaternionScale(&tmp, q1, dot);
|
||||
kmQuaternionSubtract(&tmp, q2, &tmp);
|
||||
kmQuaternionNormalize(&tmp, &tmp);
|
||||
|
||||
kmQuaternion t1, t2;
|
||||
kmQuaternionScale(&t1, q1, cos(theta));
|
||||
kmQuaternionScale(&t2, &tmp, sin(theta));
|
||||
|
||||
kmQuaternionAdd(pOut, &t1, &t2);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Get the axis and angle of rotation from a quaternion
|
||||
void kmQuaternionToAxisAngle(const kmQuaternion* pIn,
|
||||
kmVec3* pAxis,
|
||||
kmScalar* pAngle)
|
||||
{
|
||||
kmScalar tempAngle; // temp angle
|
||||
kmScalar scale; // temp vars
|
||||
|
||||
tempAngle = acosf(pIn->w);
|
||||
scale = sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
|
||||
|
||||
if (((scale > -kmEpsilon) && scale < kmEpsilon)
|
||||
|| (scale < 2*kmPI + kmEpsilon && scale > 2*kmPI - kmEpsilon)) // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0
|
||||
{
|
||||
*pAngle = 0.0f;
|
||||
|
||||
pAxis->x = 0.0f;
|
||||
pAxis->y = 0.0f;
|
||||
pAxis->z = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pAngle = tempAngle * 2.0f; // angle in radians
|
||||
|
||||
pAxis->x = pIn->x / scale;
|
||||
pAxis->y = pIn->y / scale;
|
||||
pAxis->z = pIn->z / scale;
|
||||
kmVec3Normalize(pAxis, pAxis);
|
||||
}
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionScale(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn,
|
||||
kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
pOut->z = pIn->z * s;
|
||||
pOut->w = pIn->w * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
memcpy(pOut, pIn, sizeof(kmScalar) * 4);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionSubtract(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2) {
|
||||
pOut->x = pQ1->x - pQ2->x;
|
||||
pOut->y = pQ1->y - pQ2->y;
|
||||
pOut->z = pQ1->z - pQ2->z;
|
||||
pOut->w = pQ1->w - pQ2->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2)
|
||||
{
|
||||
pOut->x = pQ1->x + pQ2->x;
|
||||
pOut->y = pQ1->y + pQ2->y;
|
||||
pOut->z = pQ1->z + pQ2->z;
|
||||
pOut->w = pQ1->w + pQ2->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Adapted from the OGRE engine!
|
||||
|
||||
Gets the shortest arc quaternion to rotate this vector to the destination
|
||||
vector.
|
||||
@remarks
|
||||
If you call this with a dest vector that is close to the inverse
|
||||
of this vector, we will rotate 180 degrees around the 'fallbackAxis'
|
||||
(if specified, or a generated axis if not) since in this case
|
||||
ANY axis of rotation is valid.
|
||||
*/
|
||||
|
||||
kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const kmVec3* vec1, const kmVec3* vec2, const kmVec3* fallback) {
|
||||
|
||||
kmVec3 v1, v2;
|
||||
kmScalar a;
|
||||
|
||||
kmVec3Assign(&v1, vec1);
|
||||
kmVec3Assign(&v2, vec2);
|
||||
|
||||
kmVec3Normalize(&v1, &v1);
|
||||
kmVec3Normalize(&v2, &v2);
|
||||
|
||||
a = kmVec3Dot(&v1, &v2);
|
||||
|
||||
if (a >= 1.0) {
|
||||
kmQuaternionIdentity(pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
if (a < (1e-6f - 1.0f)) {
|
||||
if (fabs(kmVec3LengthSq(fallback)) < kmEpsilon) {
|
||||
kmQuaternionRotationAxisAngle(pOut, fallback, kmPI);
|
||||
} else {
|
||||
kmVec3 axis;
|
||||
kmVec3 X;
|
||||
X.x = 1.0;
|
||||
X.y = 0.0;
|
||||
X.z = 0.0;
|
||||
|
||||
|
||||
kmVec3Cross(&axis, &X, vec1);
|
||||
|
||||
//If axis is zero
|
||||
if (fabs(kmVec3LengthSq(&axis)) < kmEpsilon) {
|
||||
kmVec3 Y;
|
||||
Y.x = 0.0;
|
||||
Y.y = 1.0;
|
||||
Y.z = 0.0;
|
||||
|
||||
kmVec3Cross(&axis, &Y, vec1);
|
||||
}
|
||||
|
||||
kmVec3Normalize(&axis, &axis);
|
||||
|
||||
kmQuaternionRotationAxisAngle(pOut, &axis, kmPI);
|
||||
}
|
||||
} else {
|
||||
kmScalar s = sqrtf((1+a) * 2);
|
||||
kmScalar invs = 1 / s;
|
||||
|
||||
kmVec3 c;
|
||||
kmVec3Cross(&c, &v1, &v2);
|
||||
|
||||
pOut->x = c.x * invs;
|
||||
pOut->y = c.y * invs;
|
||||
pOut->z = c.z * invs;
|
||||
pOut->w = s * 0.5f;
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
}
|
||||
|
||||
return pOut;
|
||||
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionMultiplyVec3(kmVec3* pOut, const kmQuaternion* q, const kmVec3* v) {
|
||||
kmVec3 uv, uuv, qvec;
|
||||
|
||||
qvec.x = q->x;
|
||||
qvec.y = q->y;
|
||||
qvec.z = q->z;
|
||||
|
||||
kmVec3Cross(&uv, &qvec, v);
|
||||
kmVec3Cross(&uuv, &qvec, &uv);
|
||||
|
||||
kmVec3Scale(&uv, &uv, (2.0f * q->w));
|
||||
kmVec3Scale(&uuv, &uuv, 2.0f);
|
||||
|
||||
kmVec3Add(pOut, v, &uv);
|
||||
kmVec3Add(pOut, pOut, &uuv);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionGetUpVec3(kmVec3* pOut, const kmQuaternion* pIn) {
|
||||
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_Y);
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionGetRightVec3(kmVec3* pOut, const kmQuaternion* pIn) {
|
||||
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_X);
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionGetForwardVec3RH(kmVec3* pOut, const kmQuaternion* pIn) {
|
||||
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_NEG_Z);
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionGetForwardVec3LH(kmVec3* pOut, const kmQuaternion* pIn) {
|
||||
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_Z);
|
||||
}
|
||||
|
||||
kmScalar kmQuaternionGetPitch(const kmQuaternion* q) {
|
||||
float result = atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z);
|
||||
return result;
|
||||
}
|
||||
|
||||
kmScalar kmQuaternionGetYaw(const kmQuaternion* q) {
|
||||
float result = asin(-2 * (q->x * q->z - q->w * q->y));
|
||||
return result;
|
||||
}
|
||||
|
||||
kmScalar kmQuaternionGetRoll(const kmQuaternion* q) {
|
||||
float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z);
|
||||
return result;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionLookRotation(kmQuaternion* pOut, const kmVec3* direction, const kmVec3* up) {
|
||||
kmMat3 tmp;
|
||||
kmMat3LookAt(&tmp, &KM_VEC3_ZERO, direction, up);
|
||||
return kmQuaternionNormalize(pOut, kmQuaternionRotationMatrix(pOut, &tmp));
|
||||
/*
|
||||
if(!direction->x && !direction->y && !direction->z) {
|
||||
return kmQuaternionIdentity(pOut);
|
||||
}
|
||||
|
||||
kmVec3 right;
|
||||
kmVec3Cross(&right, up, direction);
|
||||
|
||||
pOut->w = sqrtf(1.0f + right.x + up->y + direction->z) * 0.5f;
|
||||
|
||||
float w4_recip = 1.0f / (4.0f * pOut->w);
|
||||
|
||||
pOut->x = (up->z - direction->y) * w4_recip;
|
||||
pOut->y = (direction->x - right.z) * w4_recip;
|
||||
pOut->z = (right.y - up->x) * w4_recip;
|
||||
|
||||
return kmQuaternionNormalize(pOut, pOut);*/
|
||||
}
|
|
@ -30,7 +30,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
|
||||
struct kmMat4;
|
||||
|
@ -38,15 +37,15 @@ struct kmMat3;
|
|||
struct kmVec3;
|
||||
|
||||
typedef struct kmQuaternion {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
kmScalar w;
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
kmScalar w;
|
||||
} kmQuaternion;
|
||||
|
||||
CC_DLL kmQuaternion* const kmQuaternionConjugate(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns pOut, sets pOut to the conjugate of pIn
|
||||
|
||||
CC_DLL const kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2); ///< Returns the dot product of the 2 quaternions
|
||||
CC_DLL int kmQuaternionAreEqual(const kmQuaternion* p1, const kmQuaternion* p2);
|
||||
CC_DLL kmQuaternion* kmQuaternionFill(kmQuaternion* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w);
|
||||
CC_DLL kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2); ///< Returns the dot product of the 2 quaternions
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns the exponential of the quaternion
|
||||
|
||||
|
@ -56,8 +55,7 @@ CC_DLL kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut);
|
|||
|
||||
///< Returns the inverse of the passed Quaternion
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn);
|
||||
CC_DLL kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut, const kmQuaternion* pIn);
|
||||
|
||||
///< Returns true if the quaternion is an identity quaternion
|
||||
|
||||
|
@ -85,7 +83,7 @@ CC_DLL kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut, const kmQuaternio
|
|||
|
||||
///< Rotates a quaternion around an axis
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionRotationAxis(kmQuaternion* pOut, const struct kmVec3* pV, kmScalar angle);
|
||||
CC_DLL kmQuaternion* kmQuaternionRotationAxisAngle(kmQuaternion* pOut, const struct kmVec3* pV, kmScalar angle);
|
||||
|
||||
///< Creates a quaternion from a rotation matrix
|
||||
|
||||
|
@ -93,7 +91,7 @@ CC_DLL kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut, const struct
|
|||
|
||||
///< Create a quaternion from yaw, pitch and roll
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut, kmScalar yaw, kmScalar pitch, kmScalar roll);
|
||||
CC_DLL kmQuaternion* kmQuaternionRotationPitchYawRoll(kmQuaternion* pOut, kmScalar pitch, kmScalar yaw, kmScalar roll);
|
||||
///< Interpolate between 2 quaternions
|
||||
CC_DLL kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2, kmScalar t);
|
||||
|
||||
|
@ -104,9 +102,22 @@ CC_DLL void kmQuaternionToAxisAngle(const kmQuaternion* pIn, struct kmVec3* pVec
|
|||
CC_DLL kmQuaternion* kmQuaternionScale(kmQuaternion* pOut, const kmQuaternion* pIn, kmScalar s);
|
||||
CC_DLL kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn);
|
||||
CC_DLL kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2);
|
||||
CC_DLL kmQuaternion* kmQuaternionSubtract(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2);
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const struct kmVec3* vec1, const struct kmVec3* vec2, const struct kmVec3* fallback);
|
||||
CC_DLL struct kmVec3* kmQuaternionMultiplyVec3(struct kmVec3* pOut, const kmQuaternion* q, const struct kmVec3* v);
|
||||
|
||||
CC_DLL kmVec3* kmQuaternionGetUpVec3(kmVec3* pOut, const kmQuaternion* pIn);
|
||||
CC_DLL kmVec3* kmQuaternionGetRightVec3(kmVec3* pOut, const kmQuaternion* pIn);
|
||||
CC_DLL kmVec3* kmQuaternionGetForwardVec3RH(kmVec3* pOut, const kmQuaternion* pIn);
|
||||
CC_DLL kmVec3* kmQuaternionGetForwardVec3LH(kmVec3* pOut, const kmQuaternion* pIn);
|
||||
|
||||
CC_DLL kmScalar kmQuaternionGetPitch(const kmQuaternion* q);
|
||||
CC_DLL kmScalar kmQuaternionGetYaw(const kmQuaternion* q);
|
||||
CC_DLL kmScalar kmQuaternionGetRoll(const kmQuaternion* q);
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionLookRotation(kmQuaternion* pOut, const kmVec3* direction, const kmVec3* up);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,200 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "ray2.h"
|
||||
|
||||
void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy) {
|
||||
ray->start.x = px;
|
||||
ray->start.y = py;
|
||||
ray->dir.x = vx;
|
||||
ray->dir.y = vy;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) {
|
||||
|
||||
kmScalar x1 = ray->start.x;
|
||||
kmScalar y1 = ray->start.y;
|
||||
kmScalar x2 = ray->start.x + ray->dir.x;
|
||||
kmScalar y2 = ray->start.y + ray->dir.y;
|
||||
kmScalar x3 = p1->x;
|
||||
kmScalar y3 = p1->y;
|
||||
kmScalar x4 = p2->x;
|
||||
kmScalar y4 = p2->y;
|
||||
|
||||
kmScalar denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
||||
|
||||
//If denom is zero, the lines are parallel
|
||||
if(denom > -kmEpsilon && denom < kmEpsilon) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
kmScalar ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
|
||||
kmScalar ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
|
||||
|
||||
kmScalar x = x1 + ua * (x2 - x1);
|
||||
kmScalar y = y1 + ua * (y2 - y1);
|
||||
|
||||
if((0.0 <= ua) && (ua <= 1.0) && (0.0 <= ub) && (ub <= 1.0)) {
|
||||
intersection->x = x;
|
||||
intersection->y = y;
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2 other_point, kmVec2* normal_out) {
|
||||
/*
|
||||
A = (3,4)
|
||||
B = (2,1)
|
||||
C = (1,3)
|
||||
|
||||
AB = (2,1) - (3,4) = (-1,-3)
|
||||
AC = (1,3) - (3,4) = (-2,-1)
|
||||
N = n(AB) = (-3,1)
|
||||
D = dot(N,AC) = 6 + -1 = 5
|
||||
|
||||
since D > 0:
|
||||
N = -N = (3,-1)
|
||||
*/
|
||||
|
||||
kmVec2 edge, other_edge;
|
||||
kmVec2Subtract(&edge, &p2, &p1);
|
||||
kmVec2Subtract(&other_edge, &other_point, &p1);
|
||||
kmVec2Normalize(&edge, &edge);
|
||||
kmVec2Normalize(&other_edge, &other_edge);
|
||||
|
||||
kmVec2 n;
|
||||
n.x = edge.y;
|
||||
n.y = -edge.x;
|
||||
|
||||
kmScalar d = kmVec2Dot(&n, &other_edge);
|
||||
if(d > 0.0f) {
|
||||
n.x = -n.x;
|
||||
n.y = -n.y;
|
||||
}
|
||||
|
||||
normal_out->x = n.x;
|
||||
normal_out->y = n.y;
|
||||
kmVec2Normalize(normal_out, normal_out);
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out, kmScalar* distance_out) {
|
||||
kmVec2 intersect;
|
||||
kmVec2 final_intersect;
|
||||
kmVec2 normal;
|
||||
kmScalar distance = 10000.0f;
|
||||
kmBool intersected = KM_FALSE;
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p1, p2, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
kmVec2 this_normal;
|
||||
calculate_line_normal(*p1, *p2, *p3, &this_normal);
|
||||
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
kmVec2Assign(&normal, &this_normal);
|
||||
intersected = KM_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
|
||||
kmVec2 this_normal;
|
||||
calculate_line_normal(*p2, *p3, *p1, &this_normal);
|
||||
|
||||
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
kmVec2Assign(&normal, &this_normal);
|
||||
intersected = KM_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) {
|
||||
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
|
||||
kmVec2 this_normal;
|
||||
calculate_line_normal(*p3, *p1, *p2, &this_normal);
|
||||
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
kmVec2Assign(&normal, &this_normal);
|
||||
intersected = KM_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(intersected) {
|
||||
intersection->x = final_intersect.x;
|
||||
intersection->y = final_intersect.y;
|
||||
if(normal_out) {
|
||||
normal_out->x = normal.x;
|
||||
normal_out->y = normal.y;
|
||||
}
|
||||
if(distance) {
|
||||
*distance_out = distance;
|
||||
}
|
||||
}
|
||||
|
||||
return intersected;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4,
|
||||
kmVec2* intersection, kmVec2* normal_out) {
|
||||
kmBool intersected = KM_FALSE;
|
||||
kmVec2 intersect, final_intersect, normal;
|
||||
kmScalar distance = 10000.0f;
|
||||
|
||||
const kmVec2* points[4];
|
||||
points[0] = p1;
|
||||
points[1] = p2;
|
||||
points[2] = p3;
|
||||
points[3] = p4;
|
||||
|
||||
unsigned int i = 0;
|
||||
for(; i < 4; ++i) {
|
||||
const kmVec2* this_point = points[i];
|
||||
const kmVec2* next_point = (i == 3) ? points[0] : points[i+1];
|
||||
const kmVec2* other_point = (i == 3 || i == 0) ? points[1] : points[0];
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, this_point, next_point, &intersect)) {
|
||||
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
|
||||
kmVec2 this_normal;
|
||||
|
||||
calculate_line_normal(*this_point, *next_point, *other_point, &this_normal);
|
||||
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
|
||||
kmVec2Assign(&final_intersect, &intersect);
|
||||
distance = this_distance;
|
||||
intersected = KM_TRUE;
|
||||
kmVec2Assign(&normal, &this_normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(intersected) {
|
||||
intersection->x = final_intersect.x;
|
||||
intersection->y = final_intersect.y;
|
||||
if(normal_out) {
|
||||
normal_out->x = normal.x;
|
||||
normal_out->y = normal.y;
|
||||
}
|
||||
}
|
||||
|
||||
return intersected;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection) {
|
||||
assert(0 && "Not implemented");
|
||||
return KM_TRUE;
|
||||
}
|
|
@ -26,7 +26,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef RAY_2_H
|
||||
#define RAY_2_H
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
#include "vec2.h"
|
||||
|
||||
|
@ -41,7 +40,11 @@ typedef struct kmRay2 {
|
|||
|
||||
CC_DLL void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy);
|
||||
CC_DLL kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection);
|
||||
CC_DLL kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out);
|
||||
CC_DLL kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out, kmScalar* distance);
|
||||
|
||||
CC_DLL kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4,
|
||||
CC_DLL kmVec2* intersection, kmVec2* normal_out);
|
||||
|
||||
CC_DLL kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection);
|
||||
|
||||
#ifdef __cplusplus
|
|
@ -0,0 +1,47 @@
|
|||
#include "plane.h"
|
||||
#include "ray3.h"
|
||||
|
||||
kmRay3* kmRay3Fill(kmRay3* ray, kmScalar px, kmScalar py, kmScalar pz, kmScalar vx, kmScalar vy, kmScalar vz) {
|
||||
ray->start.x = px;
|
||||
ray->start.y = py;
|
||||
ray->start.z = pz;
|
||||
|
||||
ray->dir.x = vx;
|
||||
ray->dir.y = vy;
|
||||
ray->dir.z = vz;
|
||||
|
||||
return ray;
|
||||
}
|
||||
|
||||
kmRay3* kmRay3FromPointAndDirection(kmRay3* ray, const kmVec3* point, const kmVec3* direction) {
|
||||
kmVec3Assign(&ray->start, point);
|
||||
kmVec3Assign(&ray->dir, direction);
|
||||
return ray;
|
||||
}
|
||||
|
||||
kmBool kmRay3IntersectPlane(kmVec3* pOut, const kmRay3* ray, const kmPlane* plane) {
|
||||
//t = - (A*org.x + B*org.y + C*org.z + D) / (A*dir.x + B*dir.y + C*dir.z )
|
||||
|
||||
kmScalar d = (plane->a * ray->dir.x +
|
||||
plane->b * ray->dir.y +
|
||||
plane->c * ray->dir.z);
|
||||
|
||||
if(d == 0)
|
||||
{
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
kmScalar t = -(plane->a * ray->start.x +
|
||||
plane->b * ray->start.y +
|
||||
plane->c * ray->start.z + plane->d) / d;
|
||||
|
||||
if(t < 0)
|
||||
{
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
kmVec3 scaled_dir;
|
||||
kmVec3Scale(&scaled_dir, &ray->dir, t);
|
||||
kmVec3Add(pOut, &ray->start, &scaled_dir);
|
||||
return KM_TRUE;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef RAY3_H
|
||||
#define RAY3_H
|
||||
|
||||
#include "utility.h"
|
||||
#include "vec3.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct kmRay3 {
|
||||
kmVec3 start;
|
||||
kmVec3 dir;
|
||||
} kmRay3;
|
||||
|
||||
struct kmPlane;
|
||||
|
||||
CC_DLL kmRay3* kmRay3Fill(kmRay3* ray, kmScalar px, kmScalar py, kmScalar pz, kmScalar vx, kmScalar vy, kmScalar vz);
|
||||
CC_DLL kmRay3* kmRay3FromPointAndDirection(kmRay3* ray, const kmVec3* point, const kmVec3* direction);
|
||||
CC_DLL kmBool kmRay3IntersectPlane(kmVec3* pOut, const kmRay3* ray, const struct kmPlane* plane);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RAY3_H
|
|
@ -23,27 +23,27 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "utility.h"
|
||||
|
||||
/**
|
||||
* Returns the square of s (e.g. s*s)
|
||||
*/
|
||||
kmScalar kmSQR(kmScalar s) {
|
||||
return s*s;
|
||||
return s*s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns degrees as radians.
|
||||
*/
|
||||
kmScalar kmDegreesToRadians(kmScalar degrees) {
|
||||
return degrees * kmPIOver180;
|
||||
return degrees * kmPIOver180;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns radians as degrees
|
||||
*/
|
||||
kmScalar kmRadiansToDegrees(kmScalar radians) {
|
||||
return radians * kmPIUnder180;
|
||||
return radians * kmPIUnder180;
|
||||
}
|
||||
|
||||
kmScalar kmMin(kmScalar lhs, kmScalar rhs) {
|
||||
|
@ -57,3 +57,13 @@ kmScalar kmMax(kmScalar lhs, kmScalar rhs) {
|
|||
kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs) {
|
||||
return (lhs + kmEpsilon > rhs && lhs - kmEpsilon < rhs);
|
||||
}
|
||||
|
||||
kmScalar kmClamp(kmScalar x, kmScalar min, kmScalar max)
|
||||
{
|
||||
return x < min ? min : (x > max ? max : x);
|
||||
}
|
||||
|
||||
kmScalar kmLerp(kmScalar x, kmScalar y, kmScalar t )
|
||||
{
|
||||
return x + t * ( y - x );
|
||||
}
|
|
@ -26,21 +26,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef UTILITY_H_INCLUDED
|
||||
#define UTILITY_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef kmScalar
|
||||
#ifdef USE_DOUBLE_PRECISION
|
||||
#define kmScalar double
|
||||
#else
|
||||
#define kmScalar float
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef kmBool
|
||||
#define kmBool unsigned char
|
||||
#endif
|
||||
|
||||
#ifndef kmUchar
|
||||
#define kmUchar unsigned char
|
||||
#endif
|
||||
|
||||
#ifndef kmEnum
|
||||
#define kmEnum unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef kmUint
|
||||
#define kmUint unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef kmInt
|
||||
#define kmInt int
|
||||
#endif
|
||||
|
||||
#ifndef KM_FALSE
|
||||
#define KM_FALSE 0
|
||||
#endif
|
||||
|
@ -49,24 +65,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define KM_TRUE 1
|
||||
#endif
|
||||
|
||||
#define kmPI 3.141592f
|
||||
#define kmPIOver180 0.017453f // PI / 180
|
||||
#define kmPIUnder180 57.295779f // 180 / PI
|
||||
#define kmEpsilon 1.0 / 64.0
|
||||
|
||||
#define kmPI 3.14159265358979323846f
|
||||
#define kmPIOver180 (kmPI / 180.0f)
|
||||
#define kmPIUnder180 (180.0 / kmPI)
|
||||
#define kmEpsilon 0.0001
|
||||
|
||||
#define KM_CONTAINS_NONE 0
|
||||
#define KM_CONTAINS_PARTIAL 1
|
||||
#define KM_CONTAINS_ALL 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CC_DLL kmScalar kmSQR(kmScalar s);
|
||||
CC_DLL kmScalar kmDegreesToRadians(kmScalar degrees);
|
||||
CC_DLL kmScalar kmRadiansToDegrees(kmScalar radians);
|
||||
extern kmScalar kmSQR(kmScalar s);
|
||||
extern kmScalar kmDegreesToRadians(kmScalar degrees);
|
||||
extern kmScalar kmRadiansToDegrees(kmScalar radians);
|
||||
|
||||
CC_DLL kmScalar kmMin(kmScalar lhs, kmScalar rhs);
|
||||
CC_DLL kmScalar kmMax(kmScalar lhs, kmScalar rhs);
|
||||
CC_DLL kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs);
|
||||
extern kmScalar kmMin(kmScalar lhs, kmScalar rhs);
|
||||
extern kmScalar kmMax(kmScalar lhs, kmScalar rhs);
|
||||
extern kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs);
|
||||
|
||||
extern kmScalar kmClamp(kmScalar x, kmScalar min, kmScalar max);
|
||||
extern kmScalar kmLerp(kmScalar x, kmScalar y, kmScalar factor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mat3.h"
|
||||
#include "vec2.h"
|
||||
#include "utility.h"
|
||||
|
||||
const kmVec2 KM_VEC2_POS_Y = { 0, 1 };
|
||||
const kmVec2 KM_VEC2_NEG_Y = { 0, -1 };
|
||||
const kmVec2 KM_VEC2_NEG_X = { -1, 0 };
|
||||
const kmVec2 KM_VEC2_POS_X = { 1, 0 };
|
||||
const kmVec2 KM_VEC2_ZERO = { 0, 0 };
|
||||
|
||||
kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y)
|
||||
{
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Length(const kmVec2* pIn)
|
||||
{
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y));
|
||||
}
|
||||
|
||||
kmScalar kmVec2LengthSq(const kmVec2* pIn)
|
||||
{
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y);
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Lerp(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2, kmScalar t) {
|
||||
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
|
||||
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn)
|
||||
{
|
||||
if (!pIn->x && !pIn->y)
|
||||
return kmVec2Assign(pOut, pIn);
|
||||
|
||||
kmScalar l = 1.0f / kmVec2Length(pIn);
|
||||
|
||||
kmVec2 v;
|
||||
v.x = pIn->x * l;
|
||||
v.y = pIn->y * l;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
pOut->x = pV1->x + pV2->x;
|
||||
pOut->y = pV1->y + pV2->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
return pV1->x * pV2->x + pV1->y * pV2->y;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Cross(const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
return pV1->x * pV2->y - pV1->y * pV2->x;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
pOut->x = pV1->x - pV2->x;
|
||||
pOut->y = pV1->y - pV2->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Mul( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ) {
|
||||
pOut->x = pV1->x * pV2->x;
|
||||
pOut->y = pV1->y * pV2->y;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Div( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ) {
|
||||
if ( pV2->x && pV2->y ){
|
||||
pOut->x = pV1->x / pV2->x;
|
||||
pOut->y = pV1->y / pV2->y;
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
|
||||
{
|
||||
kmVec2 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pM->mat[6];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pM->mat[7];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
|
||||
{
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2)
|
||||
{
|
||||
return (
|
||||
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
|
||||
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same
|
||||
* then nothing happens but pOut is still returned
|
||||
*/
|
||||
kmVec2* kmVec2Assign(kmVec2* pOut, const kmVec2* pIn) {
|
||||
if (pOut == pIn) {
|
||||
return pOut;
|
||||
}
|
||||
|
||||
pOut->x = pIn->x;
|
||||
pOut->y = pIn->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the point anticlockwise around a center
|
||||
* by an amount of degrees.
|
||||
*
|
||||
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
|
||||
*/
|
||||
kmVec2* kmVec2RotateBy(kmVec2* pOut, const kmVec2* pIn,
|
||||
const kmScalar degrees, const kmVec2* center)
|
||||
{
|
||||
kmScalar x, y;
|
||||
const kmScalar radians = kmDegreesToRadians(degrees);
|
||||
const kmScalar cs = cosf(radians), sn = sinf(radians);
|
||||
|
||||
pOut->x = pIn->x - center->x;
|
||||
pOut->y = pIn->y - center->y;
|
||||
|
||||
x = pOut->x * cs - pOut->y * sn;
|
||||
y = pOut->x * sn + pOut->y * cs;
|
||||
|
||||
pOut->x = x + center->x;
|
||||
pOut->y = y + center->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the angle in degrees between the two vectors
|
||||
*/
|
||||
kmScalar kmVec2DegreesBetween(const kmVec2* v1, const kmVec2* v2) {
|
||||
if(kmVec2AreEqual(v1, v2)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
kmVec2 t1, t2;
|
||||
kmVec2Normalize(&t1, v1);
|
||||
kmVec2Normalize(&t2, v2);
|
||||
|
||||
kmScalar cross = kmVec2Cross(&t1, &t2);
|
||||
kmScalar dot = kmVec2Dot(&t1, &t2);
|
||||
|
||||
/*
|
||||
* acos is only defined for -1 to 1. Outside the range we
|
||||
* get NaN even if that's just because of a floating point error
|
||||
* so we clamp to the -1 - 1 range
|
||||
*/
|
||||
|
||||
if(dot > 1.0) dot = 1.0;
|
||||
if(dot < -1.0) dot = -1.0;
|
||||
|
||||
return kmRadiansToDegrees(atan2(cross, dot));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distance between the two points
|
||||
*/
|
||||
kmScalar kmVec2DistanceBetween(const kmVec2* v1, const kmVec2* v2) {
|
||||
kmVec2 diff;
|
||||
kmVec2Subtract(&diff, v2, v1);
|
||||
return fabs(kmVec2Length(&diff));
|
||||
}
|
||||
/**
|
||||
* Returns the point mid-way between two others
|
||||
*/
|
||||
kmVec2* kmVec2MidPointBetween(kmVec2* pOut, const kmVec2* v1, const kmVec2* v2) {
|
||||
kmVec2 sum;
|
||||
kmVec2Add(&sum, v1, v2);
|
||||
pOut->x = sum.x / 2.0f;
|
||||
pOut->y = sum.y / 2.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -27,13 +27,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define VEC2_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
|
||||
struct kmMat3;
|
||||
|
||||
#ifndef kmScalar
|
||||
#define kmScalar float
|
||||
#endif
|
||||
|
||||
#pragma pack(push) /* push current alignment to stack */
|
||||
#pragma pack(1) /* set alignment to 1 byte boundary */
|
||||
typedef struct kmVec2 {
|
||||
|
@ -46,17 +43,33 @@ typedef struct kmVec2 {
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CC_DLL kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y);
|
||||
CC_DLL kmScalar kmVec2Length(const kmVec2* pIn); ///< Returns the length of the vector
|
||||
CC_DLL kmScalar kmVec2LengthSq(const kmVec2* pIn); ///< Returns the square of the length of the vector
|
||||
CC_DLL kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn); ///< Returns the vector passed in set to unit length
|
||||
CC_DLL kmVec2* kmVec2Lerp(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2, kmScalar t);
|
||||
CC_DLL kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Adds 2 vectors and returns the result
|
||||
CC_DLL kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2); /** Returns the Dot product which is the cosine of the angle between the two vectors multiplied by their lengths */
|
||||
CC_DLL kmScalar kmVec2Cross(const kmVec2* pV1, const kmVec2* pV2);
|
||||
CC_DLL kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Subtracts 2 vectors and returns the result
|
||||
CC_DLL kmVec2* kmVec2Mul( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ); ///< Component-wise multiplication
|
||||
CC_DLL kmVec2* kmVec2Div( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ); ///< Component-wise division
|
||||
CC_DLL kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV1, const struct kmMat3* pM); /** Transform the Vector */
|
||||
CC_DLL kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const struct kmMat3* pM); ///<Transforms a 2D vector by a given matrix, projecting the result back into w = 1.
|
||||
CC_DLL kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s); ///< Scales a vector to length s
|
||||
CC_DLL int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2); ///< Returns 1 if both vectors are equal
|
||||
CC_DLL int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2); ///< Returns 1 if both vectors are equal
|
||||
CC_DLL kmVec2* kmVec2Assign(kmVec2* pOut, const kmVec2* pIn);
|
||||
CC_DLL kmVec2* kmVec2RotateBy(kmVec2* pOut, const kmVec2* pIn, const kmScalar degrees, const kmVec2* center); ///<Rotates the point anticlockwise around a center by an amount of degrees.
|
||||
CC_DLL kmScalar kmVec2DegreesBetween(const kmVec2* v1, const kmVec2* v2);
|
||||
CC_DLL kmScalar kmVec2DistanceBetween(const kmVec2* v1, const kmVec2* v2);
|
||||
CC_DLL kmVec2* kmVec2MidPointBetween(kmVec2* pOut, const kmVec2* v1, const kmVec2* v2);
|
||||
|
||||
extern const kmVec2 KM_VEC2_POS_Y;
|
||||
extern const kmVec2 KM_VEC2_NEG_Y;
|
||||
extern const kmVec2 KM_VEC2_NEG_X;
|
||||
extern const kmVec2 KM_VEC2_POS_X;
|
||||
extern const kmVec2 KM_VEC2_ZERO;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -0,0 +1,444 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file vec3.c
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "utility.h"
|
||||
#include "vec4.h"
|
||||
#include "mat4.h"
|
||||
#include "mat3.h"
|
||||
#include "vec3.h"
|
||||
#include "plane.h"
|
||||
#include "ray3.h"
|
||||
|
||||
const kmVec3 KM_VEC3_POS_Z = { 0, 0, 1 };
|
||||
const kmVec3 KM_VEC3_NEG_Z = { 0, 0, -1 };
|
||||
const kmVec3 KM_VEC3_POS_Y = { 0, 1, 0 };
|
||||
const kmVec3 KM_VEC3_NEG_Y = { 0, -1, 0 };
|
||||
const kmVec3 KM_VEC3_NEG_X = { -1, 0, 0 };
|
||||
const kmVec3 KM_VEC3_POS_X = { 1, 0, 0 };
|
||||
const kmVec3 KM_VEC3_ZERO = { 0, 0, 0 };
|
||||
|
||||
/**
|
||||
* Fill a kmVec3 structure using 3 floating point values
|
||||
* The result is store in pOut, returns pOut
|
||||
*/
|
||||
kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z)
|
||||
{
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
pOut->z = z;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the length of the vector
|
||||
*/
|
||||
kmScalar kmVec3Length(const kmVec3* pIn)
|
||||
{
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square of the length of the vector
|
||||
*/
|
||||
kmScalar kmVec3LengthSq(const kmVec3* pIn)
|
||||
{
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z);
|
||||
}
|
||||
|
||||
/// Returns the interpolation of 2 4D vectors based on t.
|
||||
kmVec3* kmVec3Lerp(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2, kmScalar t) {
|
||||
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
|
||||
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
|
||||
pOut->z = pV1->z + t * ( pV2->z - pV1->z );
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vector passed in set to unit length
|
||||
* the result is stored in pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn)
|
||||
{
|
||||
if (!pIn->x && !pIn->y && !pIn->z)
|
||||
return kmVec3Assign(pOut, pIn);
|
||||
|
||||
kmScalar l = 1.0f / kmVec3Length(pIn);
|
||||
|
||||
kmVec3 v;
|
||||
v.x = pIn->x * l;
|
||||
v.y = pIn->y * l;
|
||||
v.z = pIn->z * l;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector perpendicular to 2 other vectors.
|
||||
* The result is stored in pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
|
||||
kmVec3 v;
|
||||
|
||||
v.x = (pV1->y * pV2->z) - (pV1->z * pV2->y);
|
||||
v.y = (pV1->z * pV2->x) - (pV1->x * pV2->z);
|
||||
v.z = (pV1->x * pV2->y) - (pV1->y * pV2->x);
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cosine of the angle between 2 vectors
|
||||
*/
|
||||
kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
return ( pV1->x * pV2->x
|
||||
+ pV1->y * pV2->y
|
||||
+ pV1->z * pV2->z );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds 2 vectors and returns the result. The resulting
|
||||
* vector is stored in pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV1->x + pV2->x;
|
||||
v.y = pV1->y + pV2->y;
|
||||
v.z = pV1->z + pV2->z;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts 2 vectors and returns the result. The result is stored in
|
||||
* pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV1->x - pV2->x;
|
||||
v.y = pV1->y - pV2->y;
|
||||
v.z = pV1->z - pV2->z;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3Mul( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 ) {
|
||||
pOut->x = pV1->x * pV2->x;
|
||||
pOut->y = pV1->y * pV2->y;
|
||||
pOut->z = pV1->z * pV2->z;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3Div( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 ) {
|
||||
if ( pV2->x && pV2->y && pV2->z ){
|
||||
pOut->x = pV1->x / pV2->x;
|
||||
pOut->y = pV1->y / pV2->y;
|
||||
pOut->z = pV1->z / pV2->z;
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3MultiplyMat3(kmVec3* pOut, const kmVec3* pV, const kmMat3* pM) {
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pV->z * pM->mat[6];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pV->z * pM->mat[7];
|
||||
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[5] + pV->z * pM->mat[8];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies vector (x, y, z, 1) by a given matrix. The result
|
||||
* is stored in pOut. pOut is returned.
|
||||
*/
|
||||
|
||||
kmVec3* kmVec3MultiplyMat4(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM) {
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pM->mat[12];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pM->mat[13];
|
||||
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pM->mat[14];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
@deprecated Should intead use kmVec3MultiplyMat4
|
||||
*/
|
||||
return kmVec3MultiplyMat4(pOut, pV, pM);
|
||||
}
|
||||
|
||||
kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM)
|
||||
{
|
||||
kmVec3 v1, v2;
|
||||
|
||||
v1.x = pVect->x - pM->mat[12];
|
||||
v1.y = pVect->y - pM->mat[13];
|
||||
v1.z = pVect->z - pM->mat[14];
|
||||
|
||||
v2.x = v1.x * pM->mat[0] + v1.y * pM->mat[1] + v1.z * pM->mat[2];
|
||||
v2.y = v1.x * pM->mat[4] + v1.y * pM->mat[5] + v1.z * pM->mat[6];
|
||||
v2.z = v1.x * pM->mat[8] + v1.y * pM->mat[9] + v1.z * pM->mat[10];
|
||||
|
||||
pOut->x = v2.x;
|
||||
pOut->y = v2.y;
|
||||
pOut->z = v2.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM)
|
||||
{
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pVect->x * pM->mat[0] + pVect->y * pM->mat[1] + pVect->z * pM->mat[2];
|
||||
v.y = pVect->x * pM->mat[4] + pVect->y * pM->mat[5] + pVect->z * pM->mat[6];
|
||||
v.z = pVect->x * pM->mat[8] + pVect->y * pM->mat[9] + pVect->z * pM->mat[10];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
a = (Vx, Vy, Vz, 1)
|
||||
b = (a×M)T
|
||||
Out = 1⁄bw(bx, by, bz)
|
||||
*/
|
||||
|
||||
kmVec4 v;
|
||||
kmVec4 inV;
|
||||
kmVec4Fill(&inV, pV->x, pV->y, pV->z, 1.0);
|
||||
|
||||
kmVec4Transform(&v, &inV,pM);
|
||||
|
||||
pOut->x = v.x / v.w;
|
||||
pOut->y = v.y / v.w;
|
||||
pOut->z = v.z / v.w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
a = (Vx, Vy, Vz, 0)
|
||||
b = (a×M)T
|
||||
Out = (bx, by, bz)
|
||||
*/
|
||||
//Omits the translation, only scaling + rotating
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9];
|
||||
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales a vector to length s. Does not normalize first,
|
||||
* you should do that!
|
||||
*/
|
||||
kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
pOut->z = pIn->z * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if the 2 vectors are approximately equal
|
||||
*/
|
||||
int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2)
|
||||
{
|
||||
if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) &&
|
||||
(p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) &&
|
||||
(p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same
|
||||
* then nothing happens but pOut is still returned
|
||||
*/
|
||||
kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn) {
|
||||
if (pOut == pIn) {
|
||||
return pOut;
|
||||
}
|
||||
|
||||
pOut->x = pIn->x;
|
||||
pOut->y = pIn->y;
|
||||
pOut->z = pIn->z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all the elements of pOut to zero. Returns pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Zero(kmVec3* pOut) {
|
||||
pOut->x = 0.0f;
|
||||
pOut->y = 0.0f;
|
||||
pOut->z = 0.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector.
|
||||
* Useful for orienting vector towards a point.
|
||||
*
|
||||
* Returns a rotation vector containing the X (pitch) and Y (raw) rotations (in degrees) that when applied to a
|
||||
* +Z (e.g. 0, 0, 1) direction vector would make it point in the same direction as this vector. The Z (roll) rotation
|
||||
* is always 0, since two Euler rotations are sufficient to point in any given direction.
|
||||
*
|
||||
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
|
||||
*/
|
||||
kmVec3* kmVec3GetHorizontalAngle(kmVec3* pOut, const kmVec3 *pIn) {
|
||||
const kmScalar z1 = sqrt(pIn->x * pIn->x + pIn->z * pIn->z);
|
||||
|
||||
pOut->y = kmRadiansToDegrees(atan2(pIn->x, pIn->z));
|
||||
if (pOut->y < 0)
|
||||
pOut->y += 360;
|
||||
if (pOut->y >= 360)
|
||||
pOut->y -= 360;
|
||||
|
||||
pOut->x = kmRadiansToDegrees(atan2(z1, pIn->y)) - 90.0;
|
||||
if (pOut->x < 0)
|
||||
pOut->x += 360;
|
||||
if (pOut->x >= 360)
|
||||
pOut->x -= 360;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a direction vector from input vector.
|
||||
* Input vector is assumed to be rotation vector composed from 3 Euler angle rotations, in degrees.
|
||||
* The forwards vector will be rotated by the input vector
|
||||
*
|
||||
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
|
||||
*/
|
||||
kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards)
|
||||
{
|
||||
const kmScalar xr = kmDegreesToRadians(pIn->x);
|
||||
const kmScalar yr = kmDegreesToRadians(pIn->y);
|
||||
const kmScalar zr = kmDegreesToRadians(pIn->z);
|
||||
const kmScalar cr = cos(xr), sr = sin(xr);
|
||||
const kmScalar cp = cos(yr), sp = sin(yr);
|
||||
const kmScalar cy = cos(zr), sy = sin(zr);
|
||||
|
||||
const kmScalar srsp = sr*sp;
|
||||
const kmScalar crsp = cr*sp;
|
||||
|
||||
const kmScalar pseudoMatrix[] = {
|
||||
(cp*cy), (cp*sy), (-sp),
|
||||
(srsp*cy-cr*sy), (srsp*sy+cr*cy), (sr*cp),
|
||||
(crsp*cy+sr*sy), (crsp*sy-sr*cy), (cr*cp)
|
||||
};
|
||||
|
||||
pOut->x = forwards->x * pseudoMatrix[0] +
|
||||
forwards->y * pseudoMatrix[3] +
|
||||
forwards->z * pseudoMatrix[6];
|
||||
|
||||
pOut->y = forwards->x * pseudoMatrix[1] +
|
||||
forwards->y * pseudoMatrix[4] +
|
||||
forwards->z * pseudoMatrix[7];
|
||||
|
||||
pOut->z = forwards->x * pseudoMatrix[2] +
|
||||
forwards->y * pseudoMatrix[5] +
|
||||
forwards->z * pseudoMatrix[8];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3ProjectOnToPlane(kmVec3* pOut, const kmVec3* point, const struct kmPlane* plane) {
|
||||
kmRay3 ray;
|
||||
kmVec3Assign(&ray.start, point);
|
||||
ray.dir.x = -plane->a;
|
||||
ray.dir.y = -plane->b;
|
||||
ray.dir.z = -plane->c;
|
||||
|
||||
kmRay3IntersectPlane(pOut, &ray, plane);
|
||||
return pOut;
|
||||
}
|
|
@ -27,18 +27,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define VEC3_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef kmScalar
|
||||
#define kmScalar float
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include "utility.h"
|
||||
|
||||
struct kmMat4;
|
||||
struct kmMat3;
|
||||
struct kmPlane;
|
||||
|
||||
typedef struct kmVec3 {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
} kmVec3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -48,20 +48,40 @@ extern "C" {
|
|||
CC_DLL kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z);
|
||||
CC_DLL kmScalar kmVec3Length(const kmVec3* pIn); /** Returns the length of the vector */
|
||||
CC_DLL kmScalar kmVec3LengthSq(const kmVec3* pIn); /** Returns the square of the length of the vector */
|
||||
CC_DLL kmVec3* kmVec3Lerp(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2, kmScalar t);
|
||||
CC_DLL kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn); /** Returns the vector passed in set to unit length */
|
||||
CC_DLL kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Returns a vector perpendicular to 2 other vectors */
|
||||
CC_DLL kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2); /** Returns the cosine of the angle between 2 vectors */
|
||||
CC_DLL kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Adds 2 vectors and returns the result */
|
||||
CC_DLL kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Subtracts 2 vectors and returns the result */
|
||||
CC_DLL kmVec3* kmVec3Mul( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 );
|
||||
CC_DLL kmVec3* kmVec3Div( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 );
|
||||
|
||||
CC_DLL kmVec3* kmVec3MultiplyMat3(kmVec3 *pOut, const kmVec3 *pV, const struct kmMat3* pM);
|
||||
CC_DLL kmVec3* kmVec3MultiplyMat4(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);
|
||||
|
||||
CC_DLL kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV1, const struct kmMat4* pM); /** Transforms a vector (assuming w=1) by a given matrix */
|
||||
CC_DLL kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);/**Transforms a 3D normal by a given matrix */
|
||||
CC_DLL kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM); /**Transforms a 3D vector by a given matrix, projecting the result back into w = 1. */
|
||||
|
||||
CC_DLL kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s); /** Scales a vector to length s */
|
||||
CC_DLL int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2);
|
||||
CC_DLL int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2);
|
||||
CC_DLL kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);
|
||||
CC_DLL kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const struct kmMat4* pM);
|
||||
CC_DLL kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn);
|
||||
CC_DLL kmVec3* kmVec3Zero(kmVec3* pOut);
|
||||
CC_DLL kmVec3* kmVec3GetHorizontalAngle(kmVec3* pOut, const kmVec3 *pIn); /** Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector. */
|
||||
CC_DLL kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards); /** Builds a direction vector from input vector. */
|
||||
|
||||
CC_DLL kmVec3* kmVec3ProjectOnToPlane(kmVec3* pOut, const kmVec3* point, const struct kmPlane* plane);
|
||||
|
||||
extern const kmVec3 KM_VEC3_NEG_Z;
|
||||
extern const kmVec3 KM_VEC3_POS_Z;
|
||||
extern const kmVec3 KM_VEC3_POS_Y;
|
||||
extern const kmVec3 KM_VEC3_NEG_Y;
|
||||
extern const kmVec3 KM_VEC3_NEG_X;
|
||||
extern const kmVec3 KM_VEC3_POS_X;
|
||||
extern const kmVec3 KM_VEC3_ZERO;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -27,9 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "kazmath/vec4.h"
|
||||
#include "kazmath/mat4.h"
|
||||
#include "utility.h"
|
||||
#include "vec4.h"
|
||||
#include "mat4.h"
|
||||
|
||||
|
||||
kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w)
|
||||
|
@ -45,74 +45,98 @@ kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w)
|
|||
/// Adds 2 4D vectors together. The result is store in pOut, the function returns
|
||||
/// pOut so that it can be nested in another function.
|
||||
kmVec4* kmVec4Add(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2) {
|
||||
pOut->x = pV1->x + pV2->x;
|
||||
pOut->y = pV1->y + pV2->y;
|
||||
pOut->z = pV1->z + pV2->z;
|
||||
pOut->w = pV1->w + pV2->w;
|
||||
pOut->x = pV1->x + pV2->x;
|
||||
pOut->y = pV1->y + pV2->y;
|
||||
pOut->z = pV1->z + pV2->z;
|
||||
pOut->w = pV1->w + pV2->w;
|
||||
|
||||
return pOut;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Returns the dot product of 2 4D vectors
|
||||
kmScalar kmVec4Dot(const kmVec4* pV1, const kmVec4* pV2) {
|
||||
return ( pV1->x * pV2->x
|
||||
+ pV1->y * pV2->y
|
||||
+ pV1->z * pV2->z
|
||||
+ pV1->w * pV2->w );
|
||||
return ( pV1->x * pV2->x
|
||||
+ pV1->y * pV2->y
|
||||
+ pV1->z * pV2->z
|
||||
+ pV1->w * pV2->w );
|
||||
}
|
||||
|
||||
/// Returns the length of a 4D vector, this uses a sqrt so if the squared length will do use
|
||||
/// kmVec4LengthSq
|
||||
kmScalar kmVec4Length(const kmVec4* pIn) {
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w));
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w));
|
||||
}
|
||||
|
||||
/// Returns the length of the 4D vector squared.
|
||||
kmScalar kmVec4LengthSq(const kmVec4* pIn) {
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w);
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w);
|
||||
}
|
||||
|
||||
/// Returns the interpolation of 2 4D vectors based on t. Currently not implemented!
|
||||
/// Returns the interpolation of 2 4D vectors based on t.
|
||||
kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2, kmScalar t) {
|
||||
assert(0);
|
||||
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
|
||||
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
|
||||
pOut->z = pV1->z + t * ( pV2->z - pV1->z );
|
||||
pOut->w = pV1->w + t * ( pV2->w - pV1->w );
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Normalizes a 4D vector. The result is stored in pOut. pOut is returned
|
||||
kmVec4* kmVec4Normalize(kmVec4* pOut, const kmVec4* pIn) {
|
||||
kmScalar l = 1.0f / kmVec4Length(pIn);
|
||||
if (!pIn->x && !pIn->y && !pIn->z && !pIn->w){
|
||||
return kmVec4Assign(pOut, pIn);
|
||||
}
|
||||
|
||||
pOut->x *= l;
|
||||
pOut->y *= l;
|
||||
pOut->z *= l;
|
||||
pOut->w *= l;
|
||||
kmScalar l = 1.0f / kmVec4Length(pIn);
|
||||
pOut->x = pIn->x * l;
|
||||
pOut->y = pIn->y * l;
|
||||
pOut->z = pIn->z * l;
|
||||
pOut->w = pIn->w * l;
|
||||
|
||||
return pOut;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Scales a vector to the required length. This performs a Normalize before multiplying by S.
|
||||
kmVec4* kmVec4Scale(kmVec4* pOut, const kmVec4* pIn, const kmScalar s) {
|
||||
kmVec4Normalize(pOut, pIn);
|
||||
kmVec4Normalize(pOut, pIn);
|
||||
|
||||
pOut->x *= s;
|
||||
pOut->y *= s;
|
||||
pOut->z *= s;
|
||||
pOut->w *= s;
|
||||
return pOut;
|
||||
pOut->x *= s;
|
||||
pOut->y *= s;
|
||||
pOut->z *= s;
|
||||
pOut->w *= s;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Subtracts one 4D pV2 from pV1. The result is stored in pOut. pOut is returned
|
||||
kmVec4* kmVec4Subtract(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2) {
|
||||
pOut->x = pV1->x - pV2->x;
|
||||
pOut->y = pV1->y - pV2->y;
|
||||
pOut->z = pV1->z - pV2->z;
|
||||
pOut->w = pV1->w - pV2->w;
|
||||
pOut->x = pV1->x - pV2->x;
|
||||
pOut->y = pV1->y - pV2->y;
|
||||
pOut->z = pV1->z - pV2->z;
|
||||
pOut->w = pV1->w - pV2->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec4* kmVec4Mul( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 ) {
|
||||
pOut->x = pV1->x * pV2->x;
|
||||
pOut->y = pV1->y * pV2->y;
|
||||
pOut->z = pV1->z * pV2->z;
|
||||
pOut->w = pV1->w * pV2->w;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Transforms a 4D vector by a matrix, the result is stored in pOut, and pOut is returned.
|
||||
kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) {
|
||||
kmVec4* kmVec4Div( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 ) {
|
||||
if ( pV2->x && pV2->y && pV2->z && pV2->w){
|
||||
pOut->x = pV1->x / pV2->x;
|
||||
pOut->y = pV1->y / pV2->y;
|
||||
pOut->z = pV1->z / pV2->z;
|
||||
pOut->w = pV1->w / pV2->w;
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Multiplies a 4D vector by a matrix, the result is stored in pOut, and pOut is returned.
|
||||
kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM) {
|
||||
pOut->x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pV->w * pM->mat[12];
|
||||
pOut->y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pV->w * pM->mat[13];
|
||||
pOut->z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pV->w * pM->mat[14];
|
||||
|
@ -120,9 +144,13 @@ kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) {
|
|||
return pOut;
|
||||
}
|
||||
|
||||
kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) {
|
||||
return kmVec4MultiplyMat4(pOut, pV, pM);
|
||||
}
|
||||
|
||||
/// Loops through an input array transforming each vec4 by the matrix.
|
||||
kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
|
||||
const kmVec4* pV, unsigned int vStride, const kmMat4* pM, unsigned int count) {
|
||||
const kmVec4* pV, unsigned int vStride, const kmMat4* pM, unsigned int count) {
|
||||
unsigned int i = 0;
|
||||
//Go through all of the vectors
|
||||
while (i < count) {
|
||||
|
@ -136,19 +164,19 @@ kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
|
|||
}
|
||||
|
||||
int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2) {
|
||||
return (
|
||||
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
|
||||
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon) &&
|
||||
(p1->z < p2->z + kmEpsilon && p1->z > p2->z - kmEpsilon) &&
|
||||
(p1->w < p2->w + kmEpsilon && p1->w > p2->w - kmEpsilon)
|
||||
);
|
||||
return (
|
||||
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
|
||||
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon) &&
|
||||
(p1->z < p2->z + kmEpsilon && p1->z > p2->z - kmEpsilon) &&
|
||||
(p1->w < p2->w + kmEpsilon && p1->w > p2->w - kmEpsilon)
|
||||
);
|
||||
}
|
||||
|
||||
kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn) {
|
||||
assert(pOut != pIn);
|
||||
assert(pOut != pIn);
|
||||
|
||||
memcpy(pOut, pIn, sizeof(float) * 4);
|
||||
memcpy(pOut, pIn, sizeof(kmScalar) * 4);
|
||||
|
||||
return pOut;
|
||||
return pOut;
|
||||
}
|
||||
|
|
@ -34,11 +34,12 @@ struct kmMat4;
|
|||
#pragma pack(push) /* push current alignment to stack */
|
||||
#pragma pack(1) /* set alignment to 1 byte boundary */
|
||||
|
||||
typedef struct kmVec4 {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
kmScalar w;
|
||||
typedef struct kmVec4
|
||||
{
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
kmScalar w;
|
||||
} kmVec4;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
@ -56,10 +57,14 @@ CC_DLL kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2, km
|
|||
CC_DLL kmVec4* kmVec4Normalize(kmVec4* pOut, const kmVec4* pIn);
|
||||
CC_DLL kmVec4* kmVec4Scale(kmVec4* pOut, const kmVec4* pIn, const kmScalar s); ///< Scales a vector to length s
|
||||
CC_DLL kmVec4* kmVec4Subtract(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2);
|
||||
CC_DLL kmVec4* kmVec4Mul( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 );
|
||||
CC_DLL kmVec4* kmVec4Div( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 );
|
||||
|
||||
CC_DLL kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM);
|
||||
CC_DLL kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM);
|
||||
CC_DLL kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
|
||||
const kmVec4* pV, unsigned int vStride, const struct kmMat4* pM, unsigned int count);
|
||||
CC_DLL int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2);
|
||||
const kmVec4* pV, unsigned int vStride, const struct kmMat4* pM, unsigned int count);
|
||||
CC_DLL int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2);
|
||||
CC_DLL kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn);
|
||||
|
||||
#ifdef __cplusplus
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#ADD_LIBRARY(Kazmath STATIC ${KAZMATH_SRCS})
|
||||
#INSTALL(TARGETS Kazmath ARCHIVE DESTINATION lib)
|
||||
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include )
|
||||
|
||||
ADD_LIBRARY(kazmath STATIC ${KAZMATH_SOURCES})
|
||||
INSTALL(TARGETS kazmath ARCHIVE DESTINATION lib)
|
||||
|
||||
#ADD_LIBRARY(KazmathGL STATIC ${GL_UTILS_SRCS})
|
||||
#INSTALL(TARGETS KazmathGL ARCHIVE DESTINATION lib)
|
||||
|
||||
INSTALL(FILES ${KAZMATH_HEADERS} DESTINATION include/kazmath)
|
||||
INSTALL(FILES ${GL_UTILS_HEADERS} DESTINATION include/kazmath/GL)
|
|
@ -1,738 +0,0 @@
|
|||
------------------------------------------------------------
|
||||
revno: 111
|
||||
committer: Kazade <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Thu 2010-08-19 12:07:29 +0100
|
||||
message:
|
||||
Fix #620352. Fix a reference to kmMat4RotationAxisAngle
|
||||
------------------------------------------------------------
|
||||
revno: 110
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2010-04-21 12:55:39 +0200
|
||||
message:
|
||||
applied the change to the header files as well
|
||||
------------------------------------------------------------
|
||||
revno: 109
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2010-04-21 12:54:06 +0200
|
||||
message:
|
||||
fixed kmMat4RotationAxis
|
||||
------------------------------------------------------------
|
||||
revno: 108 [merge]
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2010-04-21 12:27:53 +0200
|
||||
message:
|
||||
fixed CMake in kazmathxx due to missing utility.h
|
||||
------------------------------------------------------------
|
||||
revno: 107
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2010-04-21 12:22:40 +0200
|
||||
message:
|
||||
fixed mat4 rotation axis by normalizing the axis first
|
||||
------------------------------------------------------------
|
||||
revno: 106
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2010-01-09 16:56:04 +0000
|
||||
message:
|
||||
Add cmake module
|
||||
------------------------------------------------------------
|
||||
revno: 105
|
||||
committer: Luke Benstead <luke@Hydrogen>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2010-01-09 16:23:31 +0000
|
||||
message:
|
||||
Remove kazmodel - it really should belong in its own repo
|
||||
------------------------------------------------------------
|
||||
revno: 104
|
||||
committer: Luke Benstead <luke@Hydrogen>
|
||||
branch nick: kazmath
|
||||
timestamp: Fri 2010-01-08 23:03:13 +0000
|
||||
message:
|
||||
Reorganize the headers so that the tests can compile in place
|
||||
------------------------------------------------------------
|
||||
revno: 103
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-08-31 11:21:42 +0200
|
||||
message:
|
||||
Operators now inline, constructors fixed
|
||||
------------------------------------------------------------
|
||||
revno: 102
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-29 11:42:59 +0200
|
||||
message:
|
||||
fixed some compilation errors - still how do we define operators in headers correctly??
|
||||
------------------------------------------------------------
|
||||
revno: 101
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2009-08-26 10:37:52 +0100
|
||||
message:
|
||||
Added the header defines
|
||||
------------------------------------------------------------
|
||||
revno: 100
|
||||
committer: Luke Benstead <luke@sidney>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2009-08-26 09:38:47 +0100
|
||||
message:
|
||||
Added a V2 for kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 99
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-08-02 08:08:26 +0100
|
||||
message:
|
||||
Added missing header file to one of the tests
|
||||
------------------------------------------------------------
|
||||
revno: 98
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 12:05:25 +0200
|
||||
message:
|
||||
No longer doing self assignment in kmMat4Inverse
|
||||
------------------------------------------------------------
|
||||
revno: 97
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 11:15:36 +0200
|
||||
message:
|
||||
Fixed kmMat4Inverse
|
||||
------------------------------------------------------------
|
||||
revno: 96
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:20:33 +0100
|
||||
message:
|
||||
Fixed some whitespace issues in plane.c
|
||||
------------------------------------------------------------
|
||||
revno: 95
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:17:01 +0100
|
||||
message:
|
||||
Rename kmAABBPointInBox to kmAABBContainsPoint
|
||||
------------------------------------------------------------
|
||||
revno: 94
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:16:28 +0100
|
||||
message:
|
||||
Implement kmAABBPointInBox
|
||||
------------------------------------------------------------
|
||||
revno: 93
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:14:00 +0100
|
||||
message:
|
||||
Implement kmAABBAssign
|
||||
------------------------------------------------------------
|
||||
revno: 92
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:10:36 +0100
|
||||
message:
|
||||
Fixed some whitespace and added some comments
|
||||
------------------------------------------------------------
|
||||
revno: 91
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 08:56:13 +0100
|
||||
message:
|
||||
Implemented (untested) kmMat4RotationTranslation to construct a 4x4 matrix from a 3x3 + vec3
|
||||
------------------------------------------------------------
|
||||
revno: 90
|
||||
committer: Luke Benstead <luke@hydrogen>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-07-05 07:55:45 +0100
|
||||
message:
|
||||
Added kmMat3RotationX, kmMat3RotationY and kmMat3RotationZ
|
||||
------------------------------------------------------------
|
||||
revno: 89
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-06-27 09:38:20 +0200
|
||||
message:
|
||||
Fixed a crash?
|
||||
------------------------------------------------------------
|
||||
revno: 88
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Tue 2009-04-28 09:52:57 +0100
|
||||
message:
|
||||
Added a test for kmMat4Transpose
|
||||
------------------------------------------------------------
|
||||
revno: 87
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Tue 2009-04-28 08:49:59 +0100
|
||||
message:
|
||||
Added a commented test for kmMat4Inverse, however kmMat4Adjugate and kmMat4Determinate need implementing
|
||||
------------------------------------------------------------
|
||||
revno: 86
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Tue 2009-04-28 08:46:03 +0100
|
||||
message:
|
||||
Fixed bug in kmQuaternionRotationMatrix
|
||||
------------------------------------------------------------
|
||||
revno: 85
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Tue 2009-04-28 08:41:27 +0100
|
||||
message:
|
||||
Added missing include to test_mat3.cpp
|
||||
------------------------------------------------------------
|
||||
revno: 84
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 22:59:08 +0200
|
||||
message:
|
||||
fixed CMakeLists.txt for the tests
|
||||
------------------------------------------------------------
|
||||
revno: 83
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 21:34:20 +0100
|
||||
message:
|
||||
Added a test for kmMat3Translation
|
||||
------------------------------------------------------------
|
||||
revno: 82
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 21:32:19 +0100
|
||||
message:
|
||||
Fixed bugs in kmMat3Scaling and kmMat3Translation, added test for kmMat3Scaling
|
||||
------------------------------------------------------------
|
||||
revno: 81 [merge]
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 19:04:56 +0100
|
||||
message:
|
||||
Merge from upstream. Fixed mismatching prototype in quaternion.c
|
||||
------------------------------------------------------------
|
||||
revno: 80
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 19:01:35 +0100
|
||||
message:
|
||||
Added a test for kmMat3AreEqual. Fixed a bug in kmMat3AreEqual
|
||||
------------------------------------------------------------
|
||||
revno: 79
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 18:57:28 +0100
|
||||
message:
|
||||
Added a test for kmMat3IsIdentity
|
||||
------------------------------------------------------------
|
||||
revno: 78
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 18:54:48 +0100
|
||||
message:
|
||||
Added a test for kmMat3Identity
|
||||
------------------------------------------------------------
|
||||
revno: 77
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 18:52:14 +0100
|
||||
message:
|
||||
Added a test for kmMat3Fill
|
||||
------------------------------------------------------------
|
||||
revno: 76
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 18:46:30 +0100
|
||||
message:
|
||||
Added some mat3 unit tests. Fixed a bug in kmMat3AreEqual
|
||||
------------------------------------------------------------
|
||||
revno: 75
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 11:08:43 +0100
|
||||
message:
|
||||
Added mat4 test stub
|
||||
------------------------------------------------------------
|
||||
revno: 74
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 11:06:12 +0100
|
||||
message:
|
||||
Enabled unit testing in cmake
|
||||
------------------------------------------------------------
|
||||
revno: 73
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 10:44:37 +0100
|
||||
message:
|
||||
Added cmakelists.txt to the tests subfolder
|
||||
------------------------------------------------------------
|
||||
revno: 72
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 10:37:34 +0100
|
||||
message:
|
||||
Added stub mat3 test file
|
||||
------------------------------------------------------------
|
||||
revno: 71
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 10:35:48 +0100
|
||||
message:
|
||||
Added tests folder for new boost::unit based tests
|
||||
------------------------------------------------------------
|
||||
revno: 70
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 14:25:48 +0200
|
||||
message:
|
||||
Fixed the new quaternion -> Matrix -> AngleAxis methods and added them to mat4
|
||||
------------------------------------------------------------
|
||||
revno: 69
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 12:40:08 +0100
|
||||
message:
|
||||
Added kazmodel to the kazlibs repo
|
||||
------------------------------------------------------------
|
||||
revno: 68 [merge]
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 12:34:27 +0100
|
||||
message:
|
||||
Merge from upstream
|
||||
------------------------------------------------------------
|
||||
revno: 67
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 12:33:43 +0100
|
||||
message:
|
||||
Reorganized bzr
|
||||
------------------------------------------------------------
|
||||
revno: 66
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 10:00:18 +0100
|
||||
message:
|
||||
Renamed kmMat3RotationAxis to kmMat3RotationAxisAngle to be more accurate
|
||||
------------------------------------------------------------
|
||||
revno: 65
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:57:19 +0100
|
||||
message:
|
||||
Fixed some compilation errors
|
||||
------------------------------------------------------------
|
||||
revno: 64
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:54:12 +0100
|
||||
message:
|
||||
Added untested implementation of kmMat3RotationToAxisAngle
|
||||
------------------------------------------------------------
|
||||
revno: 63
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:49:17 +0100
|
||||
message:
|
||||
Added stub for kmMat3RotationToAxisAngle()
|
||||
------------------------------------------------------------
|
||||
revno: 62
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:45:58 +0100
|
||||
message:
|
||||
Corrected a typo
|
||||
------------------------------------------------------------
|
||||
revno: 61
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:44:39 +0100
|
||||
message:
|
||||
Fixed broken Quaternion functions
|
||||
Added (untested) kmMat3RotationAxis()
|
||||
------------------------------------------------------------
|
||||
revno: 60
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-04-18 08:55:29 +0100
|
||||
message:
|
||||
Fixed some errors in the quaternion header.
|
||||
Changed kmQuaternionRotationMatrix to accept a kmMat3 instead of kmMat4
|
||||
------------------------------------------------------------
|
||||
revno: 59
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-04-18 08:42:38 +0100
|
||||
message:
|
||||
Added kmMat3RotationQuaternion
|
||||
------------------------------------------------------------
|
||||
revno: 58
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-05 11:58:29 +0200
|
||||
message:
|
||||
Added mat3
|
||||
------------------------------------------------------------
|
||||
revno: 57 [merge]
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-05 11:54:15 +0200
|
||||
message:
|
||||
Implemented mat4 and vec4 for kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 56
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-05 11:53:07 +0200
|
||||
message:
|
||||
Implemented mat4 and vec4 for kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 55
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Fri 2009-03-13 16:46:26 +0100
|
||||
message:
|
||||
added km::vec3 to kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 54
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Fri 2009-03-13 16:14:51 +0100
|
||||
message:
|
||||
Fixed: kmVec2 is no longer transformed by kmMat4\nAdded km::vec2
|
||||
------------------------------------------------------------
|
||||
revno: 53
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Fri 2009-03-13 15:38:53 +0100
|
||||
message:
|
||||
Added folder for kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 52 [merge]
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: trunk
|
||||
timestamp: Fri 2009-03-13 14:04:32 +0000
|
||||
message:
|
||||
Merge from upstream
|
||||
------------------------------------------------------------
|
||||
revno: 51
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: trunk
|
||||
timestamp: Fri 2009-03-13 14:00:14 +0000
|
||||
message:
|
||||
Fixed for C89
|
||||
------------------------------------------------------------
|
||||
revno: 50
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Tue 2008-12-30 12:45:23 +0100
|
||||
message:
|
||||
fixed kmGLTranslate
|
||||
------------------------------------------------------------
|
||||
revno: 49
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Tue 2008-12-30 12:15:27 +0100
|
||||
message:
|
||||
fixed some stack memory leaks
|
||||
------------------------------------------------------------
|
||||
revno: 48
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Tue 2008-12-30 11:01:35 +0100
|
||||
message:
|
||||
The GL matrix stacks now work as expected - matrix multiplication was the wrong way round
|
||||
------------------------------------------------------------
|
||||
revno: 47
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Tue 2008-12-30 10:52:28 +0100
|
||||
message:
|
||||
Debug output
|
||||
------------------------------------------------------------
|
||||
revno: 46
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Mon 2008-12-29 18:32:13 +0100
|
||||
message:
|
||||
Fixed some compiler errors
|
||||
------------------------------------------------------------
|
||||
revno: 45
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Wed 2008-11-19 08:36:47 +0000
|
||||
message:
|
||||
Added kmGLTranslatef, kmGLScalef and kmGLRotatef
|
||||
------------------------------------------------------------
|
||||
revno: 44
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-11-04 20:57:30 +0000
|
||||
message:
|
||||
Fixed up kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 43
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Wed 2008-10-29 09:24:32 +0000
|
||||
message:
|
||||
Started implementing C++ operators in kazmathxx.h
|
||||
------------------------------------------------------------
|
||||
revno: 42
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 18:21:16 +0000
|
||||
message:
|
||||
Added kazmathxx.h for C++ usage
|
||||
------------------------------------------------------------
|
||||
revno: 41
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 11:00:41 +0000
|
||||
message:
|
||||
Added Doxygen documentation
|
||||
------------------------------------------------------------
|
||||
revno: 40
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:46:19 +0000
|
||||
message:
|
||||
Began documenting the kmPlane functions.
|
||||
Changed some assert(0)s to include a not implemented message
|
||||
------------------------------------------------------------
|
||||
revno: 39
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:42:24 +0000
|
||||
message:
|
||||
- Wrote stubs for the AABB functions which raise assertions if used.
|
||||
- Documented the AABB functions
|
||||
- Changed the definition of kmAABBPointInBox so that it actually makes sense
|
||||
------------------------------------------------------------
|
||||
revno: 38
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:38:48 +0000
|
||||
message:
|
||||
- Documented utility.c
|
||||
------------------------------------------------------------
|
||||
revno: 37
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:36:30 +0000
|
||||
message:
|
||||
- Documented vec3.c in detail.
|
||||
- Fixed up a not-implemented assertion.
|
||||
- Changed existing doc strings to C style - /** */
|
||||
------------------------------------------------------------
|
||||
revno: 36
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:30:00 +0000
|
||||
message:
|
||||
Removed uneccessary files from git
|
||||
------------------------------------------------------------
|
||||
revno: 35
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:28:49 +0000
|
||||
message:
|
||||
- Documented all the functions in mat4.c
|
||||
- Fixed up all asserts in mat4.c to include a message
|
||||
- Tidied up the code. Mat4.c is now done.
|
||||
------------------------------------------------------------
|
||||
revno: 34
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:52:33 +0000
|
||||
message:
|
||||
Added potential 0.1 release binary
|
||||
------------------------------------------------------------
|
||||
revno: 33
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:46:55 +0000
|
||||
message:
|
||||
Changed the README to include the BSD license
|
||||
------------------------------------------------------------
|
||||
revno: 32
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:45:51 +0000
|
||||
message:
|
||||
Added the modified BSD license to all source files
|
||||
------------------------------------------------------------
|
||||
revno: 31
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:11:51 +0000
|
||||
message:
|
||||
Fixed the installation of header files in CMake
|
||||
------------------------------------------------------------
|
||||
revno: 30
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:05:51 +0000
|
||||
message:
|
||||
Added kazmath project files
|
||||
------------------------------------------------------------
|
||||
revno: 29 [merge]
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:03:22 +0000
|
||||
message:
|
||||
Merge branch 'master' of git@github.com:Kazade/kazmath
|
||||
------------------------------------------------------------
|
||||
revno: 28
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:02:04 +0000
|
||||
message:
|
||||
Finally got kazmath compiling on VC++, man that compiler sucks! Have MS not heard of C99?
|
||||
------------------------------------------------------------
|
||||
revno: 27
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 21:35:24 +0000
|
||||
message:
|
||||
Changed the readme slightly, we need to change the license everywhere
|
||||
------------------------------------------------------------
|
||||
revno: 26
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 21:21:47 +0000
|
||||
message:
|
||||
Implemented the stacks test, fixed the undefined references I was getting
|
||||
------------------------------------------------------------
|
||||
revno: 25
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 20:59:34 +0000
|
||||
message:
|
||||
Removed the old matrix stack stuff
|
||||
------------------------------------------------------------
|
||||
revno: 24
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 20:11:58 +0000
|
||||
message:
|
||||
Started implementing the matrix stack tests
|
||||
------------------------------------------------------------
|
||||
revno: 23
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 10:56:51 +0000
|
||||
message:
|
||||
Started new implementation of the GL matrix stack
|
||||
------------------------------------------------------------
|
||||
revno: 22
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Thu 2008-08-28 12:37:41 +0200
|
||||
message:
|
||||
Added kmGLRotation
|
||||
------------------------------------------------------------
|
||||
revno: 21
|
||||
committer: Luke Benstead <luke@helium.(none)>
|
||||
timestamp: Thu 2008-08-28 09:24:00 +0100
|
||||
message:
|
||||
We now have a working matrix stack
|
||||
------------------------------------------------------------
|
||||
revno: 20
|
||||
committer: Luke Benstead <luke@helium.(none)>
|
||||
timestamp: Wed 2008-08-27 13:34:49 +0100
|
||||
message:
|
||||
Fixed the stack memory constants
|
||||
------------------------------------------------------------
|
||||
revno: 19
|
||||
committer: Luke Benstead <luke@helium.(none)>
|
||||
timestamp: Wed 2008-08-27 13:33:12 +0100
|
||||
message:
|
||||
Added the initial gl_utils implementation for replacing the matrix functionality deprecated in OpenGL 3.0
|
||||
------------------------------------------------------------
|
||||
revno: 18
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Mon 2008-08-25 12:46:16 +0200
|
||||
message:
|
||||
Fixed a bug in kmMat4LookAt
|
||||
------------------------------------------------------------
|
||||
revno: 17 [merge]
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-24 22:07:49 +0200
|
||||
message:
|
||||
Merge branch 'master' of git@github.com:Kazade/kazmath
|
||||
------------------------------------------------------------
|
||||
revno: 16
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-24 22:06:45 +0200
|
||||
message:
|
||||
Added kmMat4LookAt
|
||||
------------------------------------------------------------
|
||||
revno: 15
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Wed 2008-08-20 11:18:10 +0200
|
||||
message:
|
||||
Added Fill methods for all Vec and Mat structs
|
||||
------------------------------------------------------------
|
||||
revno: 14
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Tue 2008-08-19 22:31:55 +0200
|
||||
message:
|
||||
Added UnitTests, changed bool to int and fixed some minor bugs
|
||||
------------------------------------------------------------
|
||||
revno: 13
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-17 23:19:21 +0200
|
||||
message:
|
||||
removed .svn entries which did not belong here
|
||||
------------------------------------------------------------
|
||||
revno: 12
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-17 23:17:07 +0200
|
||||
message:
|
||||
some tweaks on matrices and first test-app, PerspectiveProjection is correct !
|
||||
------------------------------------------------------------
|
||||
revno: 11
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-17 16:04:09 +0200
|
||||
message:
|
||||
Renamed cotangent to cotangens
|
||||
------------------------------------------------------------
|
||||
revno: 10
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sat 2008-08-16 21:51:22 +0100
|
||||
message:
|
||||
Added kmMat4PerspectiveProjection and kmMat4OrthographicProjection
|
||||
------------------------------------------------------------
|
||||
revno: 9
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 21:15:45 +0100
|
||||
message:
|
||||
Added the aabb struct
|
||||
------------------------------------------------------------
|
||||
revno: 8
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 17:57:43 +0100
|
||||
message:
|
||||
Added the kmAABB structure
|
||||
------------------------------------------------------------
|
||||
revno: 7
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 14:32:24 +0100
|
||||
message:
|
||||
Fixed broken kmMat3Transpose
|
||||
------------------------------------------------------------
|
||||
revno: 6
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 14:21:04 +0100
|
||||
message:
|
||||
Fixed broken kmMat4Translation, w component was not set
|
||||
------------------------------------------------------------
|
||||
revno: 5
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 14:01:47 +0100
|
||||
message:
|
||||
Added mat3.c and mat3.h to the cmake file
|
||||
------------------------------------------------------------
|
||||
revno: 4
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 13:56:26 +0100
|
||||
message:
|
||||
Added the authors section to the readme
|
||||
------------------------------------------------------------
|
||||
revno: 3
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 13:55:41 +0100
|
||||
message:
|
||||
Updated the readme file
|
||||
------------------------------------------------------------
|
||||
revno: 2
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 13:53:26 +0100
|
||||
message:
|
||||
Added kazmath to git
|
||||
------------------------------------------------------------
|
||||
revno: 1
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 13:47:51 +0100
|
||||
message:
|
||||
First commit
|
||||
------------------------------------------------------------
|
||||
Use --include-merges or -n0 to see merged revisions.
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "kazmath/aabb.h"
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if point is in the specified AABB, returns
|
||||
* KM_FALSE otherwise.
|
||||
*/
|
||||
const int kmAABBContainsPoint(const kmVec3* pPoint, const kmAABB* pBox)
|
||||
{
|
||||
if(pPoint->x >= pBox->min.x && pPoint->x <= pBox->max.x &&
|
||||
pPoint->y >= pBox->min.y && pPoint->y <= pBox->max.y &&
|
||||
pPoint->z >= pBox->min.z && pPoint->z <= pBox->max.z) {
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut, returns pOut.
|
||||
*/
|
||||
kmAABB* const kmAABBAssign(kmAABB* pOut, const kmAABB* pIn)
|
||||
{
|
||||
kmVec3Assign(&pOut->min, &pIn->min);
|
||||
kmVec3Assign(&pOut->max, &pIn->max);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales pIn by s, stores the resulting AABB in pOut. Returns pOut
|
||||
*/
|
||||
kmAABB* const kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,372 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "kazmath/vec3.h"
|
||||
#include "kazmath/mat3.h"
|
||||
#include "kazmath/quaternion.h"
|
||||
|
||||
kmMat3* const kmMat3Fill(kmMat3* pOut, const kmScalar* pMat)
|
||||
{
|
||||
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 9);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Sets pOut to an identity matrix returns pOut*/
|
||||
kmMat3* const kmMat3Identity(kmMat3* pOut)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(float) * 9);
|
||||
pOut->mat[0] = pOut->mat[4] = pOut->mat[8] = 1.0f;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
const kmScalar kmMat3Determinant(const kmMat3* pIn)
|
||||
{
|
||||
kmScalar output;
|
||||
/*
|
||||
calculating the determinant following the rule of sarus,
|
||||
| 0 3 6 | 0 3 |
|
||||
m = | 1 4 7 | 1 4 |
|
||||
| 2 5 8 | 2 5 |
|
||||
now sum up the products of the diagonals going to the right (i.e. 0,4,8)
|
||||
and subtract the products of the other diagonals (i.e. 2,4,6)
|
||||
*/
|
||||
|
||||
output = pIn->mat[0] * pIn->mat[4] * pIn->mat[8] + pIn->mat[1] * pIn->mat[5] * pIn->mat[6] + pIn->mat[2] * pIn->mat[3] * pIn->mat[7];
|
||||
output -= pIn->mat[2] * pIn->mat[4] * pIn->mat[6] + pIn->mat[0] * pIn->mat[5] * pIn->mat[7] + pIn->mat[1] * pIn->mat[3] * pIn->mat[8];
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
kmMat3* const kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
pOut->mat[0] = pIn->mat[4] * pIn->mat[8] - pIn->mat[5] * pIn->mat[7];
|
||||
pOut->mat[1] = pIn->mat[2] * pIn->mat[7] - pIn->mat[1] * pIn->mat[8];
|
||||
pOut->mat[2] = pIn->mat[1] * pIn->mat[5] - pIn->mat[2] * pIn->mat[4];
|
||||
pOut->mat[3] = pIn->mat[5] * pIn->mat[6] - pIn->mat[3] * pIn->mat[8];
|
||||
pOut->mat[4] = pIn->mat[0] * pIn->mat[8] - pIn->mat[2] * pIn->mat[6];
|
||||
pOut->mat[5] = pIn->mat[2] * pIn->mat[3] - pIn->mat[0] * pIn->mat[5];
|
||||
pOut->mat[6] = pIn->mat[3] * pIn->mat[7] - pIn->mat[4] * pIn->mat[6];
|
||||
|
||||
// XXX: pIn->mat[9] is invalid!
|
||||
// pOut->mat[7] = pIn->mat[1] * pIn->mat[6] - pIn->mat[9] * pIn->mat[7];
|
||||
pOut->mat[8] = pIn->mat[0] * pIn->mat[4] - pIn->mat[1] * pIn->mat[3];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* const kmMat3Inverse(kmMat3* pOut, const kmScalar pDeterminate, const kmMat3* pM)
|
||||
{
|
||||
kmScalar detInv;
|
||||
kmMat3 adjugate;
|
||||
|
||||
if(pDeterminate == 0.0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
detInv = 1.0f / pDeterminate;
|
||||
|
||||
kmMat3Adjugate(&adjugate, pM);
|
||||
kmMat3ScalarMultiply(pOut, &adjugate, detInv);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Returns true if pIn is an identity matrix */
|
||||
const int kmMat3IsIdentity(const kmMat3* pIn)
|
||||
{
|
||||
static const float identity [] = { 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f};
|
||||
|
||||
return (memcmp(identity, pIn->mat, sizeof(float) * 9) == 0);
|
||||
}
|
||||
|
||||
/** Sets pOut to the transpose of pIn, returns pOut */
|
||||
kmMat3* const kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
int z, x;
|
||||
for (z = 0; z < 3; ++z) {
|
||||
for (x = 0; x < 3; ++x) {
|
||||
pOut->mat[(z * 3) + x] = pIn->mat[(x * 3) + z];
|
||||
}
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/* Multiplies pM1 with pM2, stores the result in pOut, returns pOut */
|
||||
kmMat3* const kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2)
|
||||
{
|
||||
float mat[9];
|
||||
|
||||
const float *m1 = pM1->mat, *m2 = pM2->mat;
|
||||
|
||||
mat[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2];
|
||||
mat[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2];
|
||||
mat[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2];
|
||||
|
||||
mat[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5];
|
||||
mat[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5];
|
||||
mat[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5];
|
||||
|
||||
mat[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8];
|
||||
mat[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8];
|
||||
mat[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8];
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(float)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* const kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor)
|
||||
{
|
||||
float mat[9];
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 9; i++)
|
||||
{
|
||||
mat[i] = pM->mat[i] * pFactor;
|
||||
}
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(float)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Assigns the value of pIn to pOut */
|
||||
kmMat3* const kmMat3Assign(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
assert(pOut != pIn); //You have tried to self-assign!!
|
||||
|
||||
memcpy(pOut->mat, pIn->mat, sizeof(float)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Returns true if the 2 matrices are equal (approximately) */
|
||||
const int kmMat3AreEqual(const kmMat3* pMat1, const kmMat3* pMat2)
|
||||
{
|
||||
int i;
|
||||
if (pMat1 == pMat2) {
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
|
||||
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/* Rotation around the z axis so everything stays planar in XY */
|
||||
kmMat3* const kmMat3Rotation(kmMat3* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 |
|
||||
M = | sin(A) cos(A) 0 |
|
||||
| 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = -sinf(radians);;
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Builds a scaling matrix */
|
||||
kmMat3* const kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y)
|
||||
{
|
||||
// memset(pOut->mat, 0, sizeof(float) * 9);
|
||||
kmMat3Identity(pOut);
|
||||
pOut->mat[0] = x;
|
||||
pOut->mat[4] = y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* const kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y)
|
||||
{
|
||||
// memset(pOut->mat, 0, sizeof(float) * 9);
|
||||
kmMat3Identity(pOut);
|
||||
pOut->mat[6] = x;
|
||||
pOut->mat[7] = y;
|
||||
// pOut->mat[8] = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
kmMat3* const kmMat3RotationQuaternion(kmMat3* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
if (!pIn || !pOut) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// First row
|
||||
pOut->mat[0] = 1.0f - 2.0f * (pIn->y * pIn->y + pIn->z * pIn->z);
|
||||
pOut->mat[1] = 2.0f * (pIn->x * pIn->y - pIn->w * pIn->z);
|
||||
pOut->mat[2] = 2.0f * (pIn->x * pIn->z + pIn->w * pIn->y);
|
||||
|
||||
// Second row
|
||||
pOut->mat[3] = 2.0f * (pIn->x * pIn->y + pIn->w * pIn->z);
|
||||
pOut->mat[4] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->z * pIn->z);
|
||||
pOut->mat[5] = 2.0f * (pIn->y * pIn->z - pIn->w * pIn->x);
|
||||
|
||||
// Third row
|
||||
pOut->mat[6] = 2.0f * (pIn->x * pIn->z - pIn->w * pIn->y);
|
||||
pOut->mat[7] = 2.0f * (pIn->y * pIn->z + pIn->w * pIn->x);
|
||||
pOut->mat[8] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->y * pIn->y);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians)
|
||||
{
|
||||
float rcos = cosf(radians);
|
||||
float rsin = sinf(radians);
|
||||
|
||||
pOut->mat[0] = rcos + axis->x * axis->x * (1 - rcos);
|
||||
pOut->mat[1] = axis->z * rsin + axis->y * axis->x * (1 - rcos);
|
||||
pOut->mat[2] = -axis->y * rsin + axis->z * axis->x * (1 - rcos);
|
||||
|
||||
pOut->mat[3] = -axis->z * rsin + axis->x * axis->y * (1 - rcos);
|
||||
pOut->mat[4] = rcos + axis->y * axis->y * (1 - rcos);
|
||||
pOut->mat[5] = axis->x * rsin + axis->z * axis->y * (1 - rcos);
|
||||
|
||||
pOut->mat[6] = axis->y * rsin + axis->x * axis->z * (1 - rcos);
|
||||
pOut->mat[7] = -axis->x * rsin + axis->y * axis->z * (1 - rcos);
|
||||
pOut->mat[8] = rcos + axis->z * axis->z * (1 - rcos);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* const kmMat3RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn)
|
||||
{
|
||||
/*Surely not this easy?*/
|
||||
kmQuaternion temp;
|
||||
kmQuaternionRotationMatrix(&temp, pIn);
|
||||
kmQuaternionToAxisAngle(&temp, pAxis, radians);
|
||||
return pAxis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
|
||||
*/
|
||||
kmMat3* const kmMat3RotationX(kmMat3* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| 1 0 0 |
|
||||
M = | 0 cos(A) -sin(A) |
|
||||
| 0 sin(A) cos(A) |
|
||||
|
||||
*/
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = 0.0f;
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = sinf(radians);
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = -sinf(radians);
|
||||
pOut->mat[8] = cosf(radians);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix using the rotation around the Y-axis
|
||||
* The result is stored in pOut, pOut is returned.
|
||||
*/
|
||||
kmMat3* const kmMat3RotationY(kmMat3* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) 0 sin(A) |
|
||||
M = | 0 1 0 |
|
||||
| -sin(A) 0 cos(A) |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = -sinf(radians);
|
||||
|
||||
pOut->mat[3] = 0.0f;
|
||||
pOut->mat[4] = 1.0f;
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = sinf(radians);
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = cosf(radians);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix around the Z-axis. The resulting
|
||||
* matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat3* const kmMat3RotationZ(kmMat3* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 |
|
||||
M = | sin(A) cos(A) 0 |
|
||||
| 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] =-sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = sinf(radians);;
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -1,792 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file mat4.c
|
||||
*/
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "kazmath/vec3.h"
|
||||
#include "kazmath/mat4.h"
|
||||
#include "kazmath/mat3.h"
|
||||
#include "kazmath/quaternion.h"
|
||||
#include "kazmath/plane.h"
|
||||
|
||||
#include "kazmath/neon_matrix_impl.h"
|
||||
|
||||
/**
|
||||
* Fills a kmMat4 structure with the values from a 16
|
||||
* element array of floats
|
||||
* @Params pOut - A pointer to the destination matrix
|
||||
* pMat - A 16 element array of floats
|
||||
* @Return Returns pOut so that the call can be nested
|
||||
*/
|
||||
kmMat4* const kmMat4Fill(kmMat4* pOut, const kmScalar* pMat)
|
||||
{
|
||||
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 16);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pOut to an identity matrix returns pOut
|
||||
* @Params pOut - A pointer to the matrix to set to identity
|
||||
* @Return Returns pOut so that the call can be nested
|
||||
*/
|
||||
kmMat4* const kmMat4Identity(kmMat4* pOut)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(float) * 16);
|
||||
pOut->mat[0] = pOut->mat[5] = pOut->mat[10] = pOut->mat[15] = 1.0f;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
float get(const kmMat4 * pIn, int row, int col)
|
||||
{
|
||||
return pIn->mat[row + 4*col];
|
||||
}
|
||||
|
||||
void set(kmMat4 * pIn, int row, int col, float value)
|
||||
{
|
||||
pIn->mat[row + 4*col] = value;
|
||||
}
|
||||
|
||||
void swap(kmMat4 * pIn, int r1, int c1, int r2, int c2)
|
||||
{
|
||||
float tmp = get(pIn,r1,c1);
|
||||
set(pIn,r1,c1,get(pIn,r2,c2));
|
||||
set(pIn,r2,c2, tmp);
|
||||
}
|
||||
|
||||
//Returns an upper and a lower triangular matrix which are L and R in the Gauss algorithm
|
||||
int gaussj(kmMat4 *a, kmMat4 *b)
|
||||
{
|
||||
int i, icol = 0, irow = 0, j, k, l, ll, n = 4, m = 4;
|
||||
float big, dum, pivinv;
|
||||
int indxc[4] = {0};
|
||||
int indxr[4] = {0};
|
||||
int ipiv[4] = {0};
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
ipiv[j] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
big = 0.0f;
|
||||
for (j = 0; j < n; j++) {
|
||||
if (ipiv[j] != 1) {
|
||||
for (k = 0; k < n; k++) {
|
||||
if (ipiv[k] == 0) {
|
||||
if (abs(get(a,j, k)) >= big) {
|
||||
big = abs(get(a,j, k));
|
||||
irow = j;
|
||||
icol = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++(ipiv[icol]);
|
||||
if (irow != icol) {
|
||||
for (l = 0; l < n; l++) {
|
||||
swap(a,irow, l, icol, l);
|
||||
}
|
||||
for (l = 0; l < m; l++) {
|
||||
swap(b,irow, l, icol, l);
|
||||
}
|
||||
}
|
||||
indxr[i] = irow;
|
||||
indxc[i] = icol;
|
||||
if (get(a,icol, icol) == 0.0) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
pivinv = 1.0f / get(a,icol, icol);
|
||||
set(a,icol, icol, 1.0f);
|
||||
for (l = 0; l < n; l++) {
|
||||
set(a,icol, l, get(a,icol, l) * pivinv);
|
||||
}
|
||||
for (l = 0; l < m; l++) {
|
||||
set(b,icol, l, get(b,icol, l) * pivinv);
|
||||
}
|
||||
|
||||
for (ll = 0; ll < n; ll++) {
|
||||
if (ll != icol) {
|
||||
dum = get(a,ll, icol);
|
||||
set(a,ll, icol, 0.0f);
|
||||
for (l = 0; l < n; l++) {
|
||||
set(a,ll, l, get(a,ll, l) - get(a,icol, l) * dum);
|
||||
}
|
||||
for (l = 0; l < m; l++) {
|
||||
set(b,ll, l, get(a,ll, l) - get(b,icol, l) * dum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// This is the end of the main loop over columns of the reduction. It only remains to unscram-
|
||||
// ble the solution in view of the column interchanges. We do this by interchanging pairs of
|
||||
// columns in the reverse order that the permutation was built up.
|
||||
for (l = n - 1; l >= 0; l--) {
|
||||
if (indxr[l] != indxc[l]) {
|
||||
for (k = 0; k < n; k++) {
|
||||
swap(a,k, indxr[l], k, indxc[l]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the inverse of pM and stores the result in
|
||||
* pOut.
|
||||
* @Return Returns NULL if there is no inverse, else pOut
|
||||
*/
|
||||
kmMat4* const kmMat4Inverse(kmMat4* pOut, const kmMat4* pM)
|
||||
{
|
||||
kmMat4 inv;
|
||||
kmMat4 tmp;
|
||||
|
||||
kmMat4Assign(&inv, pM);
|
||||
|
||||
kmMat4Identity(&tmp);
|
||||
|
||||
if(gaussj(&inv, &tmp) == KM_FALSE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmMat4Assign(pOut, &inv);
|
||||
return pOut;
|
||||
}
|
||||
/**
|
||||
* Returns KM_TRUE if pIn is an identity matrix
|
||||
* KM_FALSE otherwise
|
||||
*/
|
||||
const int kmMat4IsIdentity(const kmMat4* pIn)
|
||||
{
|
||||
static const float identity [] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
return (memcmp(identity, pIn->mat, sizeof(float) * 16) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pOut to the transpose of pIn, returns pOut
|
||||
*/
|
||||
kmMat4* const kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn)
|
||||
{
|
||||
int x, z;
|
||||
|
||||
for (z = 0; z < 4; ++z) {
|
||||
for (x = 0; x < 4; ++x) {
|
||||
pOut->mat[(z * 4) + x] = pIn->mat[(x * 4) + z];
|
||||
}
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies pM1 with pM2, stores the result in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* const kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2)
|
||||
{
|
||||
#if defined(__ARM_NEON__) && !defined(__arm64__)
|
||||
|
||||
// It is possible to skip the memcpy() since "out" does not overwrite p1 or p2.
|
||||
// otherwise a temp must be needed.
|
||||
float *mat = pOut->mat;
|
||||
|
||||
// Invert column-order with row-order
|
||||
NEON_Matrix4Mul( &pM2->mat[0], &pM1->mat[0], &mat[0] );
|
||||
|
||||
#else
|
||||
float mat[16];
|
||||
|
||||
const float *m1 = pM1->mat, *m2 = pM2->mat;
|
||||
|
||||
mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
|
||||
mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
|
||||
mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
|
||||
mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
|
||||
|
||||
mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
|
||||
mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
|
||||
mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
|
||||
mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
|
||||
|
||||
mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
|
||||
mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
|
||||
mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
|
||||
mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
|
||||
|
||||
mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
|
||||
mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
|
||||
mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
|
||||
mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(pOut->mat));
|
||||
|
||||
#endif
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the value of pIn to pOut
|
||||
*/
|
||||
kmMat4* const kmMat4Assign(kmMat4* pOut, const kmMat4* pIn)
|
||||
{
|
||||
assert(pOut != pIn && "You have tried to self-assign!!");
|
||||
|
||||
memcpy(pOut->mat, pIn->mat, sizeof(float)*16);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if the 2 matrices are equal (approximately)
|
||||
*/
|
||||
const int kmMat4AreEqual(const kmMat4* pMat1, const kmMat4* pMat2)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
assert(pMat1 != pMat2 && "You are comparing the same thing!");
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
|
||||
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a rotation matrix from an axis and an angle. Result is stored in pOut.
|
||||
* pOut is returned.
|
||||
*/
|
||||
kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const kmVec3* axis, kmScalar radians)
|
||||
{
|
||||
float rcos = cosf(radians);
|
||||
float rsin = sinf(radians);
|
||||
|
||||
kmVec3 normalizedAxis;
|
||||
kmVec3Normalize(&normalizedAxis, axis);
|
||||
|
||||
pOut->mat[0] = rcos + normalizedAxis.x * normalizedAxis.x * (1 - rcos);
|
||||
pOut->mat[1] = normalizedAxis.z * rsin + normalizedAxis.y * normalizedAxis.x * (1 - rcos);
|
||||
pOut->mat[2] = -normalizedAxis.y * rsin + normalizedAxis.z * normalizedAxis.x * (1 - rcos);
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = -normalizedAxis.z * rsin + normalizedAxis.x * normalizedAxis.y * (1 - rcos);
|
||||
pOut->mat[5] = rcos + normalizedAxis.y * normalizedAxis.y * (1 - rcos);
|
||||
pOut->mat[6] = normalizedAxis.x * rsin + normalizedAxis.z * normalizedAxis.y * (1 - rcos);
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = normalizedAxis.y * rsin + normalizedAxis.x * normalizedAxis.z * (1 - rcos);
|
||||
pOut->mat[9] = -normalizedAxis.x * rsin + normalizedAxis.y * normalizedAxis.z * (1 - rcos);
|
||||
pOut->mat[10] = rcos + normalizedAxis.z * normalizedAxis.z * (1 - rcos);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* const kmMat4RotationX(kmMat4* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| 1 0 0 0 |
|
||||
M = | 0 cos(A) -sin(A) 0 |
|
||||
| 0 sin(A) cos(A) 0 |
|
||||
| 0 0 0 1 |
|
||||
|
||||
*/
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = 0.0f;
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = 0.0f;
|
||||
pOut->mat[5] = cosf(radians);
|
||||
pOut->mat[6] = sinf(radians);
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = 0.0f;
|
||||
pOut->mat[9] = -sinf(radians);
|
||||
pOut->mat[10] = cosf(radians);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix using the rotation around the Y-axis
|
||||
* The result is stored in pOut, pOut is returned.
|
||||
*/
|
||||
kmMat4* const kmMat4RotationY(kmMat4* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) 0 sin(A) 0 |
|
||||
M = | 0 1 0 0 |
|
||||
| -sin(A) 0 cos(A) 0 |
|
||||
| 0 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = -sinf(radians);
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = 0.0f;
|
||||
pOut->mat[5] = 1.0f;
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = sinf(radians);
|
||||
pOut->mat[9] = 0.0f;
|
||||
pOut->mat[10] = cosf(radians);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix around the Z-axis. The resulting
|
||||
* matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat4* const kmMat4RotationZ(kmMat4* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 0 |
|
||||
M = | sin(A) cos(A) 0 0 |
|
||||
| 0 0 1 0 |
|
||||
| 0 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = -sinf(radians);;
|
||||
pOut->mat[5] = cosf(radians);
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = 0.0f;
|
||||
pOut->mat[9] = 0.0f;
|
||||
pOut->mat[10] = 1.0f;
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix from pitch, yaw and roll. The resulting
|
||||
* matrix is stored in pOut and pOut is returned
|
||||
*/
|
||||
kmMat4* const kmMat4RotationPitchYawRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll)
|
||||
{
|
||||
double cr = cos(pitch);
|
||||
double sr = sin(pitch);
|
||||
double cp = cos(yaw);
|
||||
double sp = sin(yaw);
|
||||
double cy = cos(roll);
|
||||
double sy = sin(roll);
|
||||
double srsp = sr * sp;
|
||||
double crsp = cr * sp;
|
||||
|
||||
pOut->mat[0] = (kmScalar) cp * cy;
|
||||
pOut->mat[4] = (kmScalar) cp * sy;
|
||||
pOut->mat[8] = (kmScalar) - sp;
|
||||
|
||||
pOut->mat[1] = (kmScalar) srsp * cy - cr * sy;
|
||||
pOut->mat[5] = (kmScalar) srsp * sy + cr * cy;
|
||||
pOut->mat[9] = (kmScalar) sr * cp;
|
||||
|
||||
pOut->mat[2] = (kmScalar) crsp * cy + sr * sy;
|
||||
pOut->mat[6] = (kmScalar) crsp * sy - sr * cy;
|
||||
pOut->mat[10] = (kmScalar) cr * cp;
|
||||
|
||||
pOut->mat[3] = pOut->mat[7] = pOut->mat[11] = 0.0;
|
||||
pOut->mat[15] = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Converts a quaternion to a rotation matrix,
|
||||
* the result is stored in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* const kmMat4RotationQuaternion(kmMat4* pOut, const kmQuaternion* pQ)
|
||||
{
|
||||
pOut->mat[0] = 1.0f - 2.0f * (pQ->y * pQ->y + pQ->z * pQ->z );
|
||||
pOut->mat[1] = 2.0f * (pQ->x * pQ->y + pQ->z * pQ->w);
|
||||
pOut->mat[2] = 2.0f * (pQ->x * pQ->z - pQ->y * pQ->w);
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
// Second row
|
||||
pOut->mat[4] = 2.0f * ( pQ->x * pQ->y - pQ->z * pQ->w );
|
||||
pOut->mat[5] = 1.0f - 2.0f * ( pQ->x * pQ->x + pQ->z * pQ->z );
|
||||
pOut->mat[6] = 2.0f * (pQ->z * pQ->y + pQ->x * pQ->w );
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
// Third row
|
||||
pOut->mat[8] = 2.0f * ( pQ->x * pQ->z + pQ->y * pQ->w );
|
||||
pOut->mat[9] = 2.0f * ( pQ->y * pQ->z - pQ->x * pQ->w );
|
||||
pOut->mat[10] = 1.0f - 2.0f * ( pQ->x * pQ->x + pQ->y * pQ->y );
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
// Fourth row
|
||||
pOut->mat[12] = 0;
|
||||
pOut->mat[13] = 0;
|
||||
pOut->mat[14] = 0;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Builds a scaling matrix */
|
||||
kmMat4* const kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y,
|
||||
const kmScalar z)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(float) * 16);
|
||||
pOut->mat[0] = x;
|
||||
pOut->mat[5] = y;
|
||||
pOut->mat[10] = z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a translation matrix. All other elements in the matrix
|
||||
* will be set to zero except for the diagonal which is set to 1.0
|
||||
*/
|
||||
kmMat4* const kmMat4Translation(kmMat4* pOut, const kmScalar x,
|
||||
const kmScalar y, const kmScalar z)
|
||||
{
|
||||
//FIXME: Write a test for this
|
||||
memset(pOut->mat, 0, sizeof(float) * 16);
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[5] = 1.0f;
|
||||
pOut->mat[10] = 1.0f;
|
||||
|
||||
pOut->mat[12] = x;
|
||||
pOut->mat[13] = y;
|
||||
pOut->mat[14] = z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the up vector from a matrix. pIn is the matrix you
|
||||
* wish to extract the vector from. pOut is a pointer to the
|
||||
* kmVec3 structure that should hold the resulting vector
|
||||
*/
|
||||
kmVec3* const kmMat4GetUpVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->x = pIn->mat[4];
|
||||
pOut->y = pIn->mat[5];
|
||||
pOut->z = pIn->mat[6];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Extract the right vector from a 4x4 matrix. The result is
|
||||
* stored in pOut. Returns pOut.
|
||||
*/
|
||||
kmVec3* const kmMat4GetRightVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->x = pIn->mat[0];
|
||||
pOut->y = pIn->mat[1];
|
||||
pOut->z = pIn->mat[2];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the forward vector from a 4x4 matrix. The result is
|
||||
* stored in pOut. Returns pOut.
|
||||
*/
|
||||
kmVec3* const kmMat4GetForwardVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->x = pIn->mat[8];
|
||||
pOut->y = pIn->mat[9];
|
||||
pOut->z = pIn->mat[10];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a perspective projection matrix in the
|
||||
* same way as gluPerspective
|
||||
*/
|
||||
kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY,
|
||||
kmScalar aspect, kmScalar zNear,
|
||||
kmScalar zFar)
|
||||
{
|
||||
kmScalar r = kmDegreesToRadians(fovY / 2);
|
||||
kmScalar deltaZ = zFar - zNear;
|
||||
kmScalar s = sin(r);
|
||||
kmScalar cotangent = 0;
|
||||
|
||||
if (deltaZ == 0 || s == 0 || aspect == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//cos(r) / sin(r) = cot(r)
|
||||
cotangent = cos(r) / s;
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
pOut->mat[0] = cotangent / aspect;
|
||||
pOut->mat[5] = cotangent;
|
||||
pOut->mat[10] = -(zFar + zNear) / deltaZ;
|
||||
pOut->mat[11] = -1;
|
||||
pOut->mat[14] = -2 * zNear * zFar / deltaZ;
|
||||
pOut->mat[15] = 0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Creates an orthographic projection matrix like glOrtho */
|
||||
kmMat4* const kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left,
|
||||
kmScalar right, kmScalar bottom,
|
||||
kmScalar top, kmScalar nearVal,
|
||||
kmScalar farVal)
|
||||
{
|
||||
kmScalar tx = -((right + left) / (right - left));
|
||||
kmScalar ty = -((top + bottom) / (top - bottom));
|
||||
kmScalar tz = -((farVal + nearVal) / (farVal - nearVal));
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
pOut->mat[0] = 2 / (right - left);
|
||||
pOut->mat[5] = 2 / (top - bottom);
|
||||
pOut->mat[10] = -2 / (farVal - nearVal);
|
||||
pOut->mat[12] = tx;
|
||||
pOut->mat[13] = ty;
|
||||
pOut->mat[14] = tz;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a translation matrix in the same way as gluLookAt()
|
||||
* the resulting matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat4* const kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
|
||||
const kmVec3* pCenter, const kmVec3* pUp)
|
||||
{
|
||||
kmVec3 f, up, s, u;
|
||||
kmMat4 translate;
|
||||
|
||||
kmVec3Subtract(&f, pCenter, pEye);
|
||||
kmVec3Normalize(&f, &f);
|
||||
|
||||
kmVec3Assign(&up, pUp);
|
||||
kmVec3Normalize(&up, &up);
|
||||
|
||||
kmVec3Cross(&s, &f, &up);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmVec3Cross(&u, &s, &f);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
|
||||
pOut->mat[0] = s.x;
|
||||
pOut->mat[4] = s.y;
|
||||
pOut->mat[8] = s.z;
|
||||
|
||||
pOut->mat[1] = u.x;
|
||||
pOut->mat[5] = u.y;
|
||||
pOut->mat[9] = u.z;
|
||||
|
||||
pOut->mat[2] = -f.x;
|
||||
pOut->mat[6] = -f.y;
|
||||
pOut->mat[10] = -f.z;
|
||||
|
||||
kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z);
|
||||
kmMat4Multiply(pOut, pOut, &translate);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a 3x3 rotation matrix from the input 4x4 transformation.
|
||||
* Stores the result in pOut, returns pOut
|
||||
*/
|
||||
kmMat3* const kmMat4ExtractRotation(kmMat3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->mat[0] = pIn->mat[0];
|
||||
pOut->mat[1] = pIn->mat[1];
|
||||
pOut->mat[2] = pIn->mat[2];
|
||||
|
||||
pOut->mat[3] = pIn->mat[4];
|
||||
pOut->mat[4] = pIn->mat[5];
|
||||
pOut->mat[5] = pIn->mat[6];
|
||||
|
||||
pOut->mat[6] = pIn->mat[8];
|
||||
pOut->mat[7] = pIn->mat[9];
|
||||
pOut->mat[8] = pIn->mat[10];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians)
|
||||
* returns the output axis.
|
||||
*/
|
||||
kmVec3* const kmMat4RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn)
|
||||
{
|
||||
/*Surely not this easy?*/
|
||||
kmQuaternion temp;
|
||||
kmMat3 rotation;
|
||||
kmMat4ExtractRotation(&rotation, pIn);
|
||||
kmQuaternionRotationMatrix(&temp, &rotation);
|
||||
kmQuaternionToAxisAngle(&temp, pAxis, radians);
|
||||
return pAxis;
|
||||
}
|
||||
|
||||
/** Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix,
|
||||
* and a 3d vector representing a translation. Assign the result to pOut,
|
||||
* pOut is also returned.
|
||||
*/
|
||||
kmMat4* const kmMat4RotationTranslation(kmMat4* pOut, const kmMat3* rotation, const kmVec3* translation)
|
||||
{
|
||||
pOut->mat[0] = rotation->mat[0];
|
||||
pOut->mat[1] = rotation->mat[1];
|
||||
pOut->mat[2] = rotation->mat[2];
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = rotation->mat[3];
|
||||
pOut->mat[5] = rotation->mat[4];
|
||||
pOut->mat[6] = rotation->mat[5];
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = rotation->mat[6];
|
||||
pOut->mat[9] = rotation->mat[7];
|
||||
pOut->mat[10] = rotation->mat[8];
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = translation->x;
|
||||
pOut->mat[13] = translation->y;
|
||||
pOut->mat[14] = translation->z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* const kmMat4ExtractPlane(kmPlane* pOut, const kmMat4* pIn, const kmEnum plane)
|
||||
{
|
||||
float t = 1.0f;
|
||||
|
||||
switch(plane) {
|
||||
case KM_PLANE_RIGHT:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[0];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[4];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[8];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[12];
|
||||
break;
|
||||
case KM_PLANE_LEFT:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[0];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[4];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[8];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[12];
|
||||
break;
|
||||
case KM_PLANE_BOTTOM:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[1];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[5];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[9];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[13];
|
||||
break;
|
||||
case KM_PLANE_TOP:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[1];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[5];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[9];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[13];
|
||||
break;
|
||||
case KM_PLANE_FAR:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[2];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[6];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[10];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[14];
|
||||
break;
|
||||
case KM_PLANE_NEAR:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[2];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[6];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[10];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[14];
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Invalid plane index");
|
||||
}
|
||||
|
||||
t = sqrtf(pOut->a * pOut->a +
|
||||
pOut->b * pOut->b +
|
||||
pOut->c * pOut->c);
|
||||
pOut->a /= t;
|
||||
pOut->b /= t;
|
||||
pOut->c /= t;
|
||||
pOut->d /= t;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kazmath/vec3.h"
|
||||
#include "kazmath/vec4.h"
|
||||
#include "kazmath/plane.h"
|
||||
|
||||
const kmScalar kmPlaneDot(const kmPlane* pP, const kmVec4* pV)
|
||||
{
|
||||
//a*x + b*y + c*z + d*w
|
||||
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z +
|
||||
pP->d * pV->w);
|
||||
}
|
||||
|
||||
const kmScalar kmPlaneDotCoord(const kmPlane* pP, const kmVec3* pV)
|
||||
{
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z + pP->d);
|
||||
}
|
||||
|
||||
const kmScalar kmPlaneDotNormal(const kmPlane* pP, const kmVec3* pV)
|
||||
{
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z);
|
||||
}
|
||||
|
||||
kmPlane* const kmPlaneFromPointNormal(kmPlane* pOut, const kmVec3* pPoint, const kmVec3* pNormal)
|
||||
{
|
||||
/*
|
||||
Planea = Nx
|
||||
Planeb = Ny
|
||||
Planec = Nz
|
||||
Planed = −N⋅P
|
||||
*/
|
||||
|
||||
|
||||
pOut->a = pNormal->x;
|
||||
pOut->b = pNormal->y;
|
||||
pOut->c = pNormal->z;
|
||||
pOut->d = -kmVec3Dot(pNormal, pPoint);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a plane from 3 points. The result is stored in pOut.
|
||||
* pOut is returned.
|
||||
*/
|
||||
kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3)
|
||||
{
|
||||
/*
|
||||
v = (B − A) × (C − A)
|
||||
n = 1⁄|v| v
|
||||
Outa = nx
|
||||
Outb = ny
|
||||
Outc = nz
|
||||
Outd = −n⋅A
|
||||
*/
|
||||
|
||||
kmVec3 n, v1, v2;
|
||||
kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle
|
||||
kmVec3Subtract(&v2, p3, p1);
|
||||
kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal
|
||||
|
||||
kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* const kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
/*
|
||||
n = (Planea, Planeb, Planec)
|
||||
d = V − U
|
||||
Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0]
|
||||
*/
|
||||
kmVec3 d;
|
||||
assert(0 && "Not implemented");
|
||||
|
||||
|
||||
kmVec3Subtract(&d, pV2, pV1); //Get the direction vector
|
||||
|
||||
|
||||
//TODO: Continue here!
|
||||
/*if (fabs(kmVec3Dot(&pP->m_N, &d)) > kmEpsilon)
|
||||
{
|
||||
//If we get here then the plane and line are parallel (i.e. no intersection)
|
||||
pOut = nullptr; //Set to nullptr
|
||||
|
||||
return pOut;
|
||||
} */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmPlane* const kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP)
|
||||
{
|
||||
kmVec3 n;
|
||||
kmScalar l = 0;
|
||||
|
||||
n.x = pP->a;
|
||||
n.y = pP->b;
|
||||
n.z = pP->c;
|
||||
|
||||
l = 1.0f / kmVec3Length(&n); //Get 1/length
|
||||
kmVec3Normalize(&n, &n); //Normalize the vector and assign to pOut
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
|
||||
pOut->d = pP->d * l; //Scale the D value and assign to pOut
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* const kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns
|
||||
* POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise
|
||||
*/
|
||||
const POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP)
|
||||
{
|
||||
// This function will determine if a point is on, in front of, or behind
|
||||
// the plane. First we store the dot product of the plane and the point.
|
||||
float distance = pIn->a * pP->x + pIn->b * pP->y + pIn->c * pP->z + pIn->d;
|
||||
|
||||
// Simply put if the dot product is greater than 0 then it is infront of it.
|
||||
// If it is less than 0 then it is behind it. And if it is 0 then it is on it.
|
||||
if(distance > 0.001) return POINT_INFRONT_OF_PLANE;
|
||||
if(distance < -0.001) return POINT_BEHIND_PLANE;
|
||||
|
||||
return POINT_ON_PLANE;
|
||||
}
|
||||
|
|
@ -1,586 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "kazmath/mat3.h"
|
||||
#include "kazmath/vec3.h"
|
||||
#include "kazmath/quaternion.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
///< Returns pOut, sets pOut to the conjugate of pIn
|
||||
kmQuaternion* const kmQuaternionConjugate(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
pOut->x = -pIn->x;
|
||||
pOut->y = -pIn->y;
|
||||
pOut->z = -pIn->z;
|
||||
pOut->w = pIn->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns the dot product of the 2 quaternions
|
||||
const kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2)
|
||||
{
|
||||
// A dot B = B dot A = AtBt + AxBx + AyBy + AzBz
|
||||
|
||||
return (q1->w * q2->w +
|
||||
q1->x * q2->x +
|
||||
q1->y * q2->y +
|
||||
q1->z * q2->z);
|
||||
}
|
||||
|
||||
///< Returns the exponential of the quaternion
|
||||
kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
assert(0);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Makes the passed quaternion an identity quaternion
|
||||
kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns the inverse of the passed Quaternion
|
||||
kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
kmScalar l = kmQuaternionLength(pIn);
|
||||
kmQuaternion tmp;
|
||||
|
||||
if (fabs(l) > kmEpsilon)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 0.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///Get the conjugute and divide by the length
|
||||
kmQuaternionScale(pOut,
|
||||
kmQuaternionConjugate(&tmp, pIn), 1.0f / l);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns true if the quaternion is an identity quaternion
|
||||
int kmQuaternionIsIdentity(const kmQuaternion* pIn)
|
||||
{
|
||||
return (pIn->x == 0.0 && pIn->y == 0.0 && pIn->z == 0.0 &&
|
||||
pIn->w == 1.0);
|
||||
}
|
||||
|
||||
///< Returns the length of the quaternion
|
||||
kmScalar kmQuaternionLength(const kmQuaternion* pIn)
|
||||
{
|
||||
return sqrtf(kmQuaternionLengthSq(pIn));
|
||||
}
|
||||
|
||||
///< Returns the length of the quaternion squared (prevents a sqrt)
|
||||
kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn)
|
||||
{
|
||||
return pIn->x * pIn->x + pIn->y * pIn->y +
|
||||
pIn->z * pIn->z + pIn->w * pIn->w;
|
||||
}
|
||||
|
||||
///< Returns the natural logarithm
|
||||
kmQuaternion* kmQuaternionLn(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
/*
|
||||
A unit quaternion, is defined by:
|
||||
Q == (cos(theta), sin(theta) * v) where |v| = 1
|
||||
The natural logarithm of Q is, ln(Q) = (0, theta * v)
|
||||
*/
|
||||
|
||||
assert(0);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Multiplies 2 quaternions together
|
||||
extern
|
||||
kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut,
|
||||
const kmQuaternion* q1,
|
||||
const kmQuaternion* q2)
|
||||
{
|
||||
pOut->w = q1->w * q2->w - q1->x * q2->x - q1->y * q2->y - q1->z * q2->z;
|
||||
pOut->x = q1->w * q2->x + q1->x * q2->w + q1->y * q2->z - q1->z * q2->y;
|
||||
pOut->y = q1->w * q2->y + q1->y * q2->w + q1->z * q2->x - q1->x * q2->z;
|
||||
pOut->z = q1->w * q2->z + q1->z * q2->w + q1->x * q2->y - q1->y * q2->x;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Normalizes a quaternion
|
||||
kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
kmScalar length = kmQuaternionLength(pIn);
|
||||
assert(fabs(length) > kmEpsilon);
|
||||
kmQuaternionScale(pOut, pIn, 1.0f / length);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Rotates a quaternion around an axis
|
||||
kmQuaternion* kmQuaternionRotationAxis(kmQuaternion* pOut,
|
||||
const kmVec3* pV,
|
||||
kmScalar angle)
|
||||
{
|
||||
kmScalar rad = angle * 0.5f;
|
||||
kmScalar scale = sinf(rad);
|
||||
|
||||
pOut->w = cosf(rad);
|
||||
pOut->x = pV->x * scale;
|
||||
pOut->y = pV->y * scale;
|
||||
pOut->z = pV->z * scale;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Creates a quaternion from a rotation matrix
|
||||
kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut,
|
||||
const kmMat3* pIn)
|
||||
{
|
||||
/*
|
||||
Note: The OpenGL matrices are transposed from the description below
|
||||
taken from the Matrix and Quaternion FAQ
|
||||
|
||||
if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0:
|
||||
S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
|
||||
X = 0.25 * S;
|
||||
Y = (mat[4] + mat[1] ) / S;
|
||||
Z = (mat[2] + mat[8] ) / S;
|
||||
W = (mat[9] - mat[6] ) / S;
|
||||
} else if ( mat[5] > mat[10] ) { // Column 1:
|
||||
S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
|
||||
X = (mat[4] + mat[1] ) / S;
|
||||
Y = 0.25 * S;
|
||||
Z = (mat[9] + mat[6] ) / S;
|
||||
W = (mat[2] - mat[8] ) / S;
|
||||
} else { // Column 2:
|
||||
S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
|
||||
X = (mat[2] + mat[8] ) / S;
|
||||
Y = (mat[9] + mat[6] ) / S;
|
||||
Z = 0.25 * S;
|
||||
W = (mat[4] - mat[1] ) / S;
|
||||
}
|
||||
*/
|
||||
|
||||
float x, y, z, w;
|
||||
float *pMatrix = NULL;
|
||||
float m4x4[16] = {0};
|
||||
float scale = 0.0f;
|
||||
float diagonal = 0.0f;
|
||||
|
||||
if(!pIn) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 0 3 6
|
||||
1 4 7
|
||||
2 5 8
|
||||
|
||||
0 1 2 3
|
||||
4 5 6 7
|
||||
8 9 10 11
|
||||
12 13 14 15*/
|
||||
|
||||
m4x4[0] = pIn->mat[0];
|
||||
m4x4[1] = pIn->mat[3];
|
||||
m4x4[2] = pIn->mat[6];
|
||||
m4x4[4] = pIn->mat[1];
|
||||
m4x4[5] = pIn->mat[4];
|
||||
m4x4[6] = pIn->mat[7];
|
||||
m4x4[8] = pIn->mat[2];
|
||||
m4x4[9] = pIn->mat[5];
|
||||
m4x4[10] = pIn->mat[8];
|
||||
m4x4[15] = 1;
|
||||
pMatrix = &m4x4[0];
|
||||
|
||||
diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1;
|
||||
|
||||
if(diagonal > kmEpsilon) {
|
||||
// Calculate the scale of the diagonal
|
||||
scale = (float)sqrt(diagonal ) * 2;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = ( pMatrix[9] - pMatrix[6] ) / scale;
|
||||
y = ( pMatrix[2] - pMatrix[8] ) / scale;
|
||||
z = ( pMatrix[4] - pMatrix[1] ) / scale;
|
||||
w = 0.25f * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the first element of the diagonal is the greatest value
|
||||
if ( pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10] )
|
||||
{
|
||||
// Find the scale according to the first element, and double that value
|
||||
scale = (float)sqrt( 1.0f + pMatrix[0] - pMatrix[5] - pMatrix[10] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = 0.25f * scale;
|
||||
y = (pMatrix[4] + pMatrix[1] ) / scale;
|
||||
z = (pMatrix[2] + pMatrix[8] ) / scale;
|
||||
w = (pMatrix[9] - pMatrix[6] ) / scale;
|
||||
}
|
||||
// Else if the second element of the diagonal is the greatest value
|
||||
else if (pMatrix[5] > pMatrix[10])
|
||||
{
|
||||
// Find the scale according to the second element, and double that value
|
||||
scale = (float)sqrt( 1.0f + pMatrix[5] - pMatrix[0] - pMatrix[10] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = (pMatrix[4] + pMatrix[1] ) / scale;
|
||||
y = 0.25f * scale;
|
||||
z = (pMatrix[9] + pMatrix[6] ) / scale;
|
||||
w = (pMatrix[2] - pMatrix[8] ) / scale;
|
||||
}
|
||||
// Else the third element of the diagonal is the greatest value
|
||||
else
|
||||
{
|
||||
// Find the scale according to the third element, and double that value
|
||||
scale = (float)sqrt( 1.0f + pMatrix[10] - pMatrix[0] - pMatrix[5] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = (pMatrix[2] + pMatrix[8] ) / scale;
|
||||
y = (pMatrix[9] + pMatrix[6] ) / scale;
|
||||
z = 0.25f * scale;
|
||||
w = (pMatrix[4] - pMatrix[1] ) / scale;
|
||||
}
|
||||
}
|
||||
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
pOut->z = z;
|
||||
pOut->w = w;
|
||||
|
||||
return pOut;
|
||||
|
||||
#if 0
|
||||
kmScalar T = pIn->mat[0] + pIn->mat[5] + pIn->mat[10];
|
||||
|
||||
if (T > kmEpsilon) {
|
||||
//If the trace is greater than zero we always use this calculation:
|
||||
/* S = sqrt(T) * 2;
|
||||
X = ( mat[9] - mat[6] ) / S;
|
||||
Y = ( mat[2] - mat[8] ) / S;
|
||||
Z = ( mat[4] - mat[1] ) / S;
|
||||
W = 0.25 * S;*/
|
||||
|
||||
/* kmScalar s = sqrtf(T) * 2;
|
||||
pOut->x = (pIn->mat[9] - pIn->mat[6]) / s;
|
||||
pOut->y = (pIn->mat[8] - pIn->mat[2]) / s;
|
||||
pOut->z = (pIn->mat[1] - pIn->mat[4]) / s;
|
||||
pOut->w = 0.25f * s;
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
//Otherwise the calculation depends on which major diagonal element has the greatest value.
|
||||
|
||||
if (pIn->mat[0] > pIn->mat[5] && pIn->mat[0] > pIn->mat[10]) {
|
||||
kmScalar s = sqrtf(1 + pIn->mat[0] - pIn->mat[5] - pIn->mat[10]) * 2;
|
||||
pOut->x = 0.25f * s;
|
||||
pOut->y = (pIn->mat[1] + pIn->mat[4]) / s;
|
||||
pOut->z = (pIn->mat[8] + pIn->mat[2]) / s;
|
||||
pOut->w = (pIn->mat[9] - pIn->mat[6]) / s;
|
||||
}
|
||||
else if (pIn->mat[5] > pIn->mat[10]) {
|
||||
kmScalar s = sqrtf(1 + pIn->mat[5] - pIn->mat[0] - pIn->mat[10]) * 2;
|
||||
pOut->x = (pIn->mat[1] + pIn->mat[4]) / s;
|
||||
pOut->y = 0.25f * s;
|
||||
pOut->z = (pIn->mat[9] + pIn->mat[6]) / s;
|
||||
pOut->w = (pIn->mat[8] - pIn->mat[2]) / s;
|
||||
}
|
||||
else {
|
||||
kmScalar s = sqrt(1.0f + pIn->mat[10] - pIn->mat[0] - pIn->mat[5]) * 2.0f;
|
||||
pOut->x = (pIn->mat[8] + pIn->mat[2] ) / s;
|
||||
pOut->y = (pIn->mat[6] + pIn->mat[9] ) / s;
|
||||
pOut->z = 0.25f * s;
|
||||
pOut->w = (pIn->mat[1] - pIn->mat[4] ) / s;
|
||||
}
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
return pOut;*/
|
||||
#endif // 0
|
||||
}
|
||||
|
||||
///< Create a quaternion from yaw, pitch and roll
|
||||
kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut,
|
||||
kmScalar yaw,
|
||||
kmScalar pitch,
|
||||
kmScalar roll)
|
||||
{
|
||||
kmScalar ex, ey, ez; // temp half euler angles
|
||||
kmScalar cr, cp, cy, sr, sp, sy, cpcy, spsy; // temp vars in roll,pitch yaw
|
||||
|
||||
ex = kmDegreesToRadians(pitch) / 2.0f; // convert to rads and half them
|
||||
ey = kmDegreesToRadians(yaw) / 2.0f;
|
||||
ez = kmDegreesToRadians(roll) / 2.0f;
|
||||
|
||||
cr = cosf(ex);
|
||||
cp = cosf(ey);
|
||||
cy = cosf(ez);
|
||||
|
||||
sr = sinf(ex);
|
||||
sp = sinf(ey);
|
||||
sy = sinf(ez);
|
||||
|
||||
cpcy = cp * cy;
|
||||
spsy = sp * sy;
|
||||
|
||||
pOut->w = cr * cpcy + sr * spsy;
|
||||
|
||||
pOut->x = sr * cpcy - cr * spsy;
|
||||
pOut->y = cr * sp * cy + sr * cp * sy;
|
||||
pOut->z = cr * cp * sy - sr * sp * cy;
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Interpolate between 2 quaternions
|
||||
kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut,
|
||||
const kmQuaternion* q1,
|
||||
const kmQuaternion* q2,
|
||||
kmScalar t)
|
||||
{
|
||||
|
||||
/*float CosTheta = Q0.DotProd(Q1);
|
||||
float Theta = acosf(CosTheta);
|
||||
float SinTheta = sqrtf(1.0f-CosTheta*CosTheta);
|
||||
|
||||
float Sin_T_Theta = sinf(T*Theta)/SinTheta;
|
||||
float Sin_OneMinusT_Theta = sinf((1.0f-T)*Theta)/SinTheta;
|
||||
|
||||
Quaternion Result = Q0*Sin_OneMinusT_Theta;
|
||||
Result += (Q1*Sin_T_Theta);
|
||||
|
||||
return Result;*/
|
||||
|
||||
if (q1->x == q2->x &&
|
||||
q1->y == q2->y &&
|
||||
q1->z == q2->z &&
|
||||
q1->w == q2->w) {
|
||||
|
||||
pOut->x = q1->x;
|
||||
pOut->y = q1->y;
|
||||
pOut->z = q1->z;
|
||||
pOut->w = q1->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
{
|
||||
kmScalar ct = kmQuaternionDot(q1, q2);
|
||||
kmScalar theta = acosf(ct);
|
||||
kmScalar st = sqrtf(1.0 - kmSQR(ct));
|
||||
|
||||
kmScalar stt = sinf(t * theta) / st;
|
||||
kmScalar somt = sinf((1.0 - t) * theta) / st;
|
||||
|
||||
kmQuaternion temp, temp2;
|
||||
kmQuaternionScale(&temp, q1, somt);
|
||||
kmQuaternionScale(&temp2, q2, stt);
|
||||
kmQuaternionAdd(pOut, &temp, &temp2);
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Get the axis and angle of rotation from a quaternion
|
||||
void kmQuaternionToAxisAngle(const kmQuaternion* pIn,
|
||||
kmVec3* pAxis,
|
||||
kmScalar* pAngle)
|
||||
{
|
||||
kmScalar tempAngle; // temp angle
|
||||
kmScalar scale; // temp vars
|
||||
|
||||
tempAngle = acosf(pIn->w);
|
||||
scale = sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
|
||||
|
||||
if (((scale > -kmEpsilon) && scale < kmEpsilon)
|
||||
|| (scale < 2*kmPI + kmEpsilon && scale > 2*kmPI - kmEpsilon)) // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0
|
||||
{
|
||||
*pAngle = 0.0f;
|
||||
|
||||
pAxis->x = 0.0f;
|
||||
pAxis->y = 0.0f;
|
||||
pAxis->z = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pAngle = tempAngle * 2.0f; // angle in radians
|
||||
|
||||
pAxis->x = pIn->x / scale;
|
||||
pAxis->y = pIn->y / scale;
|
||||
pAxis->z = pIn->z / scale;
|
||||
kmVec3Normalize(pAxis, pAxis);
|
||||
}
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionScale(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn,
|
||||
kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
pOut->z = pIn->z * s;
|
||||
pOut->w = pIn->w * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
memcpy(pOut, pIn, sizeof(float) * 4);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2)
|
||||
{
|
||||
pOut->x = pQ1->x + pQ2->x;
|
||||
pOut->y = pQ1->y + pQ2->y;
|
||||
pOut->z = pQ1->z + pQ2->z;
|
||||
pOut->w = pQ1->w + pQ2->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Adapted from the OGRE engine!
|
||||
|
||||
Gets the shortest arc quaternion to rotate this vector to the destination
|
||||
vector.
|
||||
@remarks
|
||||
If you call this with a dest vector that is close to the inverse
|
||||
of this vector, we will rotate 180 degrees around the 'fallbackAxis'
|
||||
(if specified, or a generated axis if not) since in this case
|
||||
ANY axis of rotation is valid.
|
||||
*/
|
||||
|
||||
kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const kmVec3* vec1, const kmVec3* vec2, const kmVec3* fallback) {
|
||||
|
||||
kmVec3 v1, v2;
|
||||
kmScalar a;
|
||||
|
||||
kmVec3Assign(&v1, vec1);
|
||||
kmVec3Assign(&v2, vec2);
|
||||
|
||||
kmVec3Normalize(&v1, &v1);
|
||||
kmVec3Normalize(&v2, &v2);
|
||||
|
||||
a = kmVec3Dot(&v1, &v2);
|
||||
|
||||
if (a >= 1.0) {
|
||||
kmQuaternionIdentity(pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
if (a < (1e-6f - 1.0f)) {
|
||||
if (fabs(kmVec3LengthSq(fallback)) < kmEpsilon) {
|
||||
kmQuaternionRotationAxis(pOut, fallback, kmPI);
|
||||
} else {
|
||||
kmVec3 axis;
|
||||
kmVec3 X;
|
||||
X.x = 1.0;
|
||||
X.y = 0.0;
|
||||
X.z = 0.0;
|
||||
|
||||
|
||||
kmVec3Cross(&axis, &X, vec1);
|
||||
|
||||
//If axis is zero
|
||||
if (fabs(kmVec3LengthSq(&axis)) < kmEpsilon) {
|
||||
kmVec3 Y;
|
||||
Y.x = 0.0;
|
||||
Y.y = 1.0;
|
||||
Y.z = 0.0;
|
||||
|
||||
kmVec3Cross(&axis, &Y, vec1);
|
||||
}
|
||||
|
||||
kmVec3Normalize(&axis, &axis);
|
||||
|
||||
kmQuaternionRotationAxis(pOut, &axis, kmPI);
|
||||
}
|
||||
} else {
|
||||
kmScalar s = sqrtf((1+a) * 2);
|
||||
kmScalar invs = 1 / s;
|
||||
|
||||
kmVec3 c;
|
||||
kmVec3Cross(&c, &v1, &v2);
|
||||
|
||||
pOut->x = c.x * invs;
|
||||
pOut->y = c.y * invs;
|
||||
pOut->z = c.z * invs;
|
||||
pOut->w = s * 0.5f;
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
}
|
||||
|
||||
return pOut;
|
||||
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionMultiplyVec3(kmVec3* pOut, const kmQuaternion* q, const kmVec3* v) {
|
||||
kmVec3 uv, uuv, qvec;
|
||||
|
||||
qvec.x = q->x;
|
||||
qvec.y = q->y;
|
||||
qvec.z = q->z;
|
||||
|
||||
kmVec3Cross(&uv, &qvec, v);
|
||||
kmVec3Cross(&uuv, &qvec, &uv);
|
||||
|
||||
kmVec3Scale(&uv, &uv, (2.0f * q->w));
|
||||
kmVec3Scale(&uuv, &uuv, 2.0f);
|
||||
|
||||
kmVec3Add(pOut, v, &uv);
|
||||
kmVec3Add(pOut, pOut, &uuv);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "kazmath/ray2.h"
|
||||
|
||||
void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy) {
|
||||
ray->start.x = px;
|
||||
ray->start.y = py;
|
||||
ray->dir.x = vx;
|
||||
ray->dir.y = vy;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) {
|
||||
|
||||
float x1 = ray->start.x;
|
||||
float y1 = ray->start.y;
|
||||
float x2 = ray->start.x + ray->dir.x;
|
||||
float y2 = ray->start.y + ray->dir.y;
|
||||
float x3 = p1->x;
|
||||
float y3 = p1->y;
|
||||
float x4 = p2->x;
|
||||
float y4 = p2->y;
|
||||
|
||||
float denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
||||
float ua, x, y;
|
||||
//If denom is zero, the lines are parallel
|
||||
if(denom > -kmEpsilon && denom < kmEpsilon) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
|
||||
// float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
|
||||
|
||||
x = x1 + ua * (x2 - x1);
|
||||
y = y1 + ua * (y2 - y1);
|
||||
|
||||
if(x < kmMin(p1->x, p2->x) - kmEpsilon ||
|
||||
x > kmMax(p1->x, p2->x) + kmEpsilon ||
|
||||
y < kmMin(p1->y, p2->y) - kmEpsilon ||
|
||||
y > kmMax(p1->y, p2->y) + kmEpsilon) {
|
||||
//Outside of line
|
||||
//printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
if(x < kmMin(x1, x2) - kmEpsilon ||
|
||||
x > kmMax(x1, x2) + kmEpsilon ||
|
||||
y < kmMin(y1, y2) - kmEpsilon ||
|
||||
y > kmMax(y1, y2) + kmEpsilon) {
|
||||
//printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
intersection->x = x;
|
||||
intersection->y = y;
|
||||
|
||||
return KM_TRUE;
|
||||
|
||||
|
||||
/*
|
||||
kmScalar A1, B1, C1;
|
||||
kmScalar A2, B2, C2;
|
||||
|
||||
A1 = ray->dir.y;
|
||||
B1 = ray->dir.x;
|
||||
C1 = A1 * ray->start.x + B1 * ray->start.y;
|
||||
|
||||
A2 = p2->y - p1->y;
|
||||
B2 = p2->x - p1->x;
|
||||
C2 = A2 * p1->x + B2 * p1->y;
|
||||
|
||||
double det = (A1 * B2) - (A2 * B1);
|
||||
if(det == 0) {
|
||||
printf("Parallel\n");
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
double x = (B2*C1 - B1*C2) / det;
|
||||
double y = (A1*C2 - A2*C1) / det;
|
||||
|
||||
if(x < min(p1->x, p2->x) - kmEpsilon ||
|
||||
x > max(p1->x, p2->x) + kmEpsilon ||
|
||||
y < min(p1->y, p2->y) - kmEpsilon ||
|
||||
y > max(p1->y, p2->y) + kmEpsilon) {
|
||||
//Outside of line
|
||||
printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
kmScalar x1 = ray->start.x;
|
||||
kmScalar x2 = ray->start.x + ray->dir.x;
|
||||
|
||||
kmScalar y1 = ray->start.y;
|
||||
kmScalar y2 = ray->start.y + ray->dir.y;
|
||||
|
||||
if(x < min(x1, x2) - kmEpsilon ||
|
||||
x > max(x1, x2) + kmEpsilon ||
|
||||
y < min(y1, y2) - kmEpsilon ||
|
||||
y > max(y1, y2) + kmEpsilon) {
|
||||
printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
intersection->x = x;
|
||||
intersection->y = y;
|
||||
|
||||
return KM_TRUE;*/
|
||||
}
|
||||
|
||||
void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2* normal_out) {
|
||||
kmVec2 tmp;
|
||||
kmVec2Subtract(&tmp, &p2, &p1); //Get direction vector
|
||||
|
||||
normal_out->x = -tmp.y;
|
||||
normal_out->y = tmp.x;
|
||||
kmVec2Normalize(normal_out, normal_out);
|
||||
|
||||
//TODO: should check that the normal is pointing out of the triangle
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out) {
|
||||
kmVec2 intersect;
|
||||
kmVec2 final_intersect = {0., 0.}, normal = {0., 0.}; // Silencing LLVM SA.
|
||||
kmScalar distance = 10000.0f;
|
||||
kmBool intersected = KM_FALSE;
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p1, p2, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance;
|
||||
|
||||
intersected = KM_TRUE;
|
||||
this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
if(this_distance < distance) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
|
||||
calculate_line_normal(*p1, *p2, &normal);
|
||||
}
|
||||
}
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance;
|
||||
intersected = KM_TRUE;
|
||||
|
||||
this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
if(this_distance < distance) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
|
||||
calculate_line_normal(*p2, *p3, &normal);
|
||||
}
|
||||
}
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance;
|
||||
intersected = KM_TRUE;
|
||||
|
||||
this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
if(this_distance < distance) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
//distance = this_distance;
|
||||
|
||||
calculate_line_normal(*p3, *p1, &normal);
|
||||
}
|
||||
}
|
||||
|
||||
if(intersected) {
|
||||
intersection->x = final_intersect.x;
|
||||
intersection->y = final_intersect.y;
|
||||
if(normal_out) {
|
||||
normal_out->x = normal.x;
|
||||
normal_out->y = normal.y;
|
||||
}
|
||||
}
|
||||
|
||||
return intersected;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection) {
|
||||
assert(0 && "Not implemented");
|
||||
return 0;
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kazmath/mat3.h"
|
||||
#include "kazmath/vec2.h"
|
||||
#include "kazmath/utility.h"
|
||||
|
||||
kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y)
|
||||
{
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Length(const kmVec2* pIn)
|
||||
{
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y));
|
||||
}
|
||||
|
||||
kmScalar kmVec2LengthSq(const kmVec2* pIn)
|
||||
{
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y);
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn)
|
||||
{
|
||||
kmScalar l = 1.0f / kmVec2Length(pIn);
|
||||
|
||||
kmVec2 v;
|
||||
v.x = pIn->x * l;
|
||||
v.y = pIn->y * l;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
pOut->x = pV1->x + pV2->x;
|
||||
pOut->y = pV1->y + pV2->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
return pV1->x * pV2->x + pV1->y * pV2->y;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
pOut->x = pV1->x - pV2->x;
|
||||
pOut->y = pV1->y - pV2->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
|
||||
{
|
||||
kmVec2 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pM->mat[6];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pM->mat[7];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
|
||||
{
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2)
|
||||
{
|
||||
return (
|
||||
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
|
||||
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon)
|
||||
);
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче